Skip to content

Commit

Permalink
Added support for static port for Sql Server
Browse files Browse the repository at this point in the history
  • Loading branch information
tstavinoha committed Jun 15, 2021
1 parent ea7ce72 commit d065c5b
Show file tree
Hide file tree
Showing 3 changed files with 117 additions and 12 deletions.
Original file line number Diff line number Diff line change
@@ -1,20 +1,30 @@
package com.infobip.testcontainers.spring.mssql;

import static org.testcontainers.containers.MSSQLServerContainer.MS_SQL_SERVER_PORT;

import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import com.infobip.testcontainers.InitializerBase;
import org.springframework.boot.test.util.TestPropertyValues;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.env.Environment;

import java.util.*;
import java.util.stream.Collectors;

import static org.testcontainers.containers.MSSQLServerContainer.MS_SQL_SERVER_PORT;

public class MSSQLServerContainerInitializer extends InitializerBase<MSSQLServerContainerWrapper> {

private static final List<String> DEFAULT_PROPERTY_NAMES = Arrays.asList("spring.datasource.url",
"spring.flyway.url",
"spring.r2dbc.url");
private static final Pattern JDBC_URL_WITH_FIXED_PORT_PATTERN = Pattern.compile(".*://.*:(\\d+)/.*");

@Override
public void initialize(ConfigurableApplicationContext applicationContext) {
Expand All @@ -23,31 +33,31 @@ public void initialize(ConfigurableApplicationContext applicationContext) {
Map<String, String> urlPropertyNameToValue = getUrlPropertyNameToValue(environment, urlPropertyNames);

MSSQLServerContainerWrapper container = Optional.ofNullable(
environment.getProperty("testcontainers.mssql.docker.image"))
environment.getProperty("testcontainers.mssql.docker.image"))
.map(MSSQLServerContainerWrapper::new)
.orElseGet(MSSQLServerContainerWrapper::new);

resolveStaticPort(urlPropertyNameToValue.values())
.ifPresent(fixedPort -> container.setPortBindings(Collections.singletonList(fixedPort + ":" + MS_SQL_SERVER_PORT)));

start(container);
Map<String, String> replacedNameToValue = replaceHostAndPort(urlPropertyNameToValue, container);
Map<String, String> testPropertyValues = addMissingUsernameAndPassword(replacedNameToValue, container);
TestPropertyValues values = TestPropertyValues.of(testPropertyValues);

values.applyTo(applicationContext);
String url = replacedNameToValue.getOrDefault("spring.datasource.url",
replacedNameToValue.get("spring.flyway.url"));
String url = replacedNameToValue.getOrDefault("spring.datasource.url", replacedNameToValue.get("spring.flyway.url"));
DatabaseCreator creator = new DatabaseCreator(url, container.getUsername(), container.getPassword());
creator.createDatabaseIfItDoesntExist();
}

private List<String> getUrlPropertyNames(Environment environment) {

String name = environment.getProperty("testcontainers.mssql.datasource.url.property.name");

if (Objects.nonNull(name)) {
return Collections.singletonList(name);
}

String[] names = environment.getProperty("testcontainers.mssql.datasource.url.property.names", String[].class);

if (Objects.nonNull(names)) {
return Arrays.asList(names);
}
Expand All @@ -56,7 +66,6 @@ private List<String> getUrlPropertyNames(Environment environment) {
}

private Map<String, String> getUrlPropertyNameToValue(Environment environment, List<String> names) {

Map<String, String> propertyNameToValue = new HashMap<>();

for (String name : names) {
Expand All @@ -69,6 +78,15 @@ private Map<String, String> getUrlPropertyNameToValue(Environment environment, L
return propertyNameToValue;
}

private Optional<Integer> resolveStaticPort(Collection<String> connectionStrings) {
return connectionStrings.stream()
.map(JDBC_URL_WITH_FIXED_PORT_PATTERN::matcher)
.filter(Matcher::matches)
.map(matcher -> matcher.group(1))
.findFirst()
.map(Integer::valueOf);
}

private Map<String, String> replaceHostAndPort(Map<String, String> urlPropertyNameToValue,
MSSQLServerContainerWrapper container) {
String host = container.getContainerIpAddress();
Expand Down Expand Up @@ -96,4 +114,5 @@ private Map<String, String> addMissingUsernameAndPassword(Map<String, String> ur
}
return testPropertyValues;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package com.infobip.testcontainers.spring.mssql;

import static org.assertj.core.api.BDDAssertions.then;

import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.SQLException;

import lombok.AllArgsConstructor;
import org.junit.jupiter.api.Test;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.core.env.Environment;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.SimpleDriverDataSource;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.TestConstructor;
import org.testcontainers.Testcontainers;

@AllArgsConstructor
@ActiveProfiles("static-port")
@TestConstructor(autowireMode = TestConstructor.AutowireMode.ALL)
@SpringBootTest(classes = Main.class)
class StaticPortSqlServerDockerTest {

private final Environment environment;
private final DataSourceProperties properties;

@Test
void shouldCreateContainer() {
// given
JdbcTemplate jdbcTemplate = new JdbcTemplate(new SimpleDriverDataSource(
getDriver(properties.getUrl()),
properties.getUrl(),
properties.getUsername(),
properties.getPassword()));

// when
String actual = jdbcTemplate.queryForObject("SELECT db_name()", String.class);

// then
then(actual).isEqualTo("MicrosoftDriverTestDatabase");
}

@Test
void shouldReplaceHostInJdbcUrl() {
// when
String actual = environment.getProperty("spring.datasource.url");

// then
then(actual).contains("localhost:1433");
}

@Test
void shouldReplaceHostInR2dbc() {
// when
String actual = environment.getProperty("spring.r2dbc.url");

// then
then(actual).contains("localhost:1433");
}

@Test
void shouldReplaceHostInFlyway() {
// when
String actual = environment.getProperty("spring.flyway.url");

// then
then(actual).contains("localhost:1433");
}

private Driver getDriver(String jdbcUrl) {
try {
return DriverManager.getDriver(jdbcUrl);
} catch (SQLException e) {
throw new IllegalArgumentException(e);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
spring:
datasource:
url: jdbc:sqlserver://<host>:1433;database=MicrosoftDriverTestDatabase
r2dbc:
url: r2dbc:pool:mssql://<host>:1433/InfobipSpringDataJdbcQuerydslTest
flyway:
url: jdbc:sqlserver://<host>:1433;database=MicrosoftDriverTestDatabase

0 comments on commit d065c5b

Please sign in to comment.