From 4bff6814de7a909c0342d45ef3b83d48477b56ec Mon Sep 17 00:00:00 2001 From: Roger Peyer Date: Fri, 1 May 2020 22:35:54 +0200 Subject: [PATCH 1/2] Removed ServerConfigAvailableCondition and ClientConfigAvailableCondition from auto configuration, since this condition is not met if one provides his own server or client SessionSettings Bean. --- .../QuickFixJClientAutoConfiguration.java | 247 +++++++++--------- .../QuickFixJServerAutoConfiguration.java | 12 - 2 files changed, 121 insertions(+), 138 deletions(-) diff --git a/quickfixj-spring-boot-starter/src/main/java/io/allune/quickfixj/spring/boot/starter/autoconfigure/client/QuickFixJClientAutoConfiguration.java b/quickfixj-spring-boot-starter/src/main/java/io/allune/quickfixj/spring/boot/starter/autoconfigure/client/QuickFixJClientAutoConfiguration.java index 0a3a99c..deecaac 100644 --- a/quickfixj-spring-boot-starter/src/main/java/io/allune/quickfixj/spring/boot/starter/autoconfigure/client/QuickFixJClientAutoConfiguration.java +++ b/quickfixj-spring-boot-starter/src/main/java/io/allune/quickfixj/spring/boot/starter/autoconfigure/client/QuickFixJClientAutoConfiguration.java @@ -16,6 +16,12 @@ package io.allune.quickfixj.spring.boot.starter.autoconfigure.client; +import io.allune.quickfixj.spring.boot.starter.application.EventPublisherApplicationAdapter; +import io.allune.quickfixj.spring.boot.starter.autoconfigure.QuickFixJBootProperties; +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 javax.management.ObjectName; import org.quickfixj.jmx.JmxExporter; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; @@ -24,19 +30,10 @@ 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; -import io.allune.quickfixj.spring.boot.starter.autoconfigure.QuickFixJBootProperties; -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; import quickfix.ConfigError; import quickfix.DefaultMessageFactory; @@ -58,123 +55,121 @@ @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"; - - private static final String QUICKFIXJ_CLIENT_CONFIG = "quickfixj-client.cfg"; - - @Bean - @ConditionalOnMissingBean(name = "clientSessionSettings") - public SessionSettings clientSessionSettings(QuickFixJBootProperties properties) { - return SessionSettingsLocator.loadSettings(properties.getClient().getConfig(), - System.getProperty(SYSTEM_VARIABLE_QUICKFIXJ_CLIENT_CONFIG), - "file:./" + QUICKFIXJ_CLIENT_CONFIG, - "classpath:/" + QUICKFIXJ_CLIENT_CONFIG); - } - - @Bean - @ConditionalOnMissingBean(name = "clientApplication") - public Application clientApplication(ApplicationEventPublisher applicationEventPublisher) { - return new EventPublisherApplicationAdapter(applicationEventPublisher); - } - - @Bean - @ConditionalOnMissingBean(name = "clientMessageStoreFactory") - public MessageStoreFactory clientMessageStoreFactory() { - return new MemoryStoreFactory(); - } - - @Bean - @ConditionalOnMissingBean(name = "clientLogFactory") - public LogFactory clientLogFactory(SessionSettings clientSessionSettings) { - return new ScreenLogFactory(clientSessionSettings); - } - - @Bean - @ConditionalOnMissingBean(name = "clientMessageFactory") - public MessageFactory clientMessageFactory() { - return new DefaultMessageFactory(); - } - - @Bean - @ConditionalOnMissingBean - @ConditionalOnProperty(prefix = "quickfixj.client.concurrent", name = "enabled", havingValue = "false", matchIfMissing = true) - public Initiator clientInitiator( - Application clientApplication, - MessageStoreFactory clientMessageStoreFactory, - SessionSettings clientSessionSettings, - LogFactory clientLogFactory, - MessageFactory clientMessageFactory) throws ConfigError { - - return SocketInitiator.newBuilder() - .withApplication(clientApplication) - .withMessageStoreFactory(clientMessageStoreFactory) - .withSettings(clientSessionSettings) - .withLogFactory(clientLogFactory) - .withMessageFactory(clientMessageFactory) - .build(); - } - - @Bean - @ConditionalOnMissingBean - @ConditionalOnProperty(prefix = "quickfixj.client.concurrent", name = "enabled", havingValue = "true") - public Initiator clientThreadedInitiator( - Application clientApplication, - MessageStoreFactory clientMessageStoreFactory, - SessionSettings clientSessionSettings, - LogFactory clientLogFactory, - MessageFactory clientMessageFactory) throws ConfigError { - - return ThreadedSocketInitiator.newBuilder() - .withApplication(clientApplication) - .withMessageStoreFactory(clientMessageStoreFactory) - .withSettings(clientSessionSettings) - .withLogFactory(clientLogFactory) - .withMessageFactory(clientMessageFactory) - .build(); - } - - @Bean - public ConnectorManager clientConnectionManager(Initiator clientInitiator, QuickFixJBootProperties properties) { - ConnectorManager connectorManager = new ConnectorManager(clientInitiator); - if (properties.getClient() != null) { - connectorManager.setAutoStartup(properties.getClient().isAutoStartup()); - connectorManager.setPhase(properties.getClient().getPhase()); - } - return connectorManager; - } - - @Bean - @ConditionalOnProperty(prefix = "quickfixj.client", name = "jmx-enabled", havingValue = "true") - @ConditionalOnClass(JmxExporter.class) - @ConditionalOnSingleCandidate(Initiator.class) - @ConditionalOnMissingBean(name = "clientInitiatorMBean") - public ObjectName clientInitiatorMBean(Initiator clientInitiator) { - try { - JmxExporter exporter = new JmxExporter(); - return exporter.register(clientInitiator); - } catch (Exception e) { - throw new ConfigurationException(e.getMessage(), e); - } - } - - @Bean - @ConditionalOnMissingBean(name = "clientQuickFixJTemplate") - 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); - } - } + private static final String SYSTEM_VARIABLE_QUICKFIXJ_CLIENT_CONFIG = "quickfixj.client.config"; + + private static final String QUICKFIXJ_CLIENT_CONFIG = "quickfixj-client.cfg"; + + @Bean + @ConditionalOnMissingBean(name = "clientSessionSettings") + public SessionSettings clientSessionSettings(QuickFixJBootProperties properties) { + return SessionSettingsLocator.loadSettings( + properties.getClient().getConfig(), + System.getProperty(SYSTEM_VARIABLE_QUICKFIXJ_CLIENT_CONFIG), + "file:./" + QUICKFIXJ_CLIENT_CONFIG, + "classpath:/" + QUICKFIXJ_CLIENT_CONFIG); + } + + @Bean + @ConditionalOnMissingBean(name = "clientApplication") + public Application clientApplication(ApplicationEventPublisher applicationEventPublisher) { + return new EventPublisherApplicationAdapter(applicationEventPublisher); + } + + @Bean + @ConditionalOnMissingBean(name = "clientMessageStoreFactory") + public MessageStoreFactory clientMessageStoreFactory() { + return new MemoryStoreFactory(); + } + + @Bean + @ConditionalOnMissingBean(name = "clientLogFactory") + public LogFactory clientLogFactory(SessionSettings clientSessionSettings) { + return new ScreenLogFactory(clientSessionSettings); + } + + @Bean + @ConditionalOnMissingBean(name = "clientMessageFactory") + public MessageFactory clientMessageFactory() { + return new DefaultMessageFactory(); + } + + @Bean + @ConditionalOnMissingBean + @ConditionalOnProperty( + prefix = "quickfixj.client.concurrent", + name = "enabled", + havingValue = "false", + matchIfMissing = true) + public Initiator clientInitiator( + Application clientApplication, + MessageStoreFactory clientMessageStoreFactory, + SessionSettings clientSessionSettings, + LogFactory clientLogFactory, + MessageFactory clientMessageFactory) + throws ConfigError { + + return SocketInitiator.newBuilder() + .withApplication(clientApplication) + .withMessageStoreFactory(clientMessageStoreFactory) + .withSettings(clientSessionSettings) + .withLogFactory(clientLogFactory) + .withMessageFactory(clientMessageFactory) + .build(); + } + + @Bean + @ConditionalOnMissingBean + @ConditionalOnProperty( + prefix = "quickfixj.client.concurrent", + name = "enabled", + havingValue = "true") + public Initiator clientThreadedInitiator( + Application clientApplication, + MessageStoreFactory clientMessageStoreFactory, + SessionSettings clientSessionSettings, + LogFactory clientLogFactory, + MessageFactory clientMessageFactory) + throws ConfigError { + + return ThreadedSocketInitiator.newBuilder() + .withApplication(clientApplication) + .withMessageStoreFactory(clientMessageStoreFactory) + .withSettings(clientSessionSettings) + .withLogFactory(clientLogFactory) + .withMessageFactory(clientMessageFactory) + .build(); + } + + @Bean + public ConnectorManager clientConnectionManager( + Initiator clientInitiator, QuickFixJBootProperties properties) { + ConnectorManager connectorManager = new ConnectorManager(clientInitiator); + if (properties.getClient() != null) { + connectorManager.setAutoStartup(properties.getClient().isAutoStartup()); + connectorManager.setPhase(properties.getClient().getPhase()); + } + return connectorManager; + } + + @Bean + @ConditionalOnProperty(prefix = "quickfixj.client", name = "jmx-enabled", havingValue = "true") + @ConditionalOnClass(JmxExporter.class) + @ConditionalOnSingleCandidate(Initiator.class) + @ConditionalOnMissingBean(name = "clientInitiatorMBean") + public ObjectName clientInitiatorMBean(Initiator clientInitiator) { + try { + JmxExporter exporter = new JmxExporter(); + return exporter.register(clientInitiator); + } catch (Exception e) { + throw new ConfigurationException(e.getMessage(), e); + } + } + + @Bean + @ConditionalOnMissingBean(name = "clientQuickFixJTemplate") + public QuickFixJTemplate clientQuickFixJTemplate() { + return new QuickFixJTemplate(); + } } diff --git a/quickfixj-spring-boot-starter/src/main/java/io/allune/quickfixj/spring/boot/starter/autoconfigure/server/QuickFixJServerAutoConfiguration.java b/quickfixj-spring-boot-starter/src/main/java/io/allune/quickfixj/spring/boot/starter/autoconfigure/server/QuickFixJServerAutoConfiguration.java index 1de8a25..d8ffbf4 100644 --- a/quickfixj-spring-boot-starter/src/main/java/io/allune/quickfixj/spring/boot/starter/autoconfigure/server/QuickFixJServerAutoConfiguration.java +++ b/quickfixj-spring-boot-starter/src/main/java/io/allune/quickfixj/spring/boot/starter/autoconfigure/server/QuickFixJServerAutoConfiguration.java @@ -58,7 +58,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"; @@ -164,15 +163,4 @@ 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"); - } - } } From d516d63056e7447633c286657c96eaeba443a4a3 Mon Sep 17 00:00:00 2001 From: Eduardo Sanchez-Ros Date: Sat, 2 May 2020 20:57:50 +0200 Subject: [PATCH 2/2] Added unit test for client and server with provided session settings. Reverted code style in QuickFixJClientAutoConfiguration --- .../QuickFixJClientAutoConfiguration.java | 232 +++++++++--------- .../QuickFixJServerAutoConfiguration.java | 3 - .../QuickFixJClientAutoConfigurationTest.java | 25 +- .../QuickFixJServerAutoConfigurationTest.java | 68 +++-- ...QuickFixJServerClientIntegrationTest.java} | 2 +- .../test/resources/quickfixj-client-extra.cfg | 36 +++ .../test/resources/quickfixj-server-extra.cfg | 37 +++ ...d-application-no-config-defined.properties | 6 + 8 files changed, 259 insertions(+), 150 deletions(-) rename quickfixj-spring-boot-starter/src/test/java/io/allune/quickfixj/spring/boot/starter/integration/{QuickFixJServerClientIT.java => QuickFixJServerClientIntegrationTest.java} (98%) create mode 100644 quickfixj-spring-boot-starter/src/test/resources/quickfixj-client-extra.cfg create mode 100644 quickfixj-spring-boot-starter/src/test/resources/quickfixj-server-extra.cfg create mode 100644 quickfixj-spring-boot-starter/src/test/resources/single-threaded-application-no-config-defined.properties diff --git a/quickfixj-spring-boot-starter/src/main/java/io/allune/quickfixj/spring/boot/starter/autoconfigure/client/QuickFixJClientAutoConfiguration.java b/quickfixj-spring-boot-starter/src/main/java/io/allune/quickfixj/spring/boot/starter/autoconfigure/client/QuickFixJClientAutoConfiguration.java index deecaac..990eb65 100644 --- a/quickfixj-spring-boot-starter/src/main/java/io/allune/quickfixj/spring/boot/starter/autoconfigure/client/QuickFixJClientAutoConfiguration.java +++ b/quickfixj-spring-boot-starter/src/main/java/io/allune/quickfixj/spring/boot/starter/autoconfigure/client/QuickFixJClientAutoConfiguration.java @@ -16,12 +16,6 @@ package io.allune.quickfixj.spring.boot.starter.autoconfigure.client; -import io.allune.quickfixj.spring.boot.starter.application.EventPublisherApplicationAdapter; -import io.allune.quickfixj.spring.boot.starter.autoconfigure.QuickFixJBootProperties; -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 javax.management.ObjectName; import org.quickfixj.jmx.JmxExporter; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; @@ -34,6 +28,13 @@ import org.springframework.context.ApplicationEventPublisher; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; + +import io.allune.quickfixj.spring.boot.starter.application.EventPublisherApplicationAdapter; +import io.allune.quickfixj.spring.boot.starter.autoconfigure.QuickFixJBootProperties; +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; import quickfix.ConfigError; import quickfix.DefaultMessageFactory; @@ -57,119 +58,108 @@ @ConditionalOnBean(QuickFixJClientMarkerConfiguration.Marker.class) public class QuickFixJClientAutoConfiguration { - private static final String SYSTEM_VARIABLE_QUICKFIXJ_CLIENT_CONFIG = "quickfixj.client.config"; - - private static final String QUICKFIXJ_CLIENT_CONFIG = "quickfixj-client.cfg"; - - @Bean - @ConditionalOnMissingBean(name = "clientSessionSettings") - public SessionSettings clientSessionSettings(QuickFixJBootProperties properties) { - return SessionSettingsLocator.loadSettings( - properties.getClient().getConfig(), - System.getProperty(SYSTEM_VARIABLE_QUICKFIXJ_CLIENT_CONFIG), - "file:./" + QUICKFIXJ_CLIENT_CONFIG, - "classpath:/" + QUICKFIXJ_CLIENT_CONFIG); - } - - @Bean - @ConditionalOnMissingBean(name = "clientApplication") - public Application clientApplication(ApplicationEventPublisher applicationEventPublisher) { - return new EventPublisherApplicationAdapter(applicationEventPublisher); - } - - @Bean - @ConditionalOnMissingBean(name = "clientMessageStoreFactory") - public MessageStoreFactory clientMessageStoreFactory() { - return new MemoryStoreFactory(); - } - - @Bean - @ConditionalOnMissingBean(name = "clientLogFactory") - public LogFactory clientLogFactory(SessionSettings clientSessionSettings) { - return new ScreenLogFactory(clientSessionSettings); - } - - @Bean - @ConditionalOnMissingBean(name = "clientMessageFactory") - public MessageFactory clientMessageFactory() { - return new DefaultMessageFactory(); - } - - @Bean - @ConditionalOnMissingBean - @ConditionalOnProperty( - prefix = "quickfixj.client.concurrent", - name = "enabled", - havingValue = "false", - matchIfMissing = true) - public Initiator clientInitiator( - Application clientApplication, - MessageStoreFactory clientMessageStoreFactory, - SessionSettings clientSessionSettings, - LogFactory clientLogFactory, - MessageFactory clientMessageFactory) - throws ConfigError { - - return SocketInitiator.newBuilder() - .withApplication(clientApplication) - .withMessageStoreFactory(clientMessageStoreFactory) - .withSettings(clientSessionSettings) - .withLogFactory(clientLogFactory) - .withMessageFactory(clientMessageFactory) - .build(); - } - - @Bean - @ConditionalOnMissingBean - @ConditionalOnProperty( - prefix = "quickfixj.client.concurrent", - name = "enabled", - havingValue = "true") - public Initiator clientThreadedInitiator( - Application clientApplication, - MessageStoreFactory clientMessageStoreFactory, - SessionSettings clientSessionSettings, - LogFactory clientLogFactory, - MessageFactory clientMessageFactory) - throws ConfigError { - - return ThreadedSocketInitiator.newBuilder() - .withApplication(clientApplication) - .withMessageStoreFactory(clientMessageStoreFactory) - .withSettings(clientSessionSettings) - .withLogFactory(clientLogFactory) - .withMessageFactory(clientMessageFactory) - .build(); - } - - @Bean - public ConnectorManager clientConnectionManager( - Initiator clientInitiator, QuickFixJBootProperties properties) { - ConnectorManager connectorManager = new ConnectorManager(clientInitiator); - if (properties.getClient() != null) { - connectorManager.setAutoStartup(properties.getClient().isAutoStartup()); - connectorManager.setPhase(properties.getClient().getPhase()); - } - return connectorManager; - } - - @Bean - @ConditionalOnProperty(prefix = "quickfixj.client", name = "jmx-enabled", havingValue = "true") - @ConditionalOnClass(JmxExporter.class) - @ConditionalOnSingleCandidate(Initiator.class) - @ConditionalOnMissingBean(name = "clientInitiatorMBean") - public ObjectName clientInitiatorMBean(Initiator clientInitiator) { - try { - JmxExporter exporter = new JmxExporter(); - return exporter.register(clientInitiator); - } catch (Exception e) { - throw new ConfigurationException(e.getMessage(), e); - } - } - - @Bean - @ConditionalOnMissingBean(name = "clientQuickFixJTemplate") - public QuickFixJTemplate clientQuickFixJTemplate() { - return new QuickFixJTemplate(); - } + private static final String SYSTEM_VARIABLE_QUICKFIXJ_CLIENT_CONFIG = "quickfixj.client.config"; + + private static final String QUICKFIXJ_CLIENT_CONFIG = "quickfixj-client.cfg"; + + @Bean + @ConditionalOnMissingBean(name = "clientSessionSettings") + public SessionSettings clientSessionSettings(QuickFixJBootProperties properties) { + return SessionSettingsLocator.loadSettings(properties.getClient().getConfig(), + System.getProperty(SYSTEM_VARIABLE_QUICKFIXJ_CLIENT_CONFIG), + "file:./" + QUICKFIXJ_CLIENT_CONFIG, + "classpath:/" + QUICKFIXJ_CLIENT_CONFIG); + } + + @Bean + @ConditionalOnMissingBean(name = "clientApplication", value = Application.class) + public Application clientApplication(ApplicationEventPublisher applicationEventPublisher) { + return new EventPublisherApplicationAdapter(applicationEventPublisher); + } + + @Bean + @ConditionalOnMissingBean(name = "clientMessageStoreFactory", value = MessageStoreFactory.class) + public MessageStoreFactory clientMessageStoreFactory() { + return new MemoryStoreFactory(); + } + + @Bean + @ConditionalOnMissingBean(name = "clientLogFactory", value = LogFactory.class) + public LogFactory clientLogFactory(SessionSettings clientSessionSettings) { + return new ScreenLogFactory(clientSessionSettings); + } + + @Bean + @ConditionalOnMissingBean(name = "clientMessageFactory", value = MessageFactory.class) + public MessageFactory clientMessageFactory() { + return new DefaultMessageFactory(); + } + + @Bean + @ConditionalOnMissingBean + @ConditionalOnProperty(prefix = "quickfixj.client.concurrent", name = "enabled", havingValue = "false", matchIfMissing = true) + public Initiator clientInitiator( + Application clientApplication, + MessageStoreFactory clientMessageStoreFactory, + SessionSettings clientSessionSettings, + LogFactory clientLogFactory, + MessageFactory clientMessageFactory) throws ConfigError { + + return SocketInitiator.newBuilder() + .withApplication(clientApplication) + .withMessageStoreFactory(clientMessageStoreFactory) + .withSettings(clientSessionSettings) + .withLogFactory(clientLogFactory) + .withMessageFactory(clientMessageFactory) + .build(); + } + + @Bean + @ConditionalOnMissingBean + @ConditionalOnProperty(prefix = "quickfixj.client.concurrent", name = "enabled", havingValue = "true") + public Initiator clientThreadedInitiator( + Application clientApplication, + MessageStoreFactory clientMessageStoreFactory, + SessionSettings clientSessionSettings, + LogFactory clientLogFactory, + MessageFactory clientMessageFactory) throws ConfigError { + + return ThreadedSocketInitiator.newBuilder() + .withApplication(clientApplication) + .withMessageStoreFactory(clientMessageStoreFactory) + .withSettings(clientSessionSettings) + .withLogFactory(clientLogFactory) + .withMessageFactory(clientMessageFactory) + .build(); + } + + @Bean + public ConnectorManager clientConnectionManager(Initiator clientInitiator, QuickFixJBootProperties properties) { + ConnectorManager connectorManager = new ConnectorManager(clientInitiator); + if (properties.getClient() != null) { + connectorManager.setAutoStartup(properties.getClient().isAutoStartup()); + connectorManager.setPhase(properties.getClient().getPhase()); + } + return connectorManager; + } + + @Bean + @ConditionalOnProperty(prefix = "quickfixj.client", name = "jmx-enabled", havingValue = "true") + @ConditionalOnClass(JmxExporter.class) + @ConditionalOnSingleCandidate(Initiator.class) + @ConditionalOnMissingBean(name = "clientInitiatorMBean", value = ObjectName.class) + public ObjectName clientInitiatorMBean(Initiator clientInitiator) { + try { + JmxExporter exporter = new JmxExporter(); + return exporter.register(clientInitiator); + } catch (Exception e) { + throw new ConfigurationException(e.getMessage(), e); + } + } + + @Bean + @ConditionalOnMissingBean(name = "clientQuickFixJTemplate", value = QuickFixJTemplate.class) + public QuickFixJTemplate clientQuickFixJTemplate() { + return new QuickFixJTemplate(); + } } diff --git a/quickfixj-spring-boot-starter/src/main/java/io/allune/quickfixj/spring/boot/starter/autoconfigure/server/QuickFixJServerAutoConfiguration.java b/quickfixj-spring-boot-starter/src/main/java/io/allune/quickfixj/spring/boot/starter/autoconfigure/server/QuickFixJServerAutoConfiguration.java index d8ffbf4..6c3fd68 100644 --- a/quickfixj-spring-boot-starter/src/main/java/io/allune/quickfixj/spring/boot/starter/autoconfigure/server/QuickFixJServerAutoConfiguration.java +++ b/quickfixj-spring-boot-starter/src/main/java/io/allune/quickfixj/spring/boot/starter/autoconfigure/server/QuickFixJServerAutoConfiguration.java @@ -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; @@ -162,5 +160,4 @@ public ObjectName serverAcceptorMBean(Acceptor serverAcceptor) { public QuickFixJTemplate serverQuickFixJTemplate() { return new QuickFixJTemplate(); } - } diff --git a/quickfixj-spring-boot-starter/src/test/java/io/allune/quickfixj/spring/boot/starter/autoconfigure/QuickFixJClientAutoConfigurationTest.java b/quickfixj-spring-boot-starter/src/test/java/io/allune/quickfixj/spring/boot/starter/autoconfigure/QuickFixJClientAutoConfigurationTest.java index d0c6641..50a41db 100644 --- a/quickfixj-spring-boot-starter/src/test/java/io/allune/quickfixj/spring/boot/starter/autoconfigure/QuickFixJClientAutoConfigurationTest.java +++ b/quickfixj-spring-boot-starter/src/test/java/io/allune/quickfixj/spring/boot/starter/autoconfigure/QuickFixJClientAutoConfigurationTest.java @@ -24,6 +24,7 @@ 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; @@ -31,6 +32,7 @@ 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; @@ -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(); @@ -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(); @@ -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); @@ -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"); + } + } } \ No newline at end of file diff --git a/quickfixj-spring-boot-starter/src/test/java/io/allune/quickfixj/spring/boot/starter/autoconfigure/QuickFixJServerAutoConfigurationTest.java b/quickfixj-spring-boot-starter/src/test/java/io/allune/quickfixj/spring/boot/starter/autoconfigure/QuickFixJServerAutoConfigurationTest.java index 274f066..5fc3da1 100644 --- a/quickfixj-spring-boot-starter/src/test/java/io/allune/quickfixj/spring/boot/starter/autoconfigure/QuickFixJServerAutoConfigurationTest.java +++ b/quickfixj-spring-boot-starter/src/test/java/io/allune/quickfixj/spring/boot/starter/autoconfigure/QuickFixJServerAutoConfigurationTest.java @@ -24,6 +24,7 @@ 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; @@ -31,6 +32,7 @@ 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; @@ -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 @@ -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 @@ -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"); + } + } + } \ No newline at end of file diff --git a/quickfixj-spring-boot-starter/src/test/java/io/allune/quickfixj/spring/boot/starter/integration/QuickFixJServerClientIT.java b/quickfixj-spring-boot-starter/src/test/java/io/allune/quickfixj/spring/boot/starter/integration/QuickFixJServerClientIntegrationTest.java similarity index 98% rename from quickfixj-spring-boot-starter/src/test/java/io/allune/quickfixj/spring/boot/starter/integration/QuickFixJServerClientIT.java rename to quickfixj-spring-boot-starter/src/test/java/io/allune/quickfixj/spring/boot/starter/integration/QuickFixJServerClientIntegrationTest.java index 226f75a..dde29fd 100644 --- a/quickfixj-spring-boot-starter/src/test/java/io/allune/quickfixj/spring/boot/starter/integration/QuickFixJServerClientIT.java +++ b/quickfixj-spring-boot-starter/src/test/java/io/allune/quickfixj/spring/boot/starter/integration/QuickFixJServerClientIntegrationTest.java @@ -31,7 +31,7 @@ */ @RunWith(SpringJUnit4ClassRunner.class) @SpringBootTest(classes = QuickFixJServerClientITConfiguration.class) -public class QuickFixJServerClientIT { +public class QuickFixJServerClientIntegrationTest { @Autowired private QuickFixJTemplate serverQuickFixJTemplate; diff --git a/quickfixj-spring-boot-starter/src/test/resources/quickfixj-client-extra.cfg b/quickfixj-spring-boot-starter/src/test/resources/quickfixj-client-extra.cfg new file mode 100644 index 0000000..5cace2c --- /dev/null +++ b/quickfixj-spring-boot-starter/src/test/resources/quickfixj-client-extra.cfg @@ -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 diff --git a/quickfixj-spring-boot-starter/src/test/resources/quickfixj-server-extra.cfg b/quickfixj-spring-boot-starter/src/test/resources/quickfixj-server-extra.cfg new file mode 100644 index 0000000..393fbf4 --- /dev/null +++ b/quickfixj-spring-boot-starter/src/test/resources/quickfixj-server-extra.cfg @@ -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 \ No newline at end of file diff --git a/quickfixj-spring-boot-starter/src/test/resources/single-threaded-application-no-config-defined.properties b/quickfixj-spring-boot-starter/src/test/resources/single-threaded-application-no-config-defined.properties new file mode 100644 index 0000000..ab42181 --- /dev/null +++ b/quickfixj-spring-boot-starter/src/test/resources/single-threaded-application-no-config-defined.properties @@ -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 \ No newline at end of file