From 640d87329182ab9a1c286bbc38cccc9892bbb46b Mon Sep 17 00:00:00 2001 From: tstavinoha Date: Wed, 16 Jun 2021 08:43:58 +0200 Subject: [PATCH] Added support for static port for Clickhouse --- .../ClickhouseContainerInitializer.java | 23 +++++++++-- .../ClickhouseContainerStaticPortTest.java | 38 +++++++++++++++++++ .../spring/clickhouse/DataSourceConfig.java | 17 ++++----- .../resources/application-static-port.yaml | 8 ++++ .../MSSQLServerContainerInitializer.java | 6 +-- 5 files changed, 77 insertions(+), 15 deletions(-) create mode 100644 infobip-clickhouse-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/clickhouse/ClickhouseContainerStaticPortTest.java create mode 100644 infobip-clickhouse-testcontainers-spring-boot-starter/src/test/resources/application-static-port.yaml diff --git a/infobip-clickhouse-testcontainers-spring-boot-starter/src/main/java/com/infobip/testcontainers/spring/clickhouse/ClickhouseContainerInitializer.java b/infobip-clickhouse-testcontainers-spring-boot-starter/src/main/java/com/infobip/testcontainers/spring/clickhouse/ClickhouseContainerInitializer.java index 512581b..cb19c60 100644 --- a/infobip-clickhouse-testcontainers-spring-boot-starter/src/main/java/com/infobip/testcontainers/spring/clickhouse/ClickhouseContainerInitializer.java +++ b/infobip-clickhouse-testcontainers-spring-boot-starter/src/main/java/com/infobip/testcontainers/spring/clickhouse/ClickhouseContainerInitializer.java @@ -1,7 +1,10 @@ package com.infobip.testcontainers.spring.clickhouse; +import java.util.Collections; import java.util.Objects; import java.util.Optional; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import com.infobip.testcontainers.InitializerBase; import org.springframework.boot.test.util.TestPropertyValues; @@ -10,24 +13,38 @@ public class ClickhouseContainerInitializer extends InitializerBase { + private static final Pattern JDBC_URL_WITH_DEFINED_PORT_PATTERN = Pattern.compile(".*://.*:(\\d+)(/.*)?"); + @Override public void initialize(ConfigurableApplicationContext applicationContext) { Environment environment = applicationContext.getEnvironment(); Optional customPropertyPath = Optional.ofNullable(environment.getProperty("testcontainers.clickhouse.custom-path")); - String jdbcUrlPropertyPath = customPropertyPath.orElse( "spring.datasource") + ".jdbc-url"; + String jdbcUrlPropertyPath = customPropertyPath.orElse("spring.datasource") + ".jdbc-url"; String jdbcUrlValue = Objects.requireNonNull(environment.getProperty(jdbcUrlPropertyPath)); ClickhouseContainerWrapper container = Optional.ofNullable( environment.getProperty("testcontainers.clickhouse.docker.image.version")) .map(ClickhouseContainerWrapper::new) .orElseGet(ClickhouseContainerWrapper::new); + resolveStaticPort(jdbcUrlValue) + .ifPresent(staticPort -> container.setPortBindings(Collections.singletonList(staticPort + ":" + ClickhouseContainerWrapper.HTTP_PORT))); + start(container); String url = jdbcUrlValue.replace("", container.getContainerIpAddress()) - .replace("", container.getMappedPort(ClickhouseContainerWrapper.HTTP_PORT) - .toString()); + .replace("", container.getMappedPort(ClickhouseContainerWrapper.HTTP_PORT) + .toString()); TestPropertyValues values = TestPropertyValues.of( String.format("%s=%s", jdbcUrlPropertyPath, url)); values.applyTo(applicationContext); } + // todo - unduplicate + private Optional resolveStaticPort(String connectionString) { + return Optional.ofNullable(connectionString) + .map(JDBC_URL_WITH_DEFINED_PORT_PATTERN::matcher) + .filter(Matcher::matches) + .map(matcher -> matcher.group(1)) + .map(Integer::valueOf); + } + } diff --git a/infobip-clickhouse-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/clickhouse/ClickhouseContainerStaticPortTest.java b/infobip-clickhouse-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/clickhouse/ClickhouseContainerStaticPortTest.java new file mode 100644 index 0000000..4b570a6 --- /dev/null +++ b/infobip-clickhouse-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/clickhouse/ClickhouseContainerStaticPortTest.java @@ -0,0 +1,38 @@ +package com.infobip.testcontainers.spring.clickhouse; + +import static com.infobip.testcontainers.spring.clickhouse.DataSourceConfig.CLICKHOUSE_URL_PROPERTY_NAME; +import static org.assertj.core.api.BDDAssertions.then; + +import javax.sql.DataSource; + +import lombok.AllArgsConstructor; +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.core.env.Environment; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.TestConstructor; + +@AllArgsConstructor +@ActiveProfiles("static-port") +@TestConstructor(autowireMode = TestConstructor.AutowireMode.ALL) +@SpringBootTest(classes = Main.class) +class ClickhouseContainerStaticPortTest { + + Environment environment; + DataSource dataSource; + + @Test + void shouldCreateContainerWithStaticPort() { + //given + JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource); + + //when + String result = jdbcTemplate.queryForObject("SELECT 1", String.class); + + //then + then(environment.getProperty(CLICKHOUSE_URL_PROPERTY_NAME)).isEqualTo("jdbc:clickhouse://localhost:5000"); + then(result).isEqualTo("1"); + } + +} diff --git a/infobip-clickhouse-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/clickhouse/DataSourceConfig.java b/infobip-clickhouse-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/clickhouse/DataSourceConfig.java index 80057e7..eb72a98 100644 --- a/infobip-clickhouse-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/clickhouse/DataSourceConfig.java +++ b/infobip-clickhouse-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/clickhouse/DataSourceConfig.java @@ -2,24 +2,23 @@ import javax.sql.DataSource; -import lombok.AllArgsConstructor; import org.springframework.boot.jdbc.DataSourceBuilder; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.env.Environment; +import ru.yandex.clickhouse.ClickHouseDriver; @Configuration -@AllArgsConstructor public class DataSourceConfig { - private final Environment environment; + static final String CLICKHOUSE_URL_PROPERTY_NAME = "spring.datasource.clickhouse.jdbc-url"; @Bean - public DataSource getDataSource() { - String url = environment.getProperty("spring.datasource.clickhouse.jdbc-url"); - DataSourceBuilder dataSourceBuilder = DataSourceBuilder.create(); - dataSourceBuilder.driverClassName("ru.yandex.clickhouse.ClickHouseDriver"); - dataSourceBuilder.url(url); - return dataSourceBuilder.build(); + public DataSource getDataSource(Environment environment) { + return DataSourceBuilder.create() + .driverClassName(ClickHouseDriver.class.getName()) + .url(environment.getProperty(CLICKHOUSE_URL_PROPERTY_NAME)) + .build(); } + } diff --git a/infobip-clickhouse-testcontainers-spring-boot-starter/src/test/resources/application-static-port.yaml b/infobip-clickhouse-testcontainers-spring-boot-starter/src/test/resources/application-static-port.yaml new file mode 100644 index 0000000..47a4f4c --- /dev/null +++ b/infobip-clickhouse-testcontainers-spring-boot-starter/src/test/resources/application-static-port.yaml @@ -0,0 +1,8 @@ +spring: + datasource: + clickhouse: + jdbc-url: jdbc:clickhouse://:5000 + +testcontainers: + clickhouse: + custom-path: "spring.datasource.clickhouse" diff --git a/infobip-mssql-testcontainers-spring-boot-starter/src/main/java/com/infobip/testcontainers/spring/mssql/MSSQLServerContainerInitializer.java b/infobip-mssql-testcontainers-spring-boot-starter/src/main/java/com/infobip/testcontainers/spring/mssql/MSSQLServerContainerInitializer.java index 56612ba..20e0f2e 100644 --- a/infobip-mssql-testcontainers-spring-boot-starter/src/main/java/com/infobip/testcontainers/spring/mssql/MSSQLServerContainerInitializer.java +++ b/infobip-mssql-testcontainers-spring-boot-starter/src/main/java/com/infobip/testcontainers/spring/mssql/MSSQLServerContainerInitializer.java @@ -24,7 +24,7 @@ public class MSSQLServerContainerInitializer extends InitializerBase 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+)/.*"); + private static final Pattern JDBC_URL_WITH_DEFINED_PORT_PATTERN = Pattern.compile(".*://.*:(\\d+)(/.*)?"); @Override public void initialize(ConfigurableApplicationContext applicationContext) { @@ -38,7 +38,7 @@ public void initialize(ConfigurableApplicationContext applicationContext) { .orElseGet(MSSQLServerContainerWrapper::new); resolveStaticPort(urlPropertyNameToValue.values()) - .ifPresent(fixedPort -> container.setPortBindings(Collections.singletonList(fixedPort + ":" + MS_SQL_SERVER_PORT))); + .ifPresent(staticPort -> container.setPortBindings(Collections.singletonList(staticPort + ":" + MS_SQL_SERVER_PORT))); start(container); Map replacedNameToValue = replaceHostAndPort(urlPropertyNameToValue, container); @@ -80,7 +80,7 @@ private Map getUrlPropertyNameToValue(Environment environment, L private Optional resolveStaticPort(Collection connectionStrings) { return connectionStrings.stream() - .map(JDBC_URL_WITH_FIXED_PORT_PATTERN::matcher) + .map(JDBC_URL_WITH_DEFINED_PORT_PATTERN::matcher) .filter(Matcher::matches) .map(matcher -> matcher.group(1)) .findFirst()