Skip to content

Commit

Permalink
Added support for static port for Clickhouse
Browse files Browse the repository at this point in the history
  • Loading branch information
tstavinoha committed Jun 16, 2021
1 parent d065c5b commit 640d873
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 15 deletions.
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -10,24 +13,38 @@

public class ClickhouseContainerInitializer extends InitializerBase<ClickhouseContainerWrapper> {

private static final Pattern JDBC_URL_WITH_DEFINED_PORT_PATTERN = Pattern.compile(".*://.*:(\\d+)(/.*)?");

@Override
public void initialize(ConfigurableApplicationContext applicationContext) {
Environment environment = applicationContext.getEnvironment();
Optional<String> 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("<host>", container.getContainerIpAddress())
.replace("<port>", container.getMappedPort(ClickhouseContainerWrapper.HTTP_PORT)
.toString());
.replace("<port>", container.getMappedPort(ClickhouseContainerWrapper.HTTP_PORT)
.toString());
TestPropertyValues values = TestPropertyValues.of(
String.format("%s=%s", jdbcUrlPropertyPath, url));
values.applyTo(applicationContext);
}

// todo - unduplicate
private Optional<Integer> 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);
}

}
Original file line number Diff line number Diff line change
@@ -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");
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
spring:
datasource:
clickhouse:
jdbc-url: jdbc:clickhouse://<host>:5000

testcontainers:
clickhouse:
custom-path: "spring.datasource.clickhouse"
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public class MSSQLServerContainerInitializer extends InitializerBase<MSSQLServer
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+)/.*");
private static final Pattern JDBC_URL_WITH_DEFINED_PORT_PATTERN = Pattern.compile(".*://.*:(\\d+)(/.*)?");

@Override
public void initialize(ConfigurableApplicationContext applicationContext) {
Expand All @@ -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<String, String> replacedNameToValue = replaceHostAndPort(urlPropertyNameToValue, container);
Expand Down Expand Up @@ -80,7 +80,7 @@ private Map<String, String> getUrlPropertyNameToValue(Environment environment, L

private Optional<Integer> resolveStaticPort(Collection<String> 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()
Expand Down

0 comments on commit 640d873

Please sign in to comment.