image:https://dl.circleci.com/status-badge/img/gh/esanchezros/quickfixj-spring-boot-starter/tree/main.svg?style=shield["CircleCI", link="https://dl.circleci.com/status-badge/redirect/gh/esanchezros/quickfixj-spring-boot-starter/tree/main"] image:https://codecov.io/gh/esanchezros/quickfixj-spring-boot-starter/branch/main/graph/badge.svg?token=DhK6IBGZMS["codecov",link="https://codecov.io/gh/esanchezros/quickfixj-spring-boot-starter"] image:https://img.shields.io/badge/maven%20central-v2.18.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://app.codacy.com/project/badge/Grade/1c6bf92b53324a45ba587e061dc6547d["Codacy code quality", link="https://www.codacy.com/gh/esanchezros/quickfixj-spring-boot-starter/dashboard?utm_source=github.com&utm_medium=referral&utm_content=esanchezros/quickfixj-spring-boot-starter&utm_campaign=Badge_Grade"] image:https://api.securityscorecards.dev/projects/github.com/esanchezros/quickfixj-spring-boot-starter/badge["OpenSSF Scorecard", link="https://securityscorecards.dev/viewer/?uri=github.com/esanchezros/quickfixj-spring-boot-starter"]
= Spring Boot Starter for QuickFIX/J (Spring Boot 2 and Spring Boot 3)
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.3.0/quickfix/Initiator.html[Initiator] or https://www.quickfixj.org/javadoc/2.3.0/quickfix/Acceptor.html[Acceptor], and handles the lifecycle of the https://www.quickfixj.org/javadoc/2.3.0/quickfix/Connector.html[Connector].
== Compatibility with version 3.2 onwards
If you use Spring Boot 3.2 or greater you will need to use version 2.17.0 or greater of the Spring Boot Starter for QuickFIX/J as it fixes an issue with https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-3.2-Release-Notes#parameter-name-discovery[Parameter Name Discovery]
== Getting started
To use the QuickFIX/J Server or QuickFIX/J Client you need to add the QuickFIX/J Spring Boot Starter dependency in your project.
The QuickFIX/J Spring Boot Starter no longer includes quickfixj-messages-all
dependency and now includes the standard published FIX specification versions from FIX 4.0 to FIX Latest built by the QuickFIX/J project as optional dependency. They are not specified as runtime dependencies any longer, which makes it easier to customise QuickFIX/J deployments.
If you do not need to customise a FIX integration then you can use the org.quickfixj
artefacts built by the QuickFIX/J project. Include them as dependencies of your application.
For more information about customising the QuickFIX/J Runtime refer to https://github.com/quickfix-j/quickfixj?tab=readme-ov-file#quickfixj-runtime
For example, import the quickfixj-spring-boot-dependencies
pom in your dependencyManagement
section:
and add the specific version(s) of the FIX messages you need in your project dependencies
:
== QuickFIX/J Spring Boot Starter - Server (Acceptor)
There are two options to configure a QuickFIX/J Server.
=== EnableQuickFixJServer annotation
Adding the @EnableQuickFixJServer
annotation in your project will configure an Acceptor with all the default QuickFix/J components:
MessageStoreFactory
of type MemoryStoreFactory
.LogFactory
of type ScreenLogFactory
.Acceptor
of type SocketAcceptor
.Application
of type EventPublisherApplicationAdapter
.All these QuickFix/J components can be configured via properties or by overriding the beans. If you choose to provide your own implementation for any of these components, you need to specify spring.main.allow-bean-definition-overriding=true
. This annotation will be deprecated in future releases.
For example:
@EnableQuickFixJServer @SpringBootApplication public class AppServer {
public static void main(String[] args) {
SpringApplication.run(AppServer.class, args);
}
@Bean
public Application serverApplication() {
return new ServerApplicationAdapter(); // Provide your own implementation here
}
@Bean
public Acceptor severAcceptor(
Application serverApplication,
MessageStoreFactory serverMessageStoreFactory,
SessionSettings serverSessionSettings,
LogFactory serverLogFactory,
MessageFactory serverMessageFactory
) throws ConfigError {
return new ThreadedSocketAcceptor(serverApplication, serverMessageStoreFactory, serverSessionSettings,
serverLogFactory, serverMessageFactory);
}
@Bean
public LogFactory serverLogFactory(SessionSettings serverSessionSettings) {
return new FileLogFactory(serverSessionSettings);
}
=== Enabling QuickFix/J Server through a property
Enabling the autoconfiguration of QuickFix/J Server can be done through a property. It autoconfigures an Acceptor with all the same default QuickFix/J components as @EnableQuickFixJServer
.
[cols="3*", options="header"] |=== |property |example |description
|quickfixj.server.enabled |true |Enables QuickFix/J Server autoconfiguration. |===
=== Configuring the QuickFix/J Server
Additionally, you need to follow the https://www.quickfixj.org/usermanual/2.3.0/usage/configuration.html[configuration guide] to configure the FIX sessions. The configuration is resolved using the following approach:
quickfixj.server.configString
propertyquickfix.SessionSettings
bean named serverSessionSettings
quickfixj.server.config
propertyquickfixj.server.config
system propertyquickfixj-server.cfg
in the working directory or at the root of the classpath=== QuickFIX/J Server properties
[cols="3*", options="header"] |=== |Property |Example |Description
|quickfixj.server.config |classpath:quickfixj-server.cfg |Location of the QuickFix/J configuration file.
|quickfixj.server.configString
|[default] \r\n... (see below for an example)
|The content of the QuickFIX/J configuration file. This property takes precedence over quickfixj.server.config
.
|quickfixj.server.auto-startup
|true
|Whether to autostart the connection manager 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
|Type of MessageStoreFactory
to create. Supported values: cachedfile
, file
, jdbc
, memory
, noop
, sleepycat
(default: memory
).
|quickfixj.server.log-factory
|screen
|Type of LogFactory
to create. Supported values: 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 Acceptor
(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-
).
|===
For example:
quickfixj.server.config=classpath:quickfixj-server.cfg quickfixj.server.configString=[default] \r\n... (see below for an example) quickfixj.server.auto-startup=true quickfixj.server.force-disconnect=false quickfixj.server.phase=0 quickfixj.server.jmx-enabled=true quickfixj.server.message-store-factory=memory quickfixj.server.log-factory=screen
=== QuickFIX/J configuration file in properties and yaml files
Using the quickfixj.server.configString
property:
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
To enable the actuator endpoints you will also have to add the QuickFIX/J Spring Boot Actuator dependency.
Enabling the autoconfiguration of QuickFix/J Server Actuator can be done through a property.
[cols="3*", options="header"] |=== |property |example |description
|quickfixj.server.actuator.enabled |true |Enables QuickFix/J Server Actuator autoconfiguration. |===
Please note that the quickfixj-spring-boot-actuator
dependency will be added automatically by quickfixj-spring-boot-starter
And enable the QuickFix/J Server endpoint in Spring:
Example usage:
http://localhost:8081/actuator/quickfixjserver
=== QuickFIX/J Server Health Endpoint
The QuickFIX/J Spring Boot Starter provides with a HealthIndicator
that checks if the sessions are logged on when they should be (i.e. within market hours) and shows the expected schedule for each session.
For example:
The HealthIndicator
can be enabled in Spring as follows:
== QuickFIX/J Spring Boot Starter - Client (Initiator)
There are two options to configure a QuickFIX/J Client.
=== EnableQuickFixJClient annotation
Adding the @EnableQuickFixJClient
annotation in your project will configure an Initiator with all the default QuickFix/J components:
MessageStoreFactory
of type MemoryStoreFactory
.LogFactory
of type ScreenLogFactory
.Initiator
of type SocketInitiator
.Application
of type EventPublisherApplicationAdapter
.All these QuickFix/J components can be configured via properties or by overriding the beans. If you choose to provide your own implementation for any of these components, you need to specify spring.main.allow-bean-definition-overriding=true
. This annotation will be deprecated in future releases.
For example:
@EnableQuickFixJClient @SpringBootApplication public class AppClient {
public static void main(String[] args) {
SpringApplication.run(AppClient.class, args);
}
@Bean
public Application clientApplication() {
return new ClientApplicationAdapter(); // Provide your own implementation here
}
@Bean
public Initiator clientInitiator(
Application clientApplication,
MessageStoreFactory clientMessageStoreFactory,
SessionSettings clientSessionSettings,
LogFactory clientLogFactory,
MessageFactory clientMessageFactory
) throws ConfigError {
return new ThreadedSocketInitiator(clientApplication, clientMessageStoreFactory, clientSessionSettings,
clientLogFactory, clientMessageFactory);
}
@Bean
public LogFactory clientLogFactory(SessionSettings clientSessionSettings) {
return new FileLogFactory(clientSessionSettings);
}
=== Enabling QuickFix/J Client through a property
Enabling the autoconfiguration of QuickFix/J Client can be done through a property. It autoconfigures an Initiator with all the same default QuickFix/J components as @EnableQuickFixJClient
.
[cols="3*", options="header"] |=== |property |example |description
|quickfixj.client.enabled |true |Enables QuickFix/J Client autoconfiguration. |===
=== Configuring the QuickFix/J Client
Additionally you need to follow the https://www.quickfixj.org/usermanual/2.3.0/usage/configuration.html[configuration guide] to configure the FIX sessions. The configuration is resolved using the following approach:
quickfixj.client.configString
propertyquickfix.SessionSettings
bean named clientSessionSettings
quickfixj.client.config
propertyquickfixj.client.config
system propertyquickfixj-client.cfg
in the working directory or at the root of the classpath=== QuickFIX/J Client properties
[cols="3*", options="header"] |=== |Property |Example |Description
|quickfixj.client.config |classpath:quickfixj-client.cfg |Location of the QuickFix/J configuration file.
|quickfixj.client.configString
|[default] \r\n... (see below for an example)
|The content of the QuickFIX/J configuration file. This property takes precedence over quickfixj.client.config
.
|quickfixj.client.auto-startup
|true
|Whether to autostart the connection manager 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
|Type of MessageStoreFactory
to create. Supported values: cachedfile
, file
, jdbc
, memory
, noop
, sleepycat
(default: memory
).
|quickfixj.client.log-factory
|screen
|Type of LogFactory
to create. Supported values: 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 Initiator
(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-
).
|===
For example:
quickfixj.client.config=classpath:quickfixj-client.cfg quickfixj.client.configString=[default] \r\n... (see below for an example) quickfixj.client.auto-startup=true quickfixj.client.phase=0 quickfixj.client.jmx-enabled=true quickfixj.client.message-store-factory=memory quickfixj.client.log-factory=screen
=== QuickFIX/J configuration file in properties and yaml files
Using the quickfixj.client.configString
property:
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
To enable the actuator endpoints you will also have to add the QuickFIX/J Spring Boot Actuator dependency.
Enabling the autoconfiguration of QuickFix/J Client Actuator can be done through a property.
[cols="3*", options="header"] |=== |property |example |description
|quickfixj.client.actuator.enabled |true |Enables QuickFix/J Client Actuator autoconfiguration. |===
Please note that the quickfixj-spring-boot-actuator
dependency will be added automatically by quickfixj-spring-boot-starter
And enable the QuickFix/J Client endpoint in Spring:
Example usage:
http://localhost:8081/actuator/quickfixjclient
=== QuickFIX/J Client Health Endpoint
The QuickFIX/J Spring Boot Starter provides with a HealthIndicator
that checks if the sessions are logged on when they should be (i.e. within market hours) and shows the expected schedule for each session.
For example:
The HealthIndicator
can be enabled in Spring as follows:
== Listening on quickfixj.Application messages
The QuickFIX/J Spring Boot Starter provides a default implementation for the quickfixj.Application
interface, the EventPublisherApplicationAdapter
, which publishes the messages received by the Server (Acceptor) and the Client (Initiator) as ApplicationEvent
s. The EventPublisherApplicationAdapter
is provided by default, it's not meant to be used on high throughput environments
.
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:
@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) { ... }
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.
@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]
== 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].