diff --git a/pom.xml b/pom.xml
index 981f6b3ca0..e5f578a5e6 100644
--- a/pom.xml
+++ b/pom.xml
@@ -3,7 +3,7 @@
org.quickfixj
quickfixj-parent
- 2.0.1-SNAPSHOT
+ 2.1.0-SNAPSHOT
pom
QuickFIX/J Parent
diff --git a/quickfixj-all/pom.xml b/quickfixj-all/pom.xml
index 6ac9115c1b..2347ca65a1 100644
--- a/quickfixj-all/pom.xml
+++ b/quickfixj-all/pom.xml
@@ -4,7 +4,7 @@
org.quickfixj
quickfixj-parent
- 2.0.1-SNAPSHOT
+ 2.1.0-SNAPSHOT
quickfixj-all
diff --git a/quickfixj-codegenerator/pom.xml b/quickfixj-codegenerator/pom.xml
index cec7dc9783..07938f2786 100644
--- a/quickfixj-codegenerator/pom.xml
+++ b/quickfixj-codegenerator/pom.xml
@@ -4,7 +4,7 @@
org.quickfixj
quickfixj-parent
- 2.0.1-SNAPSHOT
+ 2.1.0-SNAPSHOT
quickfixj-codegenerator
diff --git a/quickfixj-core/pom.xml b/quickfixj-core/pom.xml
index 23dc556da7..65a58df01f 100644
--- a/quickfixj-core/pom.xml
+++ b/quickfixj-core/pom.xml
@@ -3,7 +3,7 @@
org.quickfixj
quickfixj-parent
- 2.0.1-SNAPSHOT
+ 2.1.0-SNAPSHOT
quickfixj-core
diff --git a/quickfixj-core/src/main/java/quickfix/FieldMap.java b/quickfixj-core/src/main/java/quickfix/FieldMap.java
index f7edfe4081..5a80be2160 100644
--- a/quickfixj-core/src/main/java/quickfix/FieldMap.java
+++ b/quickfixj-core/src/main/java/quickfix/FieldMap.java
@@ -37,13 +37,8 @@
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.LocalDateTime;
-import java.util.ArrayList;
-import java.util.Comparator;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
import java.util.Map.Entry;
-import java.util.TreeMap;
/**
* Field container used by messages, groups, and composites.
@@ -232,6 +227,15 @@ public String getString(int field) throws FieldNotFound {
return getField(field).getObject();
}
+ public Optional getOptionalString(int field) {
+ final StringField f = (StringField) fields.get(field);
+ if (f == null) {
+ return Optional.empty();
+ } else {
+ return Optional.of(f.getValue());
+ }
+ }
+
public boolean getBoolean(int field) throws FieldNotFound {
try {
return BooleanConverter.convert(getString(field));
diff --git a/quickfixj-core/src/main/java/quickfix/Message.java b/quickfixj-core/src/main/java/quickfix/Message.java
index ae33a80dec..e3405f78b4 100644
--- a/quickfixj-core/src/main/java/quickfix/Message.java
+++ b/quickfixj-core/src/main/java/quickfix/Message.java
@@ -33,6 +33,8 @@
import org.w3c.dom.CDATASection;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
+
+import quickfix.field.ApplExtID;
import quickfix.field.ApplVerID;
import quickfix.field.BeginString;
import quickfix.field.BodyLength;
@@ -720,6 +722,7 @@ static boolean isHeaderField(int field) {
case OnBehalfOfSendingTime.FIELD:
case ApplVerID.FIELD:
case CstmApplVerID.FIELD:
+ case ApplExtID.FIELD:
case NoHops.FIELD:
return true;
default:
diff --git a/quickfixj-core/src/main/java/quickfix/Session.java b/quickfixj-core/src/main/java/quickfix/Session.java
index dbfd9235bd..63392d6c4c 100644
--- a/quickfixj-core/src/main/java/quickfix/Session.java
+++ b/quickfixj-core/src/main/java/quickfix/Session.java
@@ -1073,7 +1073,10 @@ ignore the message and let the problem correct itself (optimistic approach).
generateLogout(e.getMessage());
}
}
- state.incrNextTargetMsgSeqNum();
+ // Only increment seqnum if we are at the expected seqnum
+ if (getExpectedTargetNum() == header.getInt(MsgSeqNum.FIELD)) {
+ state.incrNextTargetMsgSeqNum();
+ }
disconnect("Logon rejected: " + e, true);
} catch (final UnsupportedMessageType e) {
if (logErrorAndDisconnectIfRequired(e, message)) {
diff --git a/quickfixj-core/src/test/java/quickfix/FieldMapTest.java b/quickfixj-core/src/test/java/quickfix/FieldMapTest.java
index 8e40d5e493..c03f2cf7d3 100644
--- a/quickfixj-core/src/test/java/quickfix/FieldMapTest.java
+++ b/quickfixj-core/src/test/java/quickfix/FieldMapTest.java
@@ -11,6 +11,7 @@
import quickfix.field.converter.UtcTimeOnlyConverter;
import java.util.Iterator;
+import java.util.Optional;
/**
* Tests the {@link FieldMap} class.
@@ -91,6 +92,16 @@ public void testOrdering() {
testOrdering(new int[] { 3, 2, 1 }, new int[] { 3, 1 }, new int[] { 3, 1, 2 });
}
+ public void testOptionalString() {
+ FieldMap map = new Message();
+ map.setField(new StringField(128, "bigbank"));
+ Optional optValue = map.getOptionalString(128);
+ assertTrue(optValue.isPresent());
+ assertEquals("bigbank", optValue.get());
+ assertFalse(map.getOptionalString(129).isPresent());
+ }
+
+
private long epochMilliOfLocalDate(LocalDateTime localDateTime) {
return localDateTime.toInstant(ZoneOffset.UTC).toEpochMilli();
}
diff --git a/quickfixj-core/src/test/java/quickfix/MessageTest.java b/quickfixj-core/src/test/java/quickfix/MessageTest.java
index c8b22d45eb..ecbbbc90bd 100644
--- a/quickfixj-core/src/test/java/quickfix/MessageTest.java
+++ b/quickfixj-core/src/test/java/quickfix/MessageTest.java
@@ -24,6 +24,7 @@
import quickfix.field.Account;
import quickfix.field.AllocAccount;
import quickfix.field.AllocShares;
+import quickfix.field.ApplExtID;
import quickfix.field.ApplVerID;
import quickfix.field.AvgPx;
import quickfix.field.BeginString;
@@ -588,6 +589,11 @@ public void testFix5HeaderFields() {
assertTrue(Message.isHeaderField(CstmApplVerID.FIELD));
}
+ @Test
+ public void testApplExtIDIsHeaderField() {
+ assertTrue(Message.isHeaderField(ApplExtID.FIELD));
+ }
+
@Test
public void testCalculateStringWithNestedGroups() throws Exception {
final NewOrderCross noc = new NewOrderCross();
diff --git a/quickfixj-core/src/test/java/quickfix/SessionTest.java b/quickfixj-core/src/test/java/quickfix/SessionTest.java
index 56e3763437..a6e6fe5c6d 100644
--- a/quickfixj-core/src/test/java/quickfix/SessionTest.java
+++ b/quickfixj-core/src/test/java/quickfix/SessionTest.java
@@ -2336,6 +2336,68 @@ private void testLargeQueue(int N) throws Exception {
*/
}
+ @Test
+ public void testResendSeqWithReject() throws Exception {
+ final SessionID sessionID = new SessionID(FixVersions.BEGINSTRING_FIX44, "SENDER", "TARGET");
+ final boolean resetOnLogon = false;
+ final boolean validateSequenceNumbers = true;
+ boolean enableNextExpectedMsgSeqNum = false;
+ boolean isInitiator = false;
+
+ UnitTestApplication app = new UnitTestApplication() {
+ private int logonCount = 0;
+
+ @Override
+ public void fromAdmin(Message message, SessionID sessionId) throws FieldNotFound,
+ IncorrectDataFormat, IncorrectTagValue, RejectLogon {
+ super.fromAdmin(message, sessionId);
+ if (message.getHeader().getString(MsgType.FIELD).equals(Logon.MSGTYPE)) {
+ logonCount += 1;
+ }
+ if (logonCount == 2) {
+ throw new RejectLogon("RejectLogon");
+ }
+ }
+ };
+
+ Session session = new Session(app, new MemoryStoreFactory(),
+ sessionID, null, null, null,
+ new DefaultMessageFactory(), isInitiator ? 30 : 0, false, 30, UtcTimestampPrecision.MILLIS, resetOnLogon,
+ false, false, false, false, false, true, false, 1.5, null, validateSequenceNumbers,
+ new int[]{5}, false, false, false, true, false, true, false, null, true, 0,
+ enableNextExpectedMsgSeqNum, false);
+ UnitTestResponder responder = new UnitTestResponder();
+ session.setResponder(responder);
+
+ logonTo(session, 1);
+ //Do Something
+ session.next(createAppMessage(2));
+ session.next(createAppMessage(3));
+ session.disconnect("Disconnecting", true);
+ session.next();
+ session.logon();
+
+ //Logon
+ session.setResponder(responder);
+ logonTo(session, 105);
+ //Rejected
+ assertEquals(Logout.MSGTYPE, app.lastToAdminMessage().getHeader().getString(MsgType.FIELD));
+ assertEquals("RejectLogon", app.lastToAdminMessage().getString(Text.FIELD));
+
+ //Logon
+ session.setResponder(responder);
+ logonTo(session, 106);
+ //Accepted
+ assertEquals(Logon.MSGTYPE, app.lastFromAdminMessage().getHeader().getString(MsgType.FIELD));
+
+ session.next();
+ session.next();
+ //ResendRequest
+ assertEquals(ResendRequest.MSGTYPE, app.lastToAdminMessage().getHeader().getString(MsgType.FIELD));
+ assertEquals(4, app.lastToAdminMessage().getInt(BeginSeqNo.FIELD));
+ assertEquals(0, app.lastToAdminMessage().getInt(EndSeqNo.FIELD));
+ }
+
private News createPossDupAppMessage(int sequence) {
// create a regular app message and and add the PossDup
// and OrigSendingTime tags to it
diff --git a/quickfixj-dictgenerator/pom.xml b/quickfixj-dictgenerator/pom.xml
index 58a7fa22f0..42c980f7ba 100644
--- a/quickfixj-dictgenerator/pom.xml
+++ b/quickfixj-dictgenerator/pom.xml
@@ -4,7 +4,7 @@
org.quickfixj
quickfixj-parent
- 2.0.1-SNAPSHOT
+ 2.1.0-SNAPSHOT
quickfixj-dictgenerator
diff --git a/quickfixj-distribution/pom.xml b/quickfixj-distribution/pom.xml
index 51aeca5f68..2e9d3b001e 100644
--- a/quickfixj-distribution/pom.xml
+++ b/quickfixj-distribution/pom.xml
@@ -4,7 +4,7 @@
org.quickfixj
quickfixj-parent
- 2.0.1-SNAPSHOT
+ 2.1.0-SNAPSHOT
quickfixj-distribution
diff --git a/quickfixj-examples/banzai/pom.xml b/quickfixj-examples/banzai/pom.xml
index 3d92bf36bc..d435cb47fe 100644
--- a/quickfixj-examples/banzai/pom.xml
+++ b/quickfixj-examples/banzai/pom.xml
@@ -4,7 +4,7 @@
org.quickfixj
quickfixj-examples
- 2.0.1-SNAPSHOT
+ 2.1.0-SNAPSHOT
quickfixj-examples-banzai
diff --git a/quickfixj-examples/executor/pom.xml b/quickfixj-examples/executor/pom.xml
index ef76ed39aa..57f834a358 100644
--- a/quickfixj-examples/executor/pom.xml
+++ b/quickfixj-examples/executor/pom.xml
@@ -4,7 +4,7 @@
org.quickfixj
quickfixj-examples
- 2.0.1-SNAPSHOT
+ 2.1.0-SNAPSHOT
quickfixj-examples-executor
diff --git a/quickfixj-examples/ordermatch/pom.xml b/quickfixj-examples/ordermatch/pom.xml
index c6dd458e64..2397b3582b 100644
--- a/quickfixj-examples/ordermatch/pom.xml
+++ b/quickfixj-examples/ordermatch/pom.xml
@@ -4,7 +4,7 @@
org.quickfixj
quickfixj-examples
- 2.0.1-SNAPSHOT
+ 2.1.0-SNAPSHOT
quickfixj-examples-ordermatch
diff --git a/quickfixj-examples/pom.xml b/quickfixj-examples/pom.xml
index 6fd9c80993..e0b4f843cf 100644
--- a/quickfixj-examples/pom.xml
+++ b/quickfixj-examples/pom.xml
@@ -4,7 +4,7 @@
org.quickfixj
quickfixj-parent
- 2.0.1-SNAPSHOT
+ 2.1.0-SNAPSHOT
quickfixj-examples
diff --git a/quickfixj-messages/pom.xml b/quickfixj-messages/pom.xml
index 76b7b630fa..779579c908 100644
--- a/quickfixj-messages/pom.xml
+++ b/quickfixj-messages/pom.xml
@@ -4,7 +4,7 @@
org.quickfixj
quickfixj-parent
- 2.0.1-SNAPSHOT
+ 2.1.0-SNAPSHOT
quickfixj-messages
diff --git a/quickfixj-messages/quickfixj-messages-all/pom.xml b/quickfixj-messages/quickfixj-messages-all/pom.xml
index 7154da1351..574a1b8c69 100644
--- a/quickfixj-messages/quickfixj-messages-all/pom.xml
+++ b/quickfixj-messages/quickfixj-messages-all/pom.xml
@@ -4,7 +4,7 @@
org.quickfixj
quickfixj-messages
- 2.0.1-SNAPSHOT
+ 2.1.0-SNAPSHOT
quickfixj-messages-all
diff --git a/quickfixj-messages/quickfixj-messages-fix40/pom.xml b/quickfixj-messages/quickfixj-messages-fix40/pom.xml
index 8a6bdd354a..757c287177 100644
--- a/quickfixj-messages/quickfixj-messages-fix40/pom.xml
+++ b/quickfixj-messages/quickfixj-messages-fix40/pom.xml
@@ -4,7 +4,7 @@
org.quickfixj
quickfixj-messages
- 2.0.1-SNAPSHOT
+ 2.1.0-SNAPSHOT
quickfixj-messages-fix40
diff --git a/quickfixj-messages/quickfixj-messages-fix41/pom.xml b/quickfixj-messages/quickfixj-messages-fix41/pom.xml
index 3ed73eeba3..e4e729e220 100644
--- a/quickfixj-messages/quickfixj-messages-fix41/pom.xml
+++ b/quickfixj-messages/quickfixj-messages-fix41/pom.xml
@@ -4,7 +4,7 @@
org.quickfixj
quickfixj-messages
- 2.0.1-SNAPSHOT
+ 2.1.0-SNAPSHOT
quickfixj-messages-fix41
diff --git a/quickfixj-messages/quickfixj-messages-fix42/pom.xml b/quickfixj-messages/quickfixj-messages-fix42/pom.xml
index 909da5fe73..16ea74a562 100644
--- a/quickfixj-messages/quickfixj-messages-fix42/pom.xml
+++ b/quickfixj-messages/quickfixj-messages-fix42/pom.xml
@@ -4,7 +4,7 @@
org.quickfixj
quickfixj-messages
- 2.0.1-SNAPSHOT
+ 2.1.0-SNAPSHOT
quickfixj-messages-fix42
diff --git a/quickfixj-messages/quickfixj-messages-fix43/pom.xml b/quickfixj-messages/quickfixj-messages-fix43/pom.xml
index a83d24a717..342fd0f673 100644
--- a/quickfixj-messages/quickfixj-messages-fix43/pom.xml
+++ b/quickfixj-messages/quickfixj-messages-fix43/pom.xml
@@ -4,7 +4,7 @@
org.quickfixj
quickfixj-messages
- 2.0.1-SNAPSHOT
+ 2.1.0-SNAPSHOT
quickfixj-messages-fix43
diff --git a/quickfixj-messages/quickfixj-messages-fix44/pom.xml b/quickfixj-messages/quickfixj-messages-fix44/pom.xml
index 999cd62ea2..4f3d740ed8 100644
--- a/quickfixj-messages/quickfixj-messages-fix44/pom.xml
+++ b/quickfixj-messages/quickfixj-messages-fix44/pom.xml
@@ -4,7 +4,7 @@
org.quickfixj
quickfixj-messages
- 2.0.1-SNAPSHOT
+ 2.1.0-SNAPSHOT
quickfixj-messages-fix44
diff --git a/quickfixj-messages/quickfixj-messages-fix50/pom.xml b/quickfixj-messages/quickfixj-messages-fix50/pom.xml
index 711a007e26..80e006b579 100644
--- a/quickfixj-messages/quickfixj-messages-fix50/pom.xml
+++ b/quickfixj-messages/quickfixj-messages-fix50/pom.xml
@@ -4,7 +4,7 @@
org.quickfixj
quickfixj-messages
- 2.0.1-SNAPSHOT
+ 2.1.0-SNAPSHOT
quickfixj-messages-fix50
diff --git a/quickfixj-messages/quickfixj-messages-fix50sp1/pom.xml b/quickfixj-messages/quickfixj-messages-fix50sp1/pom.xml
index ff24ab88db..c94e97f794 100644
--- a/quickfixj-messages/quickfixj-messages-fix50sp1/pom.xml
+++ b/quickfixj-messages/quickfixj-messages-fix50sp1/pom.xml
@@ -4,7 +4,7 @@
org.quickfixj
quickfixj-messages
- 2.0.1-SNAPSHOT
+ 2.1.0-SNAPSHOT
quickfixj-messages-fix50sp1
diff --git a/quickfixj-messages/quickfixj-messages-fix50sp2/pom.xml b/quickfixj-messages/quickfixj-messages-fix50sp2/pom.xml
index 29c113eb54..49bc2c9471 100644
--- a/quickfixj-messages/quickfixj-messages-fix50sp2/pom.xml
+++ b/quickfixj-messages/quickfixj-messages-fix50sp2/pom.xml
@@ -4,7 +4,7 @@
org.quickfixj
quickfixj-messages
- 2.0.1-SNAPSHOT
+ 2.1.0-SNAPSHOT
quickfixj-messages-fix50sp2
diff --git a/quickfixj-messages/quickfixj-messages-fixt11/pom.xml b/quickfixj-messages/quickfixj-messages-fixt11/pom.xml
index 51f46292af..c959b475c7 100644
--- a/quickfixj-messages/quickfixj-messages-fixt11/pom.xml
+++ b/quickfixj-messages/quickfixj-messages-fixt11/pom.xml
@@ -4,7 +4,7 @@
org.quickfixj
quickfixj-messages
- 2.0.1-SNAPSHOT
+ 2.1.0-SNAPSHOT
quickfixj-messages-fixt11