Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,9 @@
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate;
import org.springframework.boot.autoconfigure.condition.ResourceCondition;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;

import io.allune.quickfixj.spring.boot.starter.application.EventPublisherApplicationAdapter;
Expand Down Expand Up @@ -58,7 +56,6 @@
@Configuration
@EnableConfigurationProperties(QuickFixJBootProperties.class)
@ConditionalOnBean(QuickFixJClientMarkerConfiguration.Marker.class)
@Conditional(QuickFixJClientAutoConfiguration.ClientConfigAvailableCondition.class)
public class QuickFixJClientAutoConfiguration {

private static final String SYSTEM_VARIABLE_QUICKFIXJ_CLIENT_CONFIG = "quickfixj.client.config";
Expand All @@ -75,25 +72,25 @@ public SessionSettings clientSessionSettings(QuickFixJBootProperties properties)
}

@Bean
@ConditionalOnMissingBean(name = "clientApplication")
@ConditionalOnMissingBean(name = "clientApplication", value = Application.class)
public Application clientApplication(ApplicationEventPublisher applicationEventPublisher) {
return new EventPublisherApplicationAdapter(applicationEventPublisher);
}

@Bean
@ConditionalOnMissingBean(name = "clientMessageStoreFactory")
@ConditionalOnMissingBean(name = "clientMessageStoreFactory", value = MessageStoreFactory.class)
public MessageStoreFactory clientMessageStoreFactory() {
return new MemoryStoreFactory();
}

@Bean
@ConditionalOnMissingBean(name = "clientLogFactory")
@ConditionalOnMissingBean(name = "clientLogFactory", value = LogFactory.class)
public LogFactory clientLogFactory(SessionSettings clientSessionSettings) {
return new ScreenLogFactory(clientSessionSettings);
}

@Bean
@ConditionalOnMissingBean(name = "clientMessageFactory")
@ConditionalOnMissingBean(name = "clientMessageFactory", value = MessageFactory.class)
public MessageFactory clientMessageFactory() {
return new DefaultMessageFactory();
}
Expand Down Expand Up @@ -150,7 +147,7 @@ public ConnectorManager clientConnectionManager(Initiator clientInitiator, Quick
@ConditionalOnProperty(prefix = "quickfixj.client", name = "jmx-enabled", havingValue = "true")
@ConditionalOnClass(JmxExporter.class)
@ConditionalOnSingleCandidate(Initiator.class)
@ConditionalOnMissingBean(name = "clientInitiatorMBean")
@ConditionalOnMissingBean(name = "clientInitiatorMBean", value = ObjectName.class)
public ObjectName clientInitiatorMBean(Initiator clientInitiator) {
try {
JmxExporter exporter = new JmxExporter();
Expand All @@ -161,20 +158,8 @@ public ObjectName clientInitiatorMBean(Initiator clientInitiator) {
}

@Bean
@ConditionalOnMissingBean(name = "clientQuickFixJTemplate")
@ConditionalOnMissingBean(name = "clientQuickFixJTemplate", value = QuickFixJTemplate.class)
public QuickFixJTemplate clientQuickFixJTemplate() {
return new QuickFixJTemplate();
}

/**
* {@link ClientConfigAvailableCondition} that checks if the client configuration file is defined in
* {@code quickfixj.client.config} configuration key or in the default locations.
*/
static class ClientConfigAvailableCondition extends ResourceCondition {

ClientConfigAvailableCondition() {
super("QuickFixJ Client", SYSTEM_VARIABLE_QUICKFIXJ_CLIENT_CONFIG,
"file:./" + QUICKFIXJ_CLIENT_CONFIG, "classpath:/" + QUICKFIXJ_CLIENT_CONFIG);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,9 @@
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate;
import org.springframework.boot.autoconfigure.condition.ResourceCondition;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;

import io.allune.quickfixj.spring.boot.starter.application.EventPublisherApplicationAdapter;
Expand Down Expand Up @@ -58,7 +56,6 @@
@Configuration
@EnableConfigurationProperties(QuickFixJBootProperties.class)
@ConditionalOnBean(value = QuickFixJServerMarkerConfiguration.Marker.class)
@Conditional(QuickFixJServerAutoConfiguration.ServerConfigAvailableCondition.class)
public class QuickFixJServerAutoConfiguration {

private static final String SYSTEM_VARIABLE_QUICKFIXJ_SERVER_CONFIG = "quickfixj.server.config";
Expand Down Expand Up @@ -163,16 +160,4 @@ public ObjectName serverAcceptorMBean(Acceptor serverAcceptor) {
public QuickFixJTemplate serverQuickFixJTemplate() {
return new QuickFixJTemplate();
}

/**
* {@link ServerConfigAvailableCondition} that checks if the
* {@code quickfixj.server.config} configuration key is defined.
*/
static class ServerConfigAvailableCondition extends ResourceCondition {

ServerConfigAvailableCondition() {
super("QuickFixJ Server", SYSTEM_VARIABLE_QUICKFIXJ_SERVER_CONFIG,
"file:./quickfixj-server.cfg", "classpath:/quickfixj-server.cfg");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,15 @@
import org.junit.Test;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;

import io.allune.quickfixj.spring.boot.starter.EnableQuickFixJClient;
import io.allune.quickfixj.spring.boot.starter.application.EventPublisherApplicationAdapter;
import io.allune.quickfixj.spring.boot.starter.autoconfigure.client.QuickFixJClientAutoConfiguration;
import io.allune.quickfixj.spring.boot.starter.connection.ConnectorManager;
import io.allune.quickfixj.spring.boot.starter.connection.SessionSettingsLocator;
import io.allune.quickfixj.spring.boot.starter.exception.ConfigurationException;
import io.allune.quickfixj.spring.boot.starter.template.QuickFixJTemplate;
import quickfix.Application;
Expand All @@ -52,7 +54,7 @@
public class QuickFixJClientAutoConfigurationTest {

@Test
public void testAutoConfiguredBeansSingleThreadedAcceptor() {
public void testAutoConfiguredBeansSingleThreadedInitiator() {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(SingleThreadedClientInitiatorConfiguration.class);
ConnectorManager clientConnectionManager = ctx.getBean("clientConnectionManager", ConnectorManager.class);
assertThat(clientConnectionManager.isRunning()).isFalse();
Expand All @@ -65,7 +67,7 @@ public void testAutoConfiguredBeansSingleThreadedAcceptor() {
}

@Test
public void testAutoConfiguredBeansMultiThreadedAcceptor() {
public void testAutoConfiguredBeansMultiThreadedInitiator() {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(MultiThreadedClientInitiatorConfiguration.class);
ConnectorManager clientConnectionManager = ctx.getBean("clientConnectionManager", ConnectorManager.class);
assertThat(clientConnectionManager.isRunning()).isFalse();
Expand Down Expand Up @@ -106,6 +108,13 @@ public void shouldThrowConfigurationExceptionCreatingClientInitiatorMBeanGivenNu
.isThrownBy(() -> autoConfiguration.clientInitiatorMBean(null));
}

@Test
public void testAutoConfiguredBeansSingleThreadedInitiatorWithCustomClientSettings() {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(SingleThreadedClientInitiatorConfigurationWithCustomClientSettings.class);
SessionSettings customClientSessionSettings = ctx.getBean("clientSessionSettings", SessionSettings.class);
assertThat(customClientSessionSettings.getDefaultProperties().getProperty("SenderCompID")).isEqualTo("CUSTOM-BANZAI");
}

private void hasAutoConfiguredBeans(AnnotationConfigApplicationContext ctx) {
Application clientApplication = ctx.getBean("clientApplication", Application.class);
assertThat(clientApplication).isInstanceOf(EventPublisherApplicationAdapter.class);
Expand Down Expand Up @@ -144,4 +153,16 @@ static class SingleThreadedClientInitiatorConfiguration {
static class MultiThreadedClientInitiatorConfiguration {

}

@Configuration
@EnableAutoConfiguration
@EnableQuickFixJClient
@PropertySource("classpath:single-threaded-application-no-config-defined.properties")
static class SingleThreadedClientInitiatorConfigurationWithCustomClientSettings {

@Bean(name = "clientSessionSettings")
public SessionSettings customClientSessionSettings() {
return SessionSettingsLocator.loadSettings("classpath:/quickfixj-client-extra.cfg");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,15 @@
import org.junit.Test;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;

import io.allune.quickfixj.spring.boot.starter.EnableQuickFixJServer;
import io.allune.quickfixj.spring.boot.starter.application.EventPublisherApplicationAdapter;
import io.allune.quickfixj.spring.boot.starter.autoconfigure.server.QuickFixJServerAutoConfiguration;
import io.allune.quickfixj.spring.boot.starter.connection.ConnectorManager;
import io.allune.quickfixj.spring.boot.starter.connection.SessionSettingsLocator;
import io.allune.quickfixj.spring.boot.starter.exception.ConfigurationException;
import io.allune.quickfixj.spring.boot.starter.template.QuickFixJTemplate;
import quickfix.Acceptor;
Expand Down Expand Up @@ -77,29 +79,6 @@ public void testAutoConfiguredBeansMultiThreadedAcceptor() {
hasAutoConfiguredBeans(ctx);
}

private void hasAutoConfiguredBeans(AnnotationConfigApplicationContext ctx) {
Application serverApplication = ctx.getBean("serverApplication", Application.class);
assertThat(serverApplication).isInstanceOf(EventPublisherApplicationAdapter.class);

MessageStoreFactory serverMessageStoreFactory = ctx.getBean("serverMessageStoreFactory", MessageStoreFactory.class);
assertThat(serverMessageStoreFactory).isInstanceOf(MemoryStoreFactory.class);

LogFactory serverLogFactory = ctx.getBean("serverLogFactory", LogFactory.class);
assertThat(serverLogFactory).isInstanceOf(ScreenLogFactory.class);

MessageFactory serverMessageFactory = ctx.getBean("serverMessageFactory", MessageFactory.class);
assertThat(serverMessageFactory).isInstanceOf(DefaultMessageFactory.class);

SessionSettings serverSessionSettings = ctx.getBean("serverSessionSettings", SessionSettings.class);
assertThat(serverSessionSettings).isNotNull();

ObjectName serverInitiatorMBean = ctx.getBean("serverAcceptorMBean", ObjectName.class);
assertThat(serverInitiatorMBean).isNotNull();

QuickFixJTemplate serverQuickFixJTemplate = ctx.getBean("serverQuickFixJTemplate", QuickFixJTemplate.class);
assertThat(serverQuickFixJTemplate).isNotNull();
}

@Test
public void shouldCreateServerThreadedAcceptor() throws ConfigError {
// Given
Expand Down Expand Up @@ -129,6 +108,36 @@ public void shouldThrowConfigurationExceptionCreatingServerAcceptorMBeanGivenNul
.isThrownBy(() -> autoConfiguration.serverAcceptorMBean(null));
}

@Test
public void testAutoConfiguredBeansSingleThreadedAcceptorWithCustomServerSettings() {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(SingleThreadedServerAcceptorConfigurationWithCustomClientSettings.class);
SessionSettings customClientSessionSettings = ctx.getBean("serverSessionSettings", SessionSettings.class);
assertThat(customClientSessionSettings.getDefaultProperties().getProperty("SenderCompID")).isEqualTo("CUSTOM-EXEC");
}

private void hasAutoConfiguredBeans(AnnotationConfigApplicationContext ctx) {
Application serverApplication = ctx.getBean("serverApplication", Application.class);
assertThat(serverApplication).isInstanceOf(EventPublisherApplicationAdapter.class);

MessageStoreFactory serverMessageStoreFactory = ctx.getBean("serverMessageStoreFactory", MessageStoreFactory.class);
assertThat(serverMessageStoreFactory).isInstanceOf(MemoryStoreFactory.class);

LogFactory serverLogFactory = ctx.getBean("serverLogFactory", LogFactory.class);
assertThat(serverLogFactory).isInstanceOf(ScreenLogFactory.class);

MessageFactory serverMessageFactory = ctx.getBean("serverMessageFactory", MessageFactory.class);
assertThat(serverMessageFactory).isInstanceOf(DefaultMessageFactory.class);

SessionSettings serverSessionSettings = ctx.getBean("serverSessionSettings", SessionSettings.class);
assertThat(serverSessionSettings).isNotNull();

ObjectName serverInitiatorMBean = ctx.getBean("serverAcceptorMBean", ObjectName.class);
assertThat(serverInitiatorMBean).isNotNull();

QuickFixJTemplate serverQuickFixJTemplate = ctx.getBean("serverQuickFixJTemplate", QuickFixJTemplate.class);
assertThat(serverQuickFixJTemplate).isNotNull();
}

@Configuration
@EnableAutoConfiguration
@EnableQuickFixJServer
Expand All @@ -144,4 +153,17 @@ static class SingleThreadedServerAcceptorConfiguration {
static class MultiThreadedServerAcceptorConfiguration {

}

@Configuration
@EnableAutoConfiguration
@EnableQuickFixJServer
@PropertySource("classpath:single-threaded-application-no-config-defined.properties")
static class SingleThreadedServerAcceptorConfigurationWithCustomClientSettings {

@Bean(name = "serverSessionSettings")
public SessionSettings serverSessionSettings() {
return SessionSettingsLocator.loadSettings("classpath:/quickfixj-server-extra.cfg");
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = QuickFixJServerClientITConfiguration.class)
public class QuickFixJServerClientIT {
public class QuickFixJServerClientIntegrationTest {

@Autowired
private QuickFixJTemplate serverQuickFixJTemplate;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
[default]
FileStorePath=target/data/some-other-path-client
ConnectionType=initiator
SenderCompID=CUSTOM-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.0
SocketConnectPort=9881
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
[default]
FileStorePath=target/data/some-other-path-server
ConnectionType=acceptor
StartTime=00:00:00
EndTime=00:00:00
HeartBtInt=30
ValidOrderTypes=1,2,F
SenderCompID=CUSTOM-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.0
SocketAcceptPort=9881
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
quickfixj.server.concurrent.enabled=false
quickfixj.server.autoStartup=false
quickfixj.server.jmx-enabled=true
quickfixj.client.concurrent.enabled=false
quickfixj.client.autoStartup=false
quickfixj.client.jmx-enabled=true