Skip to content

Commit

Permalink
Renamed licence template file (#137)
Browse files Browse the repository at this point in the history
* Renamed licence template file

* Version updates

* Increase test coverage

* Renamed tests
  • Loading branch information
esanchezros authored Oct 27, 2024
1 parent 65deb6c commit 836d253
Show file tree
Hide file tree
Showing 8 changed files with 229 additions and 70 deletions.
127 changes: 66 additions & 61 deletions README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -15,67 +15,6 @@ It simplifies the configuration required to create and start an https://www.quic

In this Spring Boot Starter, QuickFIX/J Server is equivalent to `Acceptor` and QuickFIX/J Client to `Initiator`.

== Breaking changes with previous versions

Due to the changes in https://github.com/spring-projects/spring-framework/wiki/Upgrading-to-Spring-Framework-6.x#core-container[how dependencies are autowired from Spring Framework 6.1] and https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-3.2-Release-Notes#parameter-name-discovery[Parameter Name Discovery], having the quickfixj client and server in the same spring context is not supported.

If you have an application that need to use both, or multiple of one, you can use the following approach to separate the Spring contexts and configurations:

[source,java]
----
@SpringBootConfiguration
public class ApplicationConfiguration {
public static void main(String[] args) {
SpringApplicationBuilder parent =
new SpringApplicationBuilder(QuickFixJCommonConfiguration.class);
parent.child(QuickFixJServerYourCompanyContextConfiguration.class).web(WebApplicationType.SERVLET);
parent.child(QuickFixJClientNDAQContextConfiguration.class).web(WebApplicationType.SERVLET);
parent.child(QuickFixJClientFOREXContextConfiguration.class).web(WebApplicationType.SERVLET);
parent.child(QuickFixJClientDOWJONESContextConfiguration.class).web(WebApplicationType.SERVLET);
parent.run(args);
}
@Configuration
public class QuickFixJCommonConfiguration {
@Bean
public QuickFixJTemplate quickFixJTemplate() {
return new QuickFixJTemplate();
}
}
@EnableAutoConfiguration
@Configuration(proxyBeanMethods = false)
@PropertySource("classpath:server/server.properties")
public class QuickFixJServerYourCompanyContextConfiguration {
// override beans if required
}
@EnableAutoConfiguration
@Configuration(proxyBeanMethods = false)
@PropertySource("classpath:client/ndaq.properties")
public class QuickFixJClientNDAQContextConfiguration {
// override beans if required
}
@EnableAutoConfiguration
@Configuration(proxyBeanMethods = false)
@PropertySource("classpath:client/forex.properties")
public class QuickFixJClientFOREXContextConfiguration {
// override beans if required
}
@EnableAutoConfiguration
@Configuration(proxyBeanMethods = false)
@PropertySource("classpath:client/dow-jones.properties")
public class QuickFixJClientDOWJONESContextConfiguration {
// override beans if required
}
}
----

== 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.
Expand Down Expand Up @@ -128,6 +67,72 @@ and add the specific version(s) of the FIX messages you need in your project `de
</dependency>
----

== Breaking changes with previous versions

Due to the changes in https://github.com/spring-projects/spring-framework/wiki/Upgrading-to-Spring-Framework-6.x#core-container[how dependencies are autowired from Spring Framework 6.1] and https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-3.2-Release-Notes#parameter-name-discovery[Parameter Name Discovery], having the quickfixj client and server in the same spring context is not supported.

If you have an application that need to use both, or multiple of one, you can use the following approach to separate the Spring contexts and configurations:

[source,java]
----
public class ApplicationConfiguration {
public static void main(String[] args) {
SpringApplicationBuilder parentBuilder
= new SpringApplicationBuilder(QuickFixJCommonConfiguration.class)
.web(WebApplicationType.NONE);
parentBuilder.run(args);
parentBuilder.child(QuickFixJServerYourCompanyContextConfiguration.class)
.properties("spring.config.name=server")
.web(WebApplicationType.SERVLET).run(args);
parentBuilder.child(QuickFixJClientNDAQContextConfiguration.class)
.properties("spring.config.name=ndaq")
.web(WebApplicationType.SERVLET).run(args);
parentBuilder.child(QuickFixJClientFOREXContextConfiguration.class)
.properties("spring.config.name=forex")
.web(WebApplicationType.SERVLET).run(args);
parentBuilder.child(QuickFixJClientDOWJONESContextConfiguration.class)
.properties("spring.config.name=dow-jones")
.web(WebApplicationType.SERVLET).run(args);
}
@Configuration
public class QuickFixJCommonConfiguration {
@Bean
public QuickFixJTemplate quickFixJTemplate() {
return new QuickFixJTemplate();
}
}
@EnableAutoConfiguration
@Configuration
public class QuickFixJServerYourCompanyContextConfiguration {
// override beans if required
}
@EnableAutoConfiguration
@Configuration
public class QuickFixJClientNDAQContextConfiguration {
// override beans if required
}
@EnableAutoConfiguration
@Configuration
public class QuickFixJClientFOREXContextConfiguration {
// override beans if required
}
@EnableAutoConfiguration
@Configuration
public class QuickFixJClientDOWJONESContextConfiguration {
// override beans if required
}
}
----

== QuickFIX/J Spring Boot Starter - Server (Acceptor)

=== Enabling QuickFix/J Server
Expand Down
File renamed without changes.
10 changes: 6 additions & 4 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<quickfixj.version>2.3.1</quickfixj.version>
<awaitility.version>4.2.2</awaitility.version>
<spring-boot-dependencies.version>3.3.5</spring-boot-dependencies.version>
<snakeyaml.version>2.3</snakeyaml.version>

<!-- Plugins -->
<maven-surefire-plugin.version>3.5.0</maven-surefire-plugin.version>
Expand Down Expand Up @@ -159,7 +161,7 @@
<!-- Import dependency management from Spring Boot -->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>3.3.5</version>
<version>${spring-boot-dependencies.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
Expand All @@ -168,7 +170,7 @@
<dependency>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
<version>2.1</version>
<version>${snakeyaml.version}</version>
</dependency>

<!-- Test -->
Expand Down Expand Up @@ -220,7 +222,7 @@
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.8</version>
<version>0.8.12</version>
<executions>
<execution>
<id>prepare-agent</id>
Expand All @@ -247,7 +249,7 @@
<version>4.6</version>
<configuration>
<!-- Template location -->
<header>licence-header.txt</header>
<header>licence-header.template</header>
<properties>
<!-- Values to be substituted in template -->
<inceptionYear>2017</inceptionYear>
Expand Down
5 changes: 0 additions & 5 deletions quickfixj-spring-boot-context/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,6 @@
<artifactId>spring-boot-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.awaitility</groupId>
<artifactId>awaitility</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import java.util.Optional;

import static java.util.Optional.empty;
import static org.apache.commons.lang3.StringUtils.isBlank;

/**
* {@link SessionSettings} helper class that attempts to load the settings files from the default locations
Expand Down Expand Up @@ -66,6 +67,9 @@ public SessionSettings loadSettings(String... locations) {
}

public SessionSettings loadSettingsFromString(String configString) {
if (isBlank(configString)) {
throw new SettingsNotFoundException("configString is blank or empty");
}
try {
return new SessionSettings(new ByteArrayInputStream(configString.getBytes()));
} catch (RuntimeException | ConfigError e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.BDDMockito.willThrow;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
Expand Down Expand Up @@ -116,4 +119,81 @@ public void shouldThrowConfigurationExceptionUponRuntimeErrorFailure() throws Ex

verify(connector).start();
}

@Test
void testIsAutoStartupDefaultTrue() {
Connector connector = mock(Connector.class);
ConnectorManager connectorManager = new ConnectorManager(connector);
// By default autoStartup should be true
assertTrue(connectorManager.isAutoStartup(), "The autoStartup should be true by default");
}

@Test
void testIsAutoStartupSetToFalse() {
Connector connector = mock(Connector.class);
ConnectorManager connectorManager = new ConnectorManager(connector);
// Set autoStartup to false
connectorManager.setAutoStartup(false);
assertFalse(connectorManager.isAutoStartup(), "The autoStartup should be false after setting it");
}

@Test
void testIsAutoStartupSetToTrue() {
Connector connector = mock(Connector.class);
ConnectorManager connectorManager = new ConnectorManager(connector);

// First set it to false
connectorManager.setAutoStartup(false);
assertFalse(connectorManager.isAutoStartup(), "The autoStartup should be false after setting it");

// Then set it back to true
connectorManager.setAutoStartup(true);
assertTrue(connectorManager.isAutoStartup(), "The autoStartup should be true after setting it back");
}

@Test
void testGetPhaseDefaultValue() {
Connector connector = mock(Connector.class);
ConnectorManager connectorManager = new ConnectorManager(connector);
// By default the phase should be Integer.MAX_VALUE
assertEquals(Integer.MAX_VALUE, connectorManager.getPhase(), "The default phase should be Integer.MAX_VALUE");
}

@Test
void testSetPhaseCustomValue() {
Connector connector = mock(Connector.class);
ConnectorManager connectorManager = new ConnectorManager(connector);
// Set phase to a specific value and check
int customPhase = 42;
connectorManager.setPhase(customPhase);
assertEquals(customPhase, connectorManager.getPhase(), "The phase should be the custom value set");
}

@Test
void testIsForceDisconnectDefaultValue() {
Connector connector = mock(Connector.class);
ConnectorManager connectorManager = new ConnectorManager(connector);
// By default, forceDisconnect should be false
assertFalse(connectorManager.isForceDisconnect(), "The default forceDisconnect should be false");
}

@Test
void testSetForceDisconnectToTrue() {
Connector connector = mock(Connector.class);
ConnectorManager connectorManager = new ConnectorManager(connector);
// Set forceDisconnect to true and check
connectorManager.setForceDisconnect(true);
assertTrue(connectorManager.isForceDisconnect(), "The forceDisconnect should be true after setting it");
}

@Test
void testSetForceDisconnectToFalse() {
Connector connector = mock(Connector.class);
ConnectorManager connectorManager = new ConnectorManager(connector);
// Initially set forceDisconnect to true
connectorManager.setForceDisconnect(true);
// Set forceDisconnect to false and check
connectorManager.setForceDisconnect(false);
assertFalse(connectorManager.isForceDisconnect(), "The forceDisconnect should be false after setting it back");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,18 @@
import io.allune.quickfixj.spring.boot.starter.exception.SettingsNotFoundException;
import org.junit.jupiter.api.Test;
import org.springframework.core.io.DefaultResourceLoader;
import quickfix.ConfigError;
import quickfix.FieldConvertError;
import quickfix.SessionID;
import quickfix.SessionSettings;

import java.io.File;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;

/**
* @author Eduardo Sanchez-Ros
Expand All @@ -50,4 +56,48 @@ public void shouldThrowSettingsNotFoundExceptionIfNoneFound() {
assertThatThrownBy(() -> sessionSettingsLocator.loadSettings(null, null, null, null))
.isInstanceOf(SettingsNotFoundException.class);
}

@Test
void testLoadSettingsFromStringValidConfig() throws ConfigError, FieldConvertError {
String configString = "[DEFAULT]\n" +
"ConnectionType=initiator\n" +
"BeginString=FIX.4.2\n" +
"SenderCompID=CLIENT1\n" +
"TargetCompID=SERVER\n" +
"\n" +
"[SESSION]\n" +
"SocketConnectPort=5001\n" +
"SocketConnectHost=localhost\n";

SessionSettingsLocator sessionSettingsLocator = new SessionSettingsLocator(new DefaultResourceLoader());
SessionSettings settings = sessionSettingsLocator.loadSettingsFromString(configString);

assertThat("initiator").isEqualTo(settings.getString("ConnectionType"));
assertThat("FIX.4.2").isEqualTo(settings.getString("BeginString"));
assertThat("CLIENT1").isEqualTo(settings.getString("SenderCompID"));
assertThat("SERVER").isEqualTo(settings.getString("TargetCompID"));

SessionID sessionID = new SessionID("FIX.4.2", "CLIENT1", "SERVER");
assertThat(5001).isEqualTo(settings.getLong(sessionID, "SocketConnectPort"));
assertThat("localhost").isEqualTo(settings.getString(sessionID, "SocketConnectHost"));
}

@Test
void testLoadSettingsFromStringEmptyConfig() {
String configString = "";
SessionSettingsLocator sessionSettingsLocator = new SessionSettingsLocator(new DefaultResourceLoader());
assertThatThrownBy(() -> sessionSettingsLocator.loadSettingsFromString(configString))
.isInstanceOf(SettingsNotFoundException.class);
}

@Test
void testLoadSettingsFromStringInvalidConfig() {
String configString = "[INVALID]\n" +
"ThisIsNotAValidSetting";

SessionSettingsLocator sessionSettingsLocator = new SessionSettingsLocator(new DefaultResourceLoader());
assertDoesNotThrow(() -> {
sessionSettingsLocator.loadSettingsFromString(configString);
});
}
}
Loading

0 comments on commit 836d253

Please sign in to comment.