Quickfix/J: How to get INVALID_MSGTYPE error for unknown messagetype which has groups?

201 Views Asked by At

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:

    1. Removed <message name='NewOrderSingle' msgcat='app' msgtype='D'> definition from spec xml. And also removed <value enum='D' description='NEWORDERSINGLE' /> from enums.
    1. 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|...)
    1. Got 58=Tag appears more than once, field=448 error.

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?

1

There are 1 best solutions below

2
Christoph John On

Actually I would expect a BusinessMessageReject for an unknown message type.

So everything that you need to do is actually implement your MessageCracker in 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

in the event a valid business message is received, fulfills session-level rules, however, the message type is not supported by the recipient. In this situation a BusinessMessageReject(35=j) with BusinessRejectReason(380) = 3 (Unsupported Message Type) can be issued...