|
63 | 63 | import quickfix.field.MsgDirection; |
64 | 64 | import quickfix.field.MsgSeqNum; |
65 | 65 | import quickfix.field.MsgType; |
| 66 | +import quickfix.field.NoHops; |
66 | 67 | import quickfix.field.NoOrders; |
| 68 | +import quickfix.field.NoSides; |
67 | 69 | import quickfix.field.OrdStatus; |
68 | 70 | import quickfix.field.OrdType; |
69 | 71 | import quickfix.field.OrderID; |
|
129 | 131 | import static org.junit.Assert.assertEquals; |
130 | 132 | import static org.junit.Assert.assertFalse; |
131 | 133 | import static org.junit.Assert.assertNotNull; |
| 134 | +import static org.junit.Assert.assertNotEquals; |
132 | 135 | import static org.junit.Assert.assertNull; |
133 | 136 | import static org.junit.Assert.assertTrue; |
134 | 137 | import static org.junit.Assert.fail; |
@@ -1966,6 +1969,162 @@ public void shouldConvertToXMLWithIndent() { |
1966 | 1969 | " <trailer/>\n" + "</message>\n", xml); |
1967 | 1970 | } |
1968 | 1971 |
|
| 1972 | + @Test |
| 1973 | + public void testValidateFieldsOutOfOrderFIXT11() throws Exception { |
| 1974 | + final DataDictionary sessDictionary = DataDictionaryTest.getDictionary("FIXT11.xml"); |
| 1975 | + final DataDictionary appDictionary = DataDictionaryTest.getDictionary("FIX50SP2.xml"); |
| 1976 | + assertNotNull(sessDictionary); |
| 1977 | + assertNotNull(appDictionary); |
| 1978 | + assertNotEquals(appDictionary.getVersion(), sessDictionary.getVersion()); |
| 1979 | + |
| 1980 | + final String orderedData = "8=FIXT.1.1\u00019=561\u000135=AE\u0001" + |
| 1981 | + "34=545\u000149=SENDER\u000152=20220210-02:44:00.820\u000156=TARGET\u0001115=ON_BHEHALF\u0001" + |
| 1982 | + "1128=9\u0001" + |
| 1983 | + "627=2\u0001" + |
| 1984 | + "628=HOPID1\u0001629=20220414-15:22:54\u0001" + |
| 1985 | + "628=HOPID2\u0001629=20220414-15:22:54\u0001" + |
| 1986 | + "15=AUD\u000122=4\u000131=27\u000132=5000.000000000000\u000148=AU000000ANZ3\u000155=ANZ\u000160=20220210-02:43:27.796\u000164=20220214\u000175=20220210\u0001106=4075\u0001167=CS\u0001381=135000\u0001461=Exxxxx\u0001487=0\u0001762=1\u0001880=7533509260093686098:0#NORMAL#1644451200000000000\u00011003=1120000338\u00011015=0\u00011301=XASX\u0001" + |
| 1987 | + "552=2\u0001" + |
| 1988 | + "54=1\u0001453=1\u0001448=338-3\u0001447=D\u0001452=1\u00011=1040445\u0001576=1\u0001577=0\u000111=7533509260093758035\u0001" + |
| 1989 | + "54=2\u0001453=1\u0001448=338-3\u0001447=D\u0001452=1\u00011=1040445\u0001576=1\u0001577=0\u000111=7533509260093757876\u0001" + |
| 1990 | + "10=129\u0001"; |
| 1991 | + final TradeCaptureReport tcrOrdered = new TradeCaptureReport(); |
| 1992 | + tcrOrdered.fromString(orderedData, sessDictionary, appDictionary, true); |
| 1993 | + DataDictionary.validate(tcrOrdered, sessDictionary, appDictionary); |
| 1994 | + // As this is our reference message created with all validations switched on, make sure some message components |
| 1995 | + // are as expected |
| 1996 | + assertEquals(tcrOrdered.getHeader().getGroupCount(NoHops.FIELD), 2); |
| 1997 | + assertEquals(tcrOrdered.getGroupCount(NoSides.FIELD), 2); |
| 1998 | + |
| 1999 | + sessDictionary.setCheckFieldsOutOfOrder(false); |
| 2000 | + appDictionary.setCheckFieldsOutOfOrder(false); |
| 2001 | + |
| 2002 | + String unorderedData = "8=FIXT.1.1\u00019=561\u000135=AE\u0001" + |
| 2003 | + "15=AUD\u000122=4\u000131=27\u000132=5000.000000000000\u000148=AU000000ANZ3\u000155=ANZ\u000160=20220210-02:43:27.796\u000164=20220214\u000175=20220210\u0001106=4075\u0001167=CS\u0001381=135000\u0001461=Exxxxx\u0001487=0\u0001762=1\u0001880=7533509260093686098:0#NORMAL#1644451200000000000\u00011003=1120000338\u00011015=0\u00011301=XASX\u0001" + |
| 2004 | + "552=2\u0001" + |
| 2005 | + "54=1\u0001453=1\u0001448=338-3\u0001447=D\u0001452=1\u00011=1040445\u0001576=1\u0001577=0\u000111=7533509260093758035\u0001" + |
| 2006 | + "54=2\u0001453=1\u0001448=338-3\u0001447=D\u0001452=1\u00011=1040445\u0001576=1\u0001577=0\u000111=7533509260093757876\u0001" + |
| 2007 | + // Repeating Header Group, found just after a Repeating group within the body |
| 2008 | + "627=2\u0001628=HOPID1\u0001629=20220414-15:22:54\u0001628=HOPID2\u0001629=20220414-15:22:54\u0001" + |
| 2009 | + "34=545\u000149=SENDER\u000152=20220210-02:44:00.820\u000156=TARGET\u0001115=ON_BHEHALF\u00011128=9\u0001" + |
| 2010 | + "10=129\u0001"; |
| 2011 | + TradeCaptureReport tcrUnOrdered = new TradeCaptureReport(); |
| 2012 | + tcrUnOrdered.fromString(unorderedData, sessDictionary, appDictionary, true); |
| 2013 | + DataDictionary.validate(tcrUnOrdered, sessDictionary, appDictionary); |
| 2014 | + |
| 2015 | + assertEquals(tcrOrdered.toString(), tcrUnOrdered.toString()); |
| 2016 | + |
| 2017 | + unorderedData = "8=FIXT.1.1\u00019=561\u000135=AE\u0001" + |
| 2018 | + "15=AUD\u000122=4\u000131=27\u000132=5000.000000000000\u000148=AU000000ANZ3\u000155=ANZ\u000160=20220210-02:43:27.796\u000164=20220214\u000175=20220210\u0001106=4075\u0001167=CS\u0001381=135000\u0001461=Exxxxx\u0001487=0\u0001762=1\u0001880=7533509260093686098:0#NORMAL#1644451200000000000\u00011003=1120000338\u00011015=0\u00011301=XASX\u0001" + |
| 2019 | + "552=2\u0001" + |
| 2020 | + "54=1\u0001453=1\u0001448=338-3\u0001447=D\u0001452=1\u00011=1040445\u0001576=1\u0001577=0\u000111=7533509260093758035\u0001" + |
| 2021 | + "54=2\u0001453=1\u0001448=338-3\u0001447=D\u0001452=1\u00011=1040445\u0001576=1\u0001577=0\u000111=7533509260093757876\u0001" + |
| 2022 | + // Header tag found just after Repeating group within the body |
| 2023 | + "34=545\u000149=SENDER\u000152=20220210-02:44:00.820\u000156=TARGET\u0001115=ON_BHEHALF\u00011128=9\u0001" + |
| 2024 | + "627=2\u0001628=HOPID1\u0001629=20220414-15:22:54\u0001628=HOPID2\u0001629=20220414-15:22:54\u0001" + |
| 2025 | + "10=129\u0001"; |
| 2026 | + tcrUnOrdered = new TradeCaptureReport(); |
| 2027 | + tcrUnOrdered.fromString(unorderedData, sessDictionary, appDictionary, true); |
| 2028 | + DataDictionary.validate(tcrUnOrdered, sessDictionary, appDictionary); |
| 2029 | + |
| 2030 | + assertEquals(tcrOrdered.toString(), tcrUnOrdered.toString()); |
| 2031 | + |
| 2032 | + unorderedData = "8=FIXT.1.1\u00019=561\u000135=AE\u0001" + |
| 2033 | + "15=AUD\u000122=4\u000131=27\u000132=5000.000000000000\u000148=AU000000ANZ3\u000155=ANZ\u000160=20220210-02:43:27.796\u000164=20220214\u000175=20220210\u0001106=4075\u0001167=CS\u0001381=135000\u0001461=Exxxxx\u0001487=0\u0001762=1\u0001880=7533509260093686098:0#NORMAL#1644451200000000000\u00011003=1120000338\u00011015=0\u00011301=XASX\u0001" + |
| 2034 | + // Some Header fields found after body fields detected |
| 2035 | + "34=545\u000149=SENDER\u000152=20220210-02:44:00.820\u000156=TARGET\u0001115=ON_BHEHALF\u00011128=9\u0001" + |
| 2036 | + // Repeating Group |
| 2037 | + "552=2\u0001" + |
| 2038 | + "54=1\u0001453=1\u0001448=338-3\u0001447=D\u0001452=1\u00011=1040445\u0001576=1\u0001577=0\u000111=7533509260093758035\u0001" + |
| 2039 | + "54=2\u0001453=1\u0001448=338-3\u0001447=D\u0001452=1\u00011=1040445\u0001576=1\u0001577=0\u000111=7533509260093757876\u0001" + |
| 2040 | + // Some repeating Header tags |
| 2041 | + "627=2\u0001628=HOPID1\u0001629=20220414-15:22:54\u0001628=HOPID2\u0001629=20220414-15:22:54\u0001" + |
| 2042 | + "10=129\u0001"; |
| 2043 | + tcrUnOrdered = new TradeCaptureReport(); |
| 2044 | + tcrUnOrdered.fromString(unorderedData, sessDictionary, appDictionary, true); |
| 2045 | + DataDictionary.validate(tcrUnOrdered, sessDictionary, appDictionary); |
| 2046 | + |
| 2047 | + assertEquals(tcrOrdered.toString(), tcrUnOrdered.toString()); |
| 2048 | + |
| 2049 | + } |
| 2050 | + |
| 2051 | + @Test |
| 2052 | + public void testValidateFieldsOutOfOrderPreFIXT11() throws Exception { |
| 2053 | + final DataDictionary sessDictionary = DataDictionaryTest.getDictionary("FIX44.xml"); |
| 2054 | + assertNotNull(sessDictionary); |
| 2055 | + |
| 2056 | + final String orderedData = |
| 2057 | + "8=FIX.4.4\u00019=551\u000135=AE\u0001" |
| 2058 | + + "34=545\u000149=SENDER\u000152=20220210-02:44:00.820\u000156=TARGET\u0001115=ON_BHEHALF\u0001" |
| 2059 | + + "627=2\u0001628=HOPID1\u0001629=20220414-15:22:54\u0001628=HOPID2\u0001629=20220414-15:22:54\u0001" |
| 2060 | + + "22=4\u000131=27\u000132=5000.000000000000\u000148=AU000000ANZ3\u000155=ANZ\u000160=20220210-02:43:27.796\u000164=20220214\u000175=20220210\u0001106=4075\u0001167=CS\u0001461=Exxxxx\u0001487=0\u0001570=N\u0001571=TradeReportID\u0001762=1\u0001880=7533509260093686098:0#NORMAL#1644451200000000000\u0001" |
| 2061 | + + "552=2\u0001" |
| 2062 | + + "54=1\u000137=OrderID1\u000111=7533509260093758035\u0001453=1\u0001448=338-3\u0001447=D\u0001452=1\u00011=1040445\u0001576=1\u0001577=0\u0001" |
| 2063 | + + "54=2\u000137=OrderID2\u000111=7533509260093757876\u0001453=1\u0001448=338-3\u0001447=D\u0001452=1\u00011=1040445\u0001576=1\u0001577=0\u0001" |
| 2064 | + + "10=191\u0001"; |
| 2065 | + final TradeCaptureReport tcrOrdered = new TradeCaptureReport(); |
| 2066 | + tcrOrdered.fromString(orderedData, sessDictionary, true); |
| 2067 | + DataDictionary.validate(tcrOrdered, sessDictionary, sessDictionary); |
| 2068 | + |
| 2069 | + // As this is our reference message created with all validations switched on, |
| 2070 | + // make sure some message components |
| 2071 | + // are as expected |
| 2072 | + assertEquals(tcrOrdered.getHeader().getGroupCount(NoHops.FIELD), 2); |
| 2073 | + assertEquals(tcrOrdered.getGroupCount(NoSides.FIELD), 2); |
| 2074 | + |
| 2075 | + sessDictionary.setCheckFieldsOutOfOrder(false); |
| 2076 | + |
| 2077 | + String unorderedData = "8=FIX.4.4\u00019=551\u000135=AE\u0001" |
| 2078 | + + "22=4\u000131=27\u000132=5000.000000000000\u000148=AU000000ANZ3\u000155=ANZ\u000160=20220210-02:43:27.796\u000164=20220214\u000175=20220210\u0001106=4075\u0001167=CS\u0001461=Exxxxx\u0001487=0\u0001570=N\u0001571=TradeReportID\u0001762=1\u0001880=7533509260093686098:0#NORMAL#1644451200000000000\u0001" |
| 2079 | + + "552=2\u0001" |
| 2080 | + + "54=1\u000137=OrderID1\u000111=7533509260093758035\u0001453=1\u0001448=338-3\u0001447=D\u0001452=1\u00011=1040445\u0001576=1\u0001577=0\u0001" |
| 2081 | + + "54=2\u000137=OrderID2\u000111=7533509260093757876\u0001453=1\u0001448=338-3\u0001447=D\u0001452=1\u00011=1040445\u0001576=1\u0001577=0\u0001" |
| 2082 | + // Repeating Header Group, found just after a Repeating group within the body |
| 2083 | + + "627=2\u0001628=HOPID1\u0001629=20220414-15:22:54\u0001628=HOPID2\u0001629=20220414-15:22:54\u0001" |
| 2084 | + + "34=545\u000149=SENDER\u000152=20220210-02:44:00.820\u000156=TARGET\u0001115=ON_BHEHALF\u0001" |
| 2085 | + + "10=191\u0001"; |
| 2086 | + TradeCaptureReport tcrUnOrdered = new TradeCaptureReport(); |
| 2087 | + tcrUnOrdered.fromString(unorderedData, sessDictionary, true); |
| 2088 | + DataDictionary.validate(tcrUnOrdered, sessDictionary, sessDictionary); |
| 2089 | + |
| 2090 | + assertEquals(tcrOrdered.toString(), tcrUnOrdered.toString()); |
| 2091 | + |
| 2092 | + unorderedData = "8=FIX.4.4\u00019=551\u000135=AE\u0001" |
| 2093 | + + "22=4\u000131=27\u000132=5000.000000000000\u000148=AU000000ANZ3\u000155=ANZ\u000160=20220210-02:43:27.796\u000164=20220214\u000175=20220210\u0001106=4075\u0001167=CS\u0001461=Exxxxx\u0001487=0\u0001570=N\u0001571=TradeReportID\u0001762=1\u0001880=7533509260093686098:0#NORMAL#1644451200000000000\u0001" |
| 2094 | + + "552=2\u0001" |
| 2095 | + + "54=1\u000137=OrderID1\u000111=7533509260093758035\u0001453=1\u0001448=338-3\u0001447=D\u0001452=1\u00011=1040445\u0001576=1\u0001577=0\u0001" |
| 2096 | + + "54=2\u000137=OrderID2\u000111=7533509260093757876\u0001453=1\u0001448=338-3\u0001447=D\u0001452=1\u00011=1040445\u0001576=1\u0001577=0\u0001" |
| 2097 | + // Header tag found just after Repeating group within the body |
| 2098 | + + "34=545\u000149=SENDER\u000152=20220210-02:44:00.820\u000156=TARGET\u0001115=ON_BHEHALF\u0001" |
| 2099 | + + "627=2\u0001628=HOPID1\u0001629=20220414-15:22:54\u0001628=HOPID2\u0001629=20220414-15:22:54\u0001" |
| 2100 | + |
| 2101 | + + "10=191\u0001"; |
| 2102 | + tcrUnOrdered = new TradeCaptureReport(); |
| 2103 | + tcrUnOrdered.fromString(unorderedData, sessDictionary, true); |
| 2104 | + DataDictionary.validate(tcrUnOrdered, sessDictionary, sessDictionary); |
| 2105 | + |
| 2106 | + assertEquals(tcrOrdered.toString(), tcrUnOrdered.toString()); |
| 2107 | + |
| 2108 | + unorderedData = "8=FIX.4.4\u00019=551\u000135=AE\u0001" |
| 2109 | + // Some body tags |
| 2110 | + + "22=4\u000131=27\u000132=5000.000000000000\u000148=AU000000ANZ3\u000155=ANZ\u000160=20220210-02:43:27.796\u000164=20220214\u000175=20220210\u0001106=4075\u0001167=CS\u0001461=Exxxxx\u0001487=0\u0001570=N\u0001571=TradeReportID\u0001762=1\u0001880=7533509260093686098:0#NORMAL#1644451200000000000\u0001" |
| 2111 | + // The some Header tags |
| 2112 | + + "34=545\u000149=SENDER\u000152=20220210-02:44:00.820\u000156=TARGET\u0001115=ON_BHEHALF\u0001" |
| 2113 | + // A Repeating body group |
| 2114 | + + "552=2\u0001" |
| 2115 | + + "54=1\u000137=OrderID1\u000111=7533509260093758035\u0001453=1\u0001448=338-3\u0001447=D\u0001452=1\u00011=1040445\u0001576=1\u0001577=0\u0001" |
| 2116 | + + "54=2\u000137=OrderID2\u000111=7533509260093757876\u0001453=1\u0001448=338-3\u0001447=D\u0001452=1\u00011=1040445\u0001576=1\u0001577=0\u0001" |
| 2117 | + // Repeating Header Group |
| 2118 | + + "627=2\u0001628=HOPID1\u0001629=20220414-15:22:54\u0001628=HOPID2\u0001629=20220414-15:22:54\u0001" |
| 2119 | + + "10=191\u0001"; |
| 2120 | + tcrUnOrdered = new TradeCaptureReport(); |
| 2121 | + tcrUnOrdered.fromString(unorderedData, sessDictionary, true); |
| 2122 | + DataDictionary.validate(tcrUnOrdered, sessDictionary, sessDictionary); |
| 2123 | + |
| 2124 | + assertEquals(tcrOrdered.toString(), tcrUnOrdered.toString()); |
| 2125 | + |
| 2126 | + } |
| 2127 | + |
1969 | 2128 | private void assertHeaderField(Message message, String expectedValue, int field) |
1970 | 2129 | throws FieldNotFound { |
1971 | 2130 | assertEquals(expectedValue, message.getHeader().getString(field)); |
|
0 commit comments