I am building a DropCopy gateway. This GW will not handle any NewOrdersingle message.
So when client sends a NewOrderSingle (NOS) message to this GW clients must get SessionRejectReason.INVALID_MSGTYPE error.
Work steps:
-
- Removed
<message name='NewOrderSingle' msgcat='app' msgtype='D'>definition from spec xml. And also removed<value enum='D' description='NEWORDERSINGLE' />from enums.
- Removed
-
- Sent a NOS message to GW which has groups (as ...|453=3|448=abc|447=D|452=28|448=alloc|447=D|452=83|448=XYZ|447=D|452=4|...)
-
- Got
58=Tag appears more than once, field=448error.
- Got
The reason of above error is Quickfix parses groups by messagetypes (you can see code part below):
Message.java
private void parseBody(DataDictionary dd, boolean doValidation) throws InvalidMessage {
StringField field = extractField(dd, this);
while (field != null) {
if (isTrailerField(field.getField())) {
pushBack(field);
return;
}
if (isHeaderField(field.getField())) {
// An acceptance test requires the sequence number to
// be available even if the related field is out of order
setField(header, field);
// Group case
if (dd != null && dd.isGroup(DataDictionary.HEADER_ID, field.getField())) {
parseGroup(DataDictionary.HEADER_ID, field, dd, dd, header, doValidation);
}
if (doValidation && dd != null && dd.isCheckFieldsOutOfOrder())
throw new FieldException(SessionRejectReason.TAG_SPECIFIED_OUT_OF_REQUIRED_ORDER,
field.getTag());
} else {
setField(this, field);
// Group case
if (dd != null && dd.isGroup(getMsgType(), field.getField())) {
parseGroup(getMsgType(), field, dd, dd, this, doValidation);
}
}
field = extractField(dd, this);
}
}
- Consider
dd.isGroup(getMsgType(), field.getField())part!
When messagetype is not on spec, groups are not parsed. So when a second field is parsed in a message SessionRejectReason.TAG_APPEARS_MORE_THAN_ONCE error occurs:
Message.java
private void setField(FieldMap fields, StringField field) {
if (fields.isSetField(field)) {
throw new FieldException(SessionRejectReason.TAG_APPEARS_MORE_THAN_ONCE, field.getTag());
}
fields.setField(field);
}
Sample Logs:
< 8=FIXT.1.1|9=241|35=D|49=TESTCLI|56=EXCHANGE|34=2|52=20230619-13:57:14|11=1806576375|48=2823|22=4|38=50|44=9|40=2|59=0|54=2|1=MyAcc|70=alim|820=limit day|528=A|60=20230619-13:57:14|453=3|448=afk|447=D|452=28|448=allocaccount|447=D|452=83|448=ABC|447=D|452=4|10=161|
> 8=FIXT.1.1|9=130|35=3|34=2|49=EXCHANGE|52=20230619-13:57:14.589|56=TESTCLI|57=CLIDC|45=2|58=Tag appears more than once, field=448|371=448|372=D|373=13|10=217|
Quickfix version: 2.3.1
To summarise, is there a way getting SessionRejectReason.INVALID_MSGTYPE error for unknown messagetypes which have groups?
Actually I would expect a
BusinessMessageRejectfor an unknown message type.So everything that you need to do is actually implement your
MessageCrackerin a way that it only accepts the messages that you want to process.https://github.com/quickfix-j/quickfixj#receiving-messages
Also see official FIX spec here https://www.fixtrading.org/online-specification/business-area-infrastructure/#category-business-rejects and here https://www.fixtrading.org/online-specification/business-area-infrastructure/#reject-codes-for-businessmessagereject35j-message