[QFJ-238] No reject sent for message with duplicate field (OpenFIX) Created: 19/Sep/07  Updated: 07/Aug/08  Resolved: 03/Feb/08

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.2.1
Fix Version/s: 1.3.2

Type: Bug Priority: Default
Reporter: Graham Miller Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None

Attachments: Text File qfj-238.patch    

 Description   

This is a failing OpenFIX certification test. It will test that the FIX engine sends a reject when it receives a message with two of the same field (non-repeating group fields). In this case, it sends a message with OrderQty(38) set twice. Here is what openFIX has to say about the test:

============
This tests your ability to handle a field that appears more than once in a message. We will send you a message with OrderQty set twice.

Expected flow:

  • Send Reject (session-level) referencing duplicate field identifier (tag number)
  • Increment inbound MsgSeqNum
  • Generate an "error" condition in test output

The details of these session-level tests can be found in the FIX 4.3 Specification, Volume 2.
=============

This is the message that they send.

FIX.4.2:XXX->OPENFIX:
8=FIX.4.2
9=192
35=8
49=OPENFIX
56=XXX
52=20070918-20:34:33
34=85
37=1190147432328-19
11=119014743232810
20=0
55=T
54=1
38=3000
40=2
44=27
17=1190147432328-20
32=0
31=0
14=0
6=0
151=3000
39=0
150=0
38=3100
10=094



 Comments   
Comment by Graham Miller [ 19/Sep/07 ]

Sorry, I forgot to mention that quickfix does not send the reject message. Therein lies the bug.

Comment by Toli Kuznets [ 20/Sep/07 ]

So this is actually fairly easy to detect - see the attached patch. There was another variation where we can collect all the dupes and then throw the error at the end, showing all the dupes. i chose the first one, but we can easily go back to case 2.

Regardless, the behaviour required by OpenFIX certifiation error is much harder to achieve.
They send a message with a dupe in it, and they expect a session-level Reject back.

However, the way this works is that a message comes in to AbstractIoHandler, MessageUtils.parse gets called which calls Message.fromString which will throw an InvalidMessage exception, prints a log error and that's it - this is too low-level a point to send out a session-level reject.

The rejects are sent form Session code itself, and we never get to that point.
If we "ignore" the dupes in the initial parse of the message in AbstracdtIoHandler entrypoint, we lose the fact that we had dupes since we just end up setting the field twice (and losing the previous value). This was the behaviour i was seeing when i was just collecting the dupes into a list, and trying to validate it later (by having another dupeDetection boolean).

So not sure how to handle this case best - if we throw an exception before we get into Session message processing code, we don't send a reject. If we wait until Session code, we've already lost the dupe.

We can, of course, send a reject in the case the message doesn't parse correctly in AbstractIoHandler.messageReceived but i'm not sure of how easy it is to do that since we don't have access to any Session.generateReject code.

thoughts?

Comment by Steve Bate [ 20/Sep/07 ]

I understand the issues. We probably need to wait until after the 1.3.0 release for this one. I'd like some more time to consider the options. Is that ok with you?

Comment by Toli Kuznets [ 20/Sep/07 ]

Yes, i agree, it's too much of a change to introduce right now.

It's possible to create a "duplicate fields" list that's part of the parsed message, and only validate that it's empty when the codepath is in Session.next() code.
However, even in Session.next(Message msg) function catching an InvalidMessage exception right now only prints a log error and doesn't reject the message, so that'll need to be changed as well.

Generated at Fri Sep 20 22:15:18 UTC 2024 using JIRA 7.5.2#75007-sha1:9f5725bb824792b3230a5d8716f0c13e296a3cae.