diff --git a/custom-applications/pom.xml b/custom-applications/pom.xml index 810ebdc..e552e68 100644 --- a/custom-applications/pom.xml +++ b/custom-applications/pom.xml @@ -16,6 +16,7 @@ using-fixlatest-server using-fixlatest-client - + using-legacy-codegen-server + using-legacy-codegen-client \ No newline at end of file diff --git a/custom-applications/readme.md b/custom-applications/readme.md index 4aa9e43..1600ad5 100644 --- a/custom-applications/readme.md +++ b/custom-applications/readme.md @@ -1,6 +1,6 @@ # Example Applications -The Example applications are trivial and only intended to demonstrate the build and runtime dependencies when using custom protocols. +The example applications are trivial and only intended to demonstrate the build and runtime dependencies when using custom protocols. The example applications use `quickfixj-spring-boot-starter`. diff --git a/custom-applications/using-fixlatest-client/src/main/java/org/quickfixj/examples/fixlatest/custom/client/ClientMessageCracker.java b/custom-applications/using-fixlatest-client/src/main/java/org/quickfixj/examples/fixlatest/custom/client/ClientMessageCracker.java index c07ca07..dda6509 100644 --- a/custom-applications/using-fixlatest-client/src/main/java/org/quickfixj/examples/fixlatest/custom/client/ClientMessageCracker.java +++ b/custom-applications/using-fixlatest-client/src/main/java/org/quickfixj/examples/fixlatest/custom/client/ClientMessageCracker.java @@ -7,12 +7,8 @@ import quickfix.fixlatest.BusinessMessageReject; import quickfix.fixlatest.ExecutionReport; import quickfix.fixlatest.MessageCracker; -import quickfix.fixlatest.NewOrderSingle; import quickfix.fixlatest.component.Instrument; -import java.time.LocalDateTime; -import java.util.UUID; - public class ClientMessageCracker extends MessageCracker { private final Logger log = LoggerFactory.getLogger(ClientMessageCracker.class); diff --git a/custom-applications/using-legacy-codegen-client/pom.xml b/custom-applications/using-legacy-codegen-client/pom.xml new file mode 100644 index 0000000..7a09ebc --- /dev/null +++ b/custom-applications/using-legacy-codegen-client/pom.xml @@ -0,0 +1,66 @@ + + 4.0.0 + + + org.quickfixj.custom.examples + custom-applications-parent + 0.0.1-SNAPSHOT + + + using-legacy-codegen-client + jar + + + + io.allune + quickfixj-spring-boot-starter + + + io.allune + quickfixj-spring-boot-actuator + + + org.springframework.boot + spring-boot-starter-web + + + org.slf4j + slf4j-api + + + org.slf4j + slf4j-simple + + + org.quickfixj + quickfixj-core + + + org.quickfixj + quickfixj-messages-fixt11 + + + org.quickfixj.custom.examples + legacy-codegen-application-messages + 0.0.1-SNAPSHOT + + + + + + ${project.artifactId} + + + org.springframework.boot + spring-boot-maven-plugin + + + + repackage + + + + + + + \ No newline at end of file diff --git a/custom-applications/using-legacy-codegen-client/src/main/java/org/quickfixj/examples/legacy/custom/client/ClientApplication.java b/custom-applications/using-legacy-codegen-client/src/main/java/org/quickfixj/examples/legacy/custom/client/ClientApplication.java new file mode 100644 index 0000000..4890c0b --- /dev/null +++ b/custom-applications/using-legacy-codegen-client/src/main/java/org/quickfixj/examples/legacy/custom/client/ClientApplication.java @@ -0,0 +1,11 @@ +package org.quickfixj.examples.legacy.custom.client; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class ClientApplication { + public static void main(String[] args) throws InterruptedException { + SpringApplication.run(ClientApplication.class, args); + } +} \ No newline at end of file diff --git a/custom-applications/using-legacy-codegen-client/src/main/java/org/quickfixj/examples/legacy/custom/client/ClientApplicationAdapter.java b/custom-applications/using-legacy-codegen-client/src/main/java/org/quickfixj/examples/legacy/custom/client/ClientApplicationAdapter.java new file mode 100644 index 0000000..be87def --- /dev/null +++ b/custom-applications/using-legacy-codegen-client/src/main/java/org/quickfixj/examples/legacy/custom/client/ClientApplicationAdapter.java @@ -0,0 +1,82 @@ +package org.quickfixj.examples.legacy.custom.client; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import quickfix.*; +import quickfix.field.*; +import quickfix.fix50sp2.MessageCracker; +import quickfix.fix50sp2.NewOrderSingle; +import quickfix.fix50sp2.component.Instrument; +import quickfix.fix50sp2.component.OrderQtyData; + +import java.time.LocalDateTime; +import java.util.UUID; + +public class ClientApplicationAdapter implements Application { + + private final MessageCracker messageCracker; + private final Logger log = LoggerFactory.getLogger(ClientApplicationAdapter.class); + + public ClientApplicationAdapter(MessageCracker messageCracker) { + this.messageCracker = messageCracker; + } + + @Override + public void onLogon(SessionID sessionID) { + log.info("logged on [{}] - [{}]", sessionID.getSenderCompID(), sessionID.getTargetCompID()); + try { + Session.sendToTarget(newOrderSingle(),sessionID); + } catch (SessionNotFound e) { + log.error("SessionNot Found", e); + } + } + + @Override + public void onLogout(SessionID sessionID) { + log.info("logged out [{}] - [{}]", sessionID.getSenderCompID(), sessionID.getTargetCompID()); + } + + @Override + public void fromAdmin(Message message, SessionID sessionId) { + log.info("fromAdmin: Message={}, SessionId={}", message, sessionId); + } + + @Override + public void onCreate(SessionID sessionId) { + log.info("onCreate: SessionId={}", sessionId); + } + + @Override + public void toAdmin(Message message, SessionID sessionId) { + log.info("toAdmin: Message={}, SessionId={}", message, sessionId); + } + + @Override + public void toApp(Message message, SessionID sessionId) { + log.info("toApp: Message={}, SessionId={}", message, sessionId); + } + + @Override + public void fromApp(Message message, SessionID sessionID) + throws FieldNotFound, IncorrectTagValue, UnsupportedMessageType { + this.messageCracker.crack(message, sessionID); + } + + private static NewOrderSingle newOrderSingle() { + NewOrderSingle newOrderSingle = new NewOrderSingle(); + newOrderSingle.set(new ClOrdID(UUID.randomUUID().toString())); + newOrderSingle.set(new OrdType(OrdType.LIMIT)); + newOrderSingle.set(new Price(99.09d)); + newOrderSingle.set(new Side(Side.BUY)); + newOrderSingle.set(new TransactTime(LocalDateTime.now())); + Instrument instrument = new Instrument(); + instrument.set(new Symbol("EX.AMPLE")); + instrument.set(new SecurityIDSource(SecurityIDSource.EXAMPLE_CUSTOM_SECURITY_ID_SOURCE)); + instrument.set(new SecurityID("202491685")); + newOrderSingle.set(instrument); + OrderQtyData orderQtyData = new OrderQtyData(); + orderQtyData.set(new OrderQty(1.0d)); + newOrderSingle.set(orderQtyData); + return newOrderSingle; + } +} \ No newline at end of file diff --git a/custom-applications/using-legacy-codegen-client/src/main/java/org/quickfixj/examples/legacy/custom/client/ClientApplicationConfiguration.java b/custom-applications/using-legacy-codegen-client/src/main/java/org/quickfixj/examples/legacy/custom/client/ClientApplicationConfiguration.java new file mode 100644 index 0000000..522fc48 --- /dev/null +++ b/custom-applications/using-legacy-codegen-client/src/main/java/org/quickfixj/examples/legacy/custom/client/ClientApplicationConfiguration.java @@ -0,0 +1,31 @@ +package org.quickfixj.examples.legacy.custom.client; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import quickfix.*; +import quickfix.fix50sp2.MessageCracker; + +@Configuration +public class ClientApplicationConfiguration { + + @Bean + MessageCracker messageCracker() { + return new ClientMessageCracker(); + } + + @Bean + Application application(MessageCracker messageCracker) { + return new ClientApplicationAdapter(messageCracker); + } + + @Bean + Initiator clientInitiator( + Application clientApplication, + MessageStoreFactory clientMessageStoreFactory, + SessionSettings clientSessionSettings, + LogFactory clientLogFactory, + MessageFactory clientMessageFactory) throws ConfigError { + return new ThreadedSocketInitiator(clientApplication, clientMessageStoreFactory, clientSessionSettings, + clientLogFactory, clientMessageFactory); + } +} diff --git a/custom-applications/using-legacy-codegen-client/src/main/java/org/quickfixj/examples/legacy/custom/client/ClientMessageCracker.java b/custom-applications/using-legacy-codegen-client/src/main/java/org/quickfixj/examples/legacy/custom/client/ClientMessageCracker.java new file mode 100644 index 0000000..62106b1 --- /dev/null +++ b/custom-applications/using-legacy-codegen-client/src/main/java/org/quickfixj/examples/legacy/custom/client/ClientMessageCracker.java @@ -0,0 +1,40 @@ +package org.quickfixj.examples.legacy.custom.client; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import quickfix.FieldNotFound; +import quickfix.SessionID; +import quickfix.field.*; +import quickfix.fix50sp2.BusinessMessageReject; +import quickfix.fix50sp2.ExecutionReport; +import quickfix.fix50sp2.MessageCracker; +import quickfix.fix50sp2.component.Instrument; + +public class ClientMessageCracker extends MessageCracker { + private final Logger log = LoggerFactory.getLogger(ClientMessageCracker.class); + + @Override + public void onMessage(ExecutionReport executionReport, SessionID sessionID) + throws FieldNotFound { + Instrument instrumentComponent = executionReport.getInstrument(); // invariant + log.info("Received ExecutionReport from sender [{}]:: clOrdID {}, symbol {}, side {}, transactTime {}, ordType {}, securityIDSource {}, securityID {}", + executionReport.getHeader().getString(SenderCompID.FIELD), + instrumentComponent.getSymbol().getValue(), + executionReport.getClOrdID().getValue(), + executionReport.getSide().getValue(), + executionReport.getTransactTime().getValue(), + executionReport.getOrdType().getValue(), + instrumentComponent.isSetSecurityIDSource() ? instrumentComponent.getSecurityIDSource().getValue() : "", + instrumentComponent.isSetSecurityID() ? instrumentComponent.getSecurityID().getValue() : ""); + } + + @Override + public void onMessage(BusinessMessageReject businessMessageReject, SessionID sessionID) + throws FieldNotFound { + log.error("Received Business Message Reject from sender [{}]: refMsgType {}, businessRejectReason{}, Text {}", + sessionID.getSenderCompID(), + businessMessageReject.getRefMsgType().getValue(), + businessMessageReject.getBusinessRejectReason().getValue(), + businessMessageReject.isSetText() ? businessMessageReject.getText().getValue() : ""); + } +} \ No newline at end of file diff --git a/custom-applications/using-legacy-codegen-client/src/main/resources/application.yml b/custom-applications/using-legacy-codegen-client/src/main/resources/application.yml new file mode 100644 index 0000000..d68eb99 --- /dev/null +++ b/custom-applications/using-legacy-codegen-client/src/main/resources/application.yml @@ -0,0 +1,53 @@ +spring: + main: + allow-bean-definition-overriding: true + +server: + port: 8083 + +management: + endpoint: + health: + show-details: always + quickfixjclient: + enabled: true + endpoints: + web: + exposure: + include: quickfixjclient,health + +app: + session: + sender-comp-id: L-INITIATOR + +quickfixj: + client: + enabled: true + configString: | + [default] + BeginString=FIXT.1.1 + DefaultApplVerID=FIX.5.0SP2 + UseDataDictionary=Y + TransportDataDictionary=FIXT11.xml + AppDataDictionary.FIX.5.0SP2=FIX50SP2.modified.xml + ConnectionType=initiator + TimeZone=Europe/London + StartTime=00:00:00 + EndTime=00:00:00 + ResetOnLogon=Y + ResetOnLogout=Y + ResetOnDisconnect=Y + ValidateUnorderedFields=Y + ValidateUserDefinedFields=Y + CheckLatency=Y + HeartBtInt=30 + PersistMessages=N + SocketConnectHost=localhost + SenderCompID=${app.session.sender-comp-id} + + #SSL + SocketUseSSL=N + + [session] + TargetCompID=L-ACCEPTOR + SocketConnectPort=9882 diff --git a/custom-applications/using-legacy-codegen-server/pom.xml b/custom-applications/using-legacy-codegen-server/pom.xml new file mode 100644 index 0000000..6baf6e3 --- /dev/null +++ b/custom-applications/using-legacy-codegen-server/pom.xml @@ -0,0 +1,66 @@ + + 4.0.0 + + + org.quickfixj.custom.examples + custom-applications-parent + 0.0.1-SNAPSHOT + + + using-legacy-codegen-server + jar + + + + io.allune + quickfixj-spring-boot-starter + + + io.allune + quickfixj-spring-boot-actuator + + + org.springframework.boot + spring-boot-starter-web + + + org.slf4j + slf4j-api + + + org.slf4j + slf4j-simple + + + org.quickfixj + quickfixj-core + + + org.quickfixj + quickfixj-messages-fixt11 + + + org.quickfixj.custom.examples + legacy-codegen-application-messages + 0.0.1-SNAPSHOT + + + + + + ${project.artifactId} + + + org.springframework.boot + spring-boot-maven-plugin + + + + repackage + + + + + + + \ No newline at end of file diff --git a/custom-applications/using-legacy-codegen-server/src/main/java/org/quickfixj/examples/legacy/custom/server/ServerApplication.java b/custom-applications/using-legacy-codegen-server/src/main/java/org/quickfixj/examples/legacy/custom/server/ServerApplication.java new file mode 100644 index 0000000..7a5fb0e --- /dev/null +++ b/custom-applications/using-legacy-codegen-server/src/main/java/org/quickfixj/examples/legacy/custom/server/ServerApplication.java @@ -0,0 +1,11 @@ +package org.quickfixj.examples.legacy.custom.server; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class ServerApplication { + public static void main(String[] args) throws InterruptedException { + SpringApplication.run(ServerApplication.class, args); + } +} diff --git a/custom-applications/using-legacy-codegen-server/src/main/java/org/quickfixj/examples/legacy/custom/server/ServerApplicationAdapter.java b/custom-applications/using-legacy-codegen-server/src/main/java/org/quickfixj/examples/legacy/custom/server/ServerApplicationAdapter.java new file mode 100644 index 0000000..0f41215 --- /dev/null +++ b/custom-applications/using-legacy-codegen-server/src/main/java/org/quickfixj/examples/legacy/custom/server/ServerApplicationAdapter.java @@ -0,0 +1,53 @@ +package org.quickfixj.examples.legacy.custom.server; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import quickfix.*; +import quickfix.fix50sp2.MessageCracker; + + +public class ServerApplicationAdapter extends ApplicationAdapter { + + private final MessageCracker messageCracker; + private final Logger log = LoggerFactory.getLogger(ServerApplicationAdapter.class); + + public ServerApplicationAdapter(MessageCracker messageCracker) { + this.messageCracker = messageCracker; + } + + @Override + public void onLogon(SessionID sessionID) { + log.info("logged on [{}] - [{}]", sessionID.getSenderCompID(), sessionID.getTargetCompID()); + } + + @Override + public void onLogout(SessionID sessionID) { + log.info("logged out [{}] - [{}]", sessionID.getSenderCompID(), sessionID.getTargetCompID()); + } + + @Override + public void fromAdmin(Message message, SessionID sessionId) { + log.info("fromAdmin: Message={}, SessionId={}", message, sessionId); + } + + @Override + public void onCreate(SessionID sessionId) { + log.info("onCreate: SessionId={}", sessionId); + } + + @Override + public void toAdmin(Message message, SessionID sessionId) { + log.info("toAdmin: Message={}, SessionId={}", message, sessionId); + } + + @Override + public void toApp(Message message, SessionID sessionId) { + log.info("toApp: Message={}, SessionId={}", message, sessionId); + } + + @Override + public void fromApp(Message message, SessionID sessionID) + throws FieldNotFound, IncorrectTagValue, UnsupportedMessageType { + this.messageCracker.crack(message, sessionID); + } +} \ No newline at end of file diff --git a/custom-applications/using-legacy-codegen-server/src/main/java/org/quickfixj/examples/legacy/custom/server/ServerApplicationConfiguration.java b/custom-applications/using-legacy-codegen-server/src/main/java/org/quickfixj/examples/legacy/custom/server/ServerApplicationConfiguration.java new file mode 100644 index 0000000..4eadad0 --- /dev/null +++ b/custom-applications/using-legacy-codegen-server/src/main/java/org/quickfixj/examples/legacy/custom/server/ServerApplicationConfiguration.java @@ -0,0 +1,32 @@ +package org.quickfixj.examples.legacy.custom.server; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import quickfix.*; +import quickfix.fix50sp2.MessageCracker; + +@Configuration +public class ServerApplicationConfiguration { + @Bean + MessageCracker messageCracker() { + return new ServerMessageCracker(); + } + + @Bean + Application application(MessageCracker messageCracker) { + return new ServerApplicationAdapter(messageCracker); + } + + @Bean + Acceptor acceptor(Application application, + MessageStoreFactory messageStoreFactory, + SessionSettings sessionSettings, + LogFactory logFactory, + MessageFactory messageFactory) throws ConfigError { + return new ThreadedSocketAcceptor(application, + messageStoreFactory, + sessionSettings, + logFactory, + messageFactory); + } +} diff --git a/custom-applications/using-legacy-codegen-server/src/main/java/org/quickfixj/examples/legacy/custom/server/ServerMessageCracker.java b/custom-applications/using-legacy-codegen-server/src/main/java/org/quickfixj/examples/legacy/custom/server/ServerMessageCracker.java new file mode 100644 index 0000000..933f4e7 --- /dev/null +++ b/custom-applications/using-legacy-codegen-server/src/main/java/org/quickfixj/examples/legacy/custom/server/ServerMessageCracker.java @@ -0,0 +1,72 @@ +package org.quickfixj.examples.legacy.custom.server; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import quickfix.*; +import quickfix.field.*; +import quickfix.fix50sp2.MessageCracker; +import quickfix.fix50sp2.BusinessMessageReject; +import quickfix.fix50sp2.ExecutionReport; +import quickfix.fix50sp2.NewOrderSingle; +import quickfix.fix50sp2.component.Instrument; + +import java.time.LocalDateTime; +import java.util.UUID; + +public class ServerMessageCracker extends MessageCracker { + private final Logger log = LoggerFactory.getLogger(ServerMessageCracker.class); + + @Override + public void onMessage(NewOrderSingle newOrderSingle, SessionID sessionID) + throws FieldNotFound { + Instrument instrumentComponent = newOrderSingle.getInstrument(); // invariant + log.info("Received NewOrderSingle from sender [{}]: clOrdID {}, symbol {}, side {}, transactTime {}, ordType {}, securityIDSource {}, securityID {}", + newOrderSingle.getHeader().getString(SenderCompID.FIELD), + instrumentComponent.getSymbol().getValue(), + newOrderSingle.getClOrdID().getValue(), + newOrderSingle.getSide().getValue(), + newOrderSingle.getTransactTime().getValue(), + newOrderSingle.getOrdType().getValue(), + instrumentComponent.isSetSecurityIDSource() ? instrumentComponent.getSecurityIDSource().getValue() : "", + instrumentComponent.isSetSecurityID() ? instrumentComponent.getSecurityID().getValue() : ""); + try { + Session.sendToTarget(executionReport(newOrderSingle),sessionID); + } catch (SessionNotFound e) { + log.error("SessionNot Found", e); + } + } + + @Override + public void onMessage(BusinessMessageReject businessMessageReject, SessionID sessionID) + throws FieldNotFound { + log.error("Received Business Message Reject from sender [{}]: refMsgType {}, businessRejectReason{}, Text {}", + sessionID.getSenderCompID(), + businessMessageReject.getRefMsgType().getValue(), + businessMessageReject.getBusinessRejectReason().getValue(), + businessMessageReject.isSetText() ? businessMessageReject.getText().getValue() : ""); + } + + private static ExecutionReport executionReport(NewOrderSingle newOrderSingle) throws FieldNotFound { + ExecutionReport executionReport = new ExecutionReport(); + executionReport.set(newOrderSingle.getClOrdID()); + executionReport.set(newOrderSingle.getSide()); + executionReport.set(newOrderSingle.getOrdType()); + executionReport.set(new TransactTime(LocalDateTime.now())); + executionReport.set(new OrderID(UUID.randomUUID().toString())); + executionReport.set(new ExecID(UUID.randomUUID().toString())); + executionReport.set(new ExecType(ExecType.TRADE)); + executionReport.set(new OrdStatus(OrdStatus.FILLED)); + executionReport.set(newOrderSingle.getInstrument()); + executionReport.set(new LeavesQty(0)); + executionReport.set(new CumQty(newOrderSingle.getOrderQtyData().getOrderQty().getValue())); + executionReport.set(new LastQty(newOrderSingle.getOrderQtyData().getOrderQty().getValue())); + if (newOrderSingle.isSetPrice()) { + Price px = newOrderSingle.getPrice(); + executionReport.set(px); + executionReport.set(new LastPx(px.getValue())); + } else { + executionReport.set(new LastPx(1.0d)); + } + return executionReport; + } +} diff --git a/custom-applications/using-legacy-codegen-server/src/main/resources/application.yml b/custom-applications/using-legacy-codegen-server/src/main/resources/application.yml new file mode 100644 index 0000000..6b20d22 --- /dev/null +++ b/custom-applications/using-legacy-codegen-server/src/main/resources/application.yml @@ -0,0 +1,70 @@ +spring: + main: + allow-bean-definition-overriding: true + +server: + port: 8082 + +management: + endpoint: + health: + show-details: always + quickfixjserver: + enabled: true + health: + quickfixjserver: + enabled: true + endpoints: + web: + exposure: + include: quickfixjserver,health + +logging: + group: + fix: quickfix.ThreadedSocketAcceptor, quickfixj.msg.incoming, quickfixj.msg,outgoing + examples: org.quickfixj.examples + +app: + session: + sender-comp-id: L-ACCEPTOR + socket-accept-port: 9882 + +quickfixj: + server: + enabled: true + auto-startup: true + force-disconnect: false + phase: 0 + jmx-enabled: true + concurrent: + enabled: true + useDefaultExecutorFactory: true + message-store-factory: memory + log-factory: slf4j + configString: | + [default] + BeginString=FIXT.1.1 + DefaultApplVerID=FIX.5.0SP2 + UseDataDictionary=Y + TransportDataDictionary=FIXT11.xml + AppDataDictionary.FIX.5.0SP2=FIX50SP2.modified.xml + ConnectionType=acceptor + TimeZone=Europe/London + StartTime=00:00:00 + EndTime=00:00:00 + ResetOnLogon=Y + ResetOnLogout=Y + ResetOnDisconnect=Y + ValidateUnorderedFields=Y + ValidateUserDefinedFields=Y + CheckLatency=Y + HeartBtInt=30 + PersistMessages=N + SenderCompID=${app.session.sender-comp-id} + SocketAcceptPort=${app.session.socket-accept-port} + + #SSL + SocketUseSSL=N + + [session] + TargetCompID=L-INITIATOR