quickfixj-spring-boot-starter
                                
                                 quickfixj-spring-boot-starter copied to clipboard
                                
                                    quickfixj-spring-boot-starter copied to clipboard
                            
                            
                            
                        Spring Boot Starter for QuickFIX/J
image:https://travis-ci.org/esanchezros/quickfixj-spring-boot-starter.svg?branch=master["Build Status", link="https://travis-ci.org/esanchezros/quickfixj-spring-boot-starter"] image:https://codecov.io/gh/esanchezros/quickfixj-spring-boot-starter/branch/master/graph/badge.svg["codecov",link="https://codecov.io/gh/esanchezros/quickfixj-spring-boot-starter"] image:https://img.shields.io/badge/maven%20central-v2.13.0-blue.svg["Maven Central",link="https://search.maven.org/#search%7Cga%7C1%7Ca%3A%22quickfixj-spring-boot-starter%22"] image:https://img.shields.io/hexpm/l/plug.svg["Apache 2",link="http://www.apache.org/licenses/LICENSE-2.0"] image:https://img.shields.io/badge/quickfixj-2.3.1-blue.svg["QuickFIX/J 2.3.1", link="https://github.com/quickfix-j/quickfixj"] image:https://api.codacy.com/project/badge/Grade/3fda9a73471c40e781617cfba9043950["Codacy code quality", link="https://www.codacy.com/app/esanchezros/quickfixj-spring-boot-starter?utm_source=github.com&utm_medium=referral&utm_content=esanchezros/quickfixj-spring-boot-starter&utm_campaign=Badge_Grade"]
= Spring Boot Starter for QuickFIX/J (Spring Boot 2)
This project is a https://spring.io/projects/spring-boot/[Spring Boot Starter] for https://github.com/quickfix-j/quickfixj[QuickFIX/J messaging engine for the FIX protocol]. It simplifies the configuration required to create and start an https://www.quickfixj.org/javadoc/2.1.0/quickfix/Initiator.html[Initiator] or https://www.quickfixj.org/javadoc/2.1.0/quickfix/Acceptor.html[Acceptor], and handles the lifecycle of the https://www.quickfixj.org/javadoc/2.1.0/quickfix/Connector.html[Connector].
== Getting started
To use the QuickFIX/J Server or QuickFIX/J Client you have to add the QuickFIX/J Spring Boot Starter dependency in your project.
[source,xml]
=== QuickFIX/J Spring Boot Starter - Server (Acceptor)
The @EnableQuickFixJServer will auto configure a QuickFIX/J Server:
[source,java]
@EnableQuickFixJServer @SpringBootApplication public class AppServer {
public static void main(String[] args) {
    SpringApplication.run(AppServer.class, args);
}
}
Additionally you need to add a https://www.quickfixj.org/usermanual/2.3.0/usage/configuration.html[quickfixj-server.cfg] file to configure the FIX sessions. The configuration is resolved using the following approach:
- By a QuickFIX/J acceptor configuration string defined by the quickfixj.server.configStringproperty
- By the presence of a quickfix.SessionSettingsbean namedserverSessionSettings
- By a configuration file defined by the quickfixj.server.configproperty
- By the presence of the quickfixj.server.configsystem property
- By a quickfixj-server.cfgin the working directory or at the root of the classpath
==== QuickFIX/J Server properties
[source,properties]
quickfixj.server.config=classpath:quickfixj-server.cfg              # location of the quickfixj acceptor configuration file
quickfixj.server.configString=[default]  \r\n...                   # the content of the QuickFIX/J acceptor configuration file
quickfixj.server.auto-startup=true                                  # whether to auto-connect to the remote endpoint at start up (default: true)
quickfixj.server.force-disconnect=false                             # whether logged on sessions should be disconnected forcibly when the connector is stopped (default: false)
quickfixj.server.phase=0                                            # phase in which this connection manager should be started and stopped (default: Integer.MAX_VALUE)
quickfixj.server.jmx-enabled=true                                   # whether to register the jmx mbeans for the acceptor (default: false)
quickfixj.server.message-store-factory=memory                       # [cachedfile,file,jdbc,memory,noop,sleepycat] (default: memory)
quickfixj.server.log-factory=screen                                 # [compositelog,file,jdbc,slf4j,screen] (default: screen)
quickfixj.server.concurrent.enabled=true                            # whether to use a simple SocketAcceptor or a ThreadedSocketAcceptor (default: false - uses SocketAcceptor)
quickfixj.server.concurrent.useDefaultExecutorFactory=true          # whether to use a default ExecutorFactory to create the SocketAcceptor (default: false)
quickfixj.server.concurrent.queueCapacity=Integer.MAX_VALUE         # when using the default ExecutorFactory, the Executor's queue capacity (default: Integer.MAX_VALUE)
quickfixj.server.concurrent.corePoolSize=8                          # when using the default ExecutorFactory, the Executor's core pool size (default: 8)
quickfixj.server.concurrent.maxPoolSize=Integer.MAX_VALUE           # when using the default ExecutorFactory, the Executor's max pool size (default: Integer.MAX_VALUE)
quickfixj.server.concurrent.allowCoreThreadTimeOut=true             # when using the default ExecutorFactory, whether to allow core thread timeout on the Executor (default: true)
quickfixj.server.concurrent.keepAliveSeconds=60                     # when using the default ExecutorFactory, the Executor's keep alive in seconds (default: 60)
quickfixj.server.concurrent.waitForTasksToCompleteOnShutdown=false  # when using the default ExecutorFactory, whether to wait for tasks to complete on shutdown on the Executor (default: false)
quickfixj.server.concurrent.awaitTerminationSeconds=0                # when using the default ExecutorFactory, the Executor's await termination in seconds (default: 0)
quickfixj.server.concurrent.threadNamePrefix="QuickFixJ Spring Boot Starter thread-" # when using the default ExecutorFactory, the Executor's thread name prefix (default: QuickFixJ Spring Boot Starter thread-)
[source,yml]
quickfixj: server: config: classpath:quickfixj-server.cfg auto-startup: true force-disconnect: false phase: 0 jmx-enabled: true concurrent: enabled: true useDefaultExecutorFactory: true queueCapacity: Integer.MAX_VALUE corePoolSize: 8 maxPoolSize: Integer.MAX_VALUE allowCoreThreadTimeOut: true keepAliveSeconds: 60 waitForTasksToCompleteOnShutdown: false awaitTerminationMillis: 0 threadNamePrefix: "QuickFixJ Spring Boot Starter thread-" message-store-factory: memory log-factory: screen
==== QuickFIX/J acceptor configuration file in properties and yaml files
Using the quickfixj.server.configString property:
[source,properties]
quickfixj.server.configString=[default]  \r\n
FileStorePath=target/data/executor  \r\n
ConnectionType=acceptor  \r\n
StartTime=00:00:00  \r\n
EndTime=00:00:00  \r\n
HeartBtInt=30  \r\n
ValidOrderTypes=1,2,F  \r\n
SenderCompID=EXEC  \r\n
TargetCompID=BANZAI  \r\n
UseDataDictionary=Y  \r\n
DefaultMarketPrice=12.30  \r\n
FileLogPath=logs-server  \r\n
\r\n
[session]  \r\n
BeginString=FIX.4.0  \r\n
SocketAcceptPort=9876  \r\n
\r\n
[session]  \r\n
BeginString=FIX.4.1  \r\n
SocketAcceptPort=9877  \r\n
\r\n
[session]  \r\n
BeginString=FIX.4.2  \r\n
SocketAcceptPort=9878  \r\n
\r\n
[session]  \r\n
BeginString=FIX.4.3  \r\n
SocketAcceptPort=9879  \r\n
\r\n
[session]  \r\n
BeginString=FIX.4.4  \r\n
SocketAcceptPort=9880  \r\n
\r\n
[session]  \r\n
BeginString=FIXT.1.1  \r\n
DefaultApplVerID=FIX.5.0SP2  \r\n
SocketAcceptPort=9881
[source,yml]
quickfixj: server: configString: | [default] FileStorePath=target/data/executor ConnectionType=acceptor StartTime=00:00:00 EndTime=00:00:00 HeartBtInt=30 ValidOrderTypes=1,2,F SenderCompID=EXEC TargetCompID=BANZAI UseDataDictionary=Y DefaultMarketPrice=12.30 FileLogPath=logs-server
  [session]
  BeginString=FIX.4.0
  SocketAcceptPort=9876
  [session]
  BeginString=FIX.4.1
  SocketAcceptPort=9877
  [session]
  BeginString=FIX.4.2
  SocketAcceptPort=9878
  [session]
  BeginString=FIX.4.3
  SocketAcceptPort=9879
  [session]
  BeginString=FIX.4.4
  SocketAcceptPort=9880
  [session]
  BeginString=FIXT.1.1
  DefaultApplVerID=FIX.5.0SP2
  SocketAcceptPort=9881
==== QuickFIX/J Server Actuator properties
To enable the actuator endpoints you will also have to add the QuickFIX/J Spring Boot Actuator dependency.
[source,xml]
And enable the QuickFix/J Server endpoint in Spring:
[source,properties]
management.endpoint.quickfixjserver.enabled=true # whether the endpoint is enabled or not management.endpoints.web.exposure.include=quickfixjserver # whether the endpoint will be exposed
[source,yml]
management: endpoint: quickfixjserver: enabled: true endpoints: web: exposure: include: quickfixjserver
Example usage:
http://localhost:8081/actuator/quickfixjserver
[source,json]
{ "FIX.4.2:EXEC->BANZAI": { "SenderCompID": "EXEC", "StartTime": "00:00:00", "DefaultMarketPrice": "12.30", "ValidOrderTypes": "1,2,F", "ConnectionType": "acceptor", "EndTime": "00:00:00", "BeginString": "FIX.4.2", "SocketAcceptPort": "9878", "TargetCompID": "BANZAI", "SenderCompID": "EXEC", "HeartBtInt": "30", "BeginString": "FIX.4.2", "TargetCompID": "BANZAI", "FileStorePath": "target/data/executor", "UseDataDictionary": "Y" }, "FIX.4.1:EXEC->BANZAI": { "SenderCompID": "EXEC", "StartTime": "00:00:00", "DefaultMarketPrice": "12.30", "ValidOrderTypes": "1,2,F", "ConnectionType": "acceptor", "EndTime": "00:00:00", "BeginString": "FIX.4.1", "SocketAcceptPort": "9877", "TargetCompID": "BANZAI", "SenderCompID": "EXEC", "HeartBtInt": "30", "BeginString": "FIX.4.1", "TargetCompID": "BANZAI", "FileStorePath": "target/data/executor", "UseDataDictionary": "Y" } }
=== QuickFIX/J Spring Boot Starter - Client (Initiator)
The @EnableQuickFixJClient will auto configure a QuickFIX/J Client:
[source,java]
@EnableQuickFixJClient @SpringBootApplication public class AppClient {
public static void main(String[] args) {
    SpringApplication.run(AppClient.class, args);
}
}
Additionally you need to add a https://www.quickfixj.org/usermanual/2.1.0/usage/configuration.html[quickfixj-client.cfg] file to configure the FIX sessions. The configuration is resolved using the following approach:
- By a QuickFIX/J initiator configuration string defined by the quickfixj.client.configStringproperty
- By the presence of a quickfix.SessionSettingsbean namedclientSessionSettings
- By a configuration file defined by the quickfixj.client.configproperty
- By the presence of the quickfixj.client.configsystem property
- By a quickfixj-client.cfgin the working directory or at the root of the classpath
==== QuickFIX/J Client properties
[source,properties]
quickfixj.client.config=classpath:quickfixj-client.cfg              # location of the quickfixj initiator
quickfixj.client.configString=[default]  \r\n...                   # the content of the QuickFIX/J initiator configuration file
quickfixj.client.auto-startup=true                                  # whether to auto-connect to the remote endpoint at start up (default: true)
quickfixj.client.phase=0                                            # phase in which this connection manager should be started and stopped (default: Integer.MAX_VALUE)
quickfixj.client.jmx-enabled=true                                   # whether to register the jmx mbeans for the initiator (default: false)
quickfixj.client.message-store-factory=memory                       # [cachedfile,file,jdbc,memory,noop,sleepycat] (default: memory)
quickfixj.client.log-factory=screen                                 # [compositelog,file,jdbc,slf4j,screen] (default: screen)
quickfixj.client.concurrent.enabled=true                            # whether to use a simple SocketInitiator or a ThreadedSocketInitiator (default: false - uses SocketInitiator)
quickfixj.client.concurrent.useDefaultExecutorFactory=true          # whether to use a default ExecutorFactory to create the SocketInitiator (default: false)
quickfixj.client.concurrent.queueCapacity=Integer.MAX_VALUE         # when using the default ExecutorFactory, the Executor's queue capacity (default: Integer.MAX_VALUE)
quickfixj.client.concurrent.corePoolSize=8                          # when using the default ExecutorFactory, the Executor's core pool size (default: 8)
quickfixj.client.concurrent.maxPoolSize=Integer.MAX_VALUE           # when using the default ExecutorFactory, the Executor's max pool size (default: Integer.MAX_VALUE)
quickfixj.client.concurrent.allowCoreThreadTimeOut=true             # when using the default ExecutorFactory, whether to allow core thread timeout on the Executor (default: true)
quickfixj.client.concurrent.keepAliveSeconds=60                     # when using the default ExecutorFactory, the Executor's keep alive in seconds (default: 60)
quickfixj.client.concurrent.waitForTasksToCompleteOnShutdown=false  # when using the default ExecutorFactory, whether to wait for tasks to complete on shutdown on the Executor (default: false)
quickfixj.client.concurrent.awaitTerminationSeconds=0                # when using the default ExecutorFactory, the Executor's await termination in seconds (default: 0)
quickfixj.client.concurrent.threadNamePrefix="QuickFixJ Spring Boot Starter thread-" # when using the default ExecutorFactory, the Executor's thread name prefix (default: QuickFixJ Spring Boot Starter thread-)
[source,yml]
quickfixj: client: config: classpath:quickfixj-client.cfg auto-startup: true force-disconnect: false phase: 0 jmx-enabled: true concurrent: enabled: true useDefaultExecutorFactory: true queueCapacity: Integer.MAX_VALUE corePoolSize: 8 maxPoolSize: Integer.MAX_VALUE allowCoreThreadTimeOut: true keepAliveSeconds: 60 waitForTasksToCompleteOnShutdown: false awaitTerminationMillis: 0 threadNamePrefix: "QuickFixJ Spring Boot Starter thread-" message-store-factory: memory log-factory: screen
==== QuickFIX/J initiator configuration file in properties and yaml files
Using the quickfixj.client.configString property:
[source,properties]
quickfixj.client.configString=[default] \r\n
FileStorePath=target/data/banzai \r\n
ConnectionType=initiator \r\n
SenderCompID=BANZAI \r\n
TargetCompID=EXEC \r\n
SocketConnectHost=localhost \r\n
StartTime=00:00:00 \r\n
EndTime=00:00:00 \r\n
HeartBtInt=30 \r\n
ReconnectInterval=5 \r\n
FileLogPath=logs-client \r\n
\r\n
[session] \r\n
BeginString=FIX.4.0 \r\n
SocketConnectPort=9876 \r\n
\r\n
[session] \r\n
BeginString=FIX.4.1 \r\n
SocketConnectPort=9877 \r\n
\r\n
[session] \r\n
BeginString=FIX.4.2 \r\n
SocketConnectPort=9878 \r\n
\r\n
[session] \r\n
BeginString=FIX.4.3 \r\n
SocketConnectPort=9879 \r\n
\r\n
[session] \r\n
BeginString=FIX.4.4 \r\n
SocketConnectPort=9880 \r\n
\r\n
[session] \r\n
BeginString=FIXT.1.1 \r\n
DefaultApplVerID=FIX.5.0SP2 \r\n
SocketConnectPort=9881
[source,yml]
quickfixj: client: configString: | [default] FileStorePath=target/data/banzai ConnectionType=initiator SenderCompID=BANZAI TargetCompID=EXEC SocketConnectHost=localhost StartTime=00:00:00 EndTime=00:00:00 HeartBtInt=30 ReconnectInterval=5 FileLogPath=logs-client
  [session]
  BeginString=FIX.4.0
  SocketConnectPort=9876
  [session]
  BeginString=FIX.4.1
  SocketConnectPort=9877
  [session]
  BeginString=FIX.4.2
  SocketConnectPort=9878
  [session]
  BeginString=FIX.4.3
  SocketConnectPort=9879
  [session]
  BeginString=FIX.4.4
  SocketConnectPort=9880
  [session]
  BeginString=FIXT.1.1
  DefaultApplVerID=FIX.5.0SP2
  SocketConnectPort=9881
==== QuickFIX/J Client Actuator properties
To enable the actuator endpoints you will also have to add the QuickFIX/J Spring Boot Actuator dependency.
[source,xml]
And enable the QuickFix/J Client endpoint in Spring:
[source,properties]
management.endpoint.quickfixjclient.enabled=true # whether the endpoint is enabled or not management.endpoints.web.exposure.include=quickfixjclient # whether the endpoint will be exposed
[source,yml]
management: endpoint: quickfixjclient: enabled: true endpoints: web: exposure: include: quickfixjclient
Example usage:
http://localhost:8081/actuator/quickfixjclient
[source,json]
{ "FIXT.1.1:BANZAI->EXEC": { "SenderCompID": "BANZAI", "StartTime": "00:00:00", "ConnectionType": "initiator", "EndTime": "00:00:00", "BeginString": "FIXT.1.1", "ReconnectInterval": "5", "TargetCompID": "EXEC", "DefaultApplVerID": "FIX.5.0", "SocketConnectHost": "localhost", "SenderCompID": "BANZAI", "HeartBtInt": "30", "BeginString": "FIXT.1.1", "TargetCompID": "EXEC", "FileStorePath": "target/data/banzai", "SocketConnectPort": "9881" }, "FIX.4.2:BANZAI->EXEC": { "SenderCompID": "BANZAI", "StartTime": "00:00:00", "ConnectionType": "initiator", "EndTime": "00:00:00", "BeginString": "FIX.4.2", "ReconnectInterval": "5", "TargetCompID": "EXEC", "SocketConnectHost": "localhost", "SenderCompID": "BANZAI", "HeartBtInt": "30", "BeginString": "FIX.4.2", "TargetCompID": "EXEC", "FileStorePath": "target/data/banzai", "SocketConnectPort": "9878" } }
=== Listening on quickfixj.Application messages
The QuickFIX/J Spring Boot Starter provides a default implementation for the quickfixj.Application interface which publishes the messages received by the Server (Acceptor) and the Client (Initiator) as ApplicationEvents.
If your application is only processing a subset of message types (i.e. toAdmin, toApp, onCreate, etc.) you will need to register an EventListener for these, with the appropriate message type as the only parameter for the listener method:
[source,java]
@EventListener public void listenFromAdmin(FromAdmin fromAdmin) { ... }
@EventListener public void listenFromApp(FromApp fromApp) { ... }
@EventListener public void listenOnCreate(Create create) { ... }
@EventListener public void listenOnLogon(Logon logon) { ... }
@EventListener public void listenOnLogout(Logout logout) { ... }
@EventListener public void listenToAdmin(ToAdmin toAdmin) { ... }
@EventListener public void listenToApp(ToApp toApp) { ... }
In case the EventListener method throws an exception, this exception will be propagated up the quickfix.Session#next() method.
Depending on the value of RejectMessageOnUnhandledException in the quickfixj configuration file, the message will be redelivered or dismissed.
=== QuickFixJTemplate
The QuickFixJTemplate provides a synchronous client to perform requests, exposing a simple, template method API over the QuickFIX/J client.
The QuickFIX/J Spring Boot Starter provides a quickFixJTemplate bean than can be Autowired in the application.
[source,java]
@Autowire private QuickFixJTemplate quickFixJTemplate;
...
SessionID sessionID = serverAcceptor.getSessions().stream() .filter(sessId -> sessId.getBeginString().equals(fixVersion) && sessId.getTargetCompID().equals(targetId)) .findFirst() .orElseThrow(RuntimeException::new);
OrderCancelRequest message = new OrderCancelRequest( new OrigClOrdID("123"), new ClOrdID("321"), new Symbol("LNUX"), new Side(Side.BUY));
quickFixJTemplate.send(message, sessionID);
== Examples Projects https://github.com/esanchezros/quickfixj-spring-boot-starter-examples[quickfixj-spring-boot-starter-examples]
- https://github.com/esanchezros/quickfixj-spring-boot-starter-examples/tree/master/docker-server-client[QuickFIX/J Spring Boot Server and Client applications as Docker containers]
- https://github.com/esanchezros/quickfixj-spring-boot-starter-examples/tree/master/docker-server-client-with-failover[QuickFIX/J Spring Boot Server and Client applications as Docker containers with server failover]
- https://github.com/esanchezros/quickfixj-spring-boot-starter-examples/tree/master/docker-server-client-with-database[QuickFIX/J Spring Boot Server and Client applications as Docker containers with database message store]
- https://github.com/esanchezros/quickfixj-spring-boot-starter-examples/tree/master/simple-client-and-server[QuickFIX/J Spring Boot Server and Client application]
- https://github.com/esanchezros/quickfixj-spring-boot-starter-examples/tree/master/simple-client-listener[QuickFIX/J Spring Boot Client application with Event Listeners]
- https://github.com/esanchezros/quickfixj-spring-boot-starter-examples/tree/master/simple-client-with-database[QuickFIX/J Spring Boot Client application with database message store]
- https://github.com/esanchezros/quickfixj-spring-boot-starter-examples/tree/master/simple-client[QuickFIX/J Spring Boot Client application]
- https://github.com/esanchezros/quickfixj-spring-boot-starter-examples/tree/master/simple-server-dynamic-sessions[QuickFIX/J Spring Boot Server application with Dynamic Sessions]
- https://github.com/esanchezros/quickfixj-spring-boot-starter-examples/tree/master/simple-server-listener[QuickFIX/J Spring Boot Server application with Event Listeners]
- https://github.com/esanchezros/quickfixj-spring-boot-starter-examples/tree/master/simple-server-with-database[QuickFIX/J Spring Boot Server application with database message store]
- https://github.com/esanchezros/quickfixj-spring-boot-starter-examples/tree/master/simple-server[QuickFIX/J Spring Boot Server application]
=== License and Acknowledgement
The QuickFIX/J Spring Boot Starter is released under version 2.0 of the http://www.apache.org/licenses/LICENSE-2.0[Apache License].
This code includes software developed by http://www.quickfixengine.org/[quickfixengine.org].