Skip to content

Commit b78514f

Browse files
Add r2dbc support for Clickhouse (#8434)
Fixes #8427 --------- Co-authored-by: Eddú Meléndez <[email protected]>
1 parent 351516c commit b78514f

File tree

9 files changed

+138
-8
lines changed

9 files changed

+138
-8
lines changed

docs/modules/databases/r2dbc.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@ So that the URL becomes:
3333

3434
### R2DBC URL examples
3535

36+
#### Using ClickHouse
37+
38+
`r2dbc:tc:clickhouse:///databasename?TC_IMAGE_TAG=21.9.2-alpine`
39+
3640
#### Using MySQL
3741

3842
`r2dbc:tc:mysql:///databasename?TC_IMAGE_TAG=8.0.36`

modules/clickhouse/build.gradle

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,12 @@ dependencies {
44
api project(':testcontainers')
55
api project(':jdbc')
66

7+
compileOnly project(':r2dbc')
8+
compileOnly(group: 'com.clickhouse', name: 'clickhouse-r2dbc', version: '0.7.0', classifier: 'http')
9+
710
testImplementation project(':jdbc-test')
8-
testRuntimeOnly 'ru.yandex.clickhouse:clickhouse-jdbc:0.3.2'
11+
testRuntimeOnly(group: 'com.clickhouse', name: 'clickhouse-jdbc', version: '0.7.0', classifier: 'http')
912
testImplementation 'org.assertj:assertj-core:3.26.3'
13+
testImplementation testFixtures(project(':r2dbc'))
14+
testRuntimeOnly(group: 'com.clickhouse', name: 'clickhouse-r2dbc', version: '0.7.0', classifier: 'http')
1015
}

modules/clickhouse/src/main/java/org/testcontainers/clickhouse/ClickHouseContainer.java

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,23 +23,29 @@ public class ClickHouseContainer extends JdbcDatabaseContainer<ClickHouseContain
2323

2424
private static final String NAME = "clickhouse";
2525

26-
private static final DockerImageName CLICKHOUSE_IMAGE_NAME = DockerImageName.parse("clickhouse/clickhouse-server");
26+
static final String CLICKHOUSE_CLICKHOUSE_SERVER = "clickhouse/clickhouse-server";
2727

28-
private static final Integer HTTP_PORT = 8123;
28+
private static final DockerImageName CLICKHOUSE_IMAGE_NAME = DockerImageName.parse(CLICKHOUSE_CLICKHOUSE_SERVER);
2929

30-
private static final Integer NATIVE_PORT = 9000;
30+
static final Integer HTTP_PORT = 8123;
31+
32+
static final Integer NATIVE_PORT = 9000;
3133

3234
private static final String DRIVER_CLASS_NAME = "com.clickhouse.jdbc.ClickHouseDriver";
3335

3436
private static final String JDBC_URL_PREFIX = "jdbc:" + NAME + "://";
3537

3638
private static final String TEST_QUERY = "SELECT 1";
3739

40+
static final String DEFAULT_USER = "default";
41+
42+
static final String DEFAULT_PASSWORD = "";
43+
3844
private String databaseName = "default";
3945

40-
private String username = "default";
46+
private String username = DEFAULT_USER;
4147

42-
private String password = "";
48+
private String password = DEFAULT_PASSWORD;
4349

4450
public ClickHouseContainer(String dockerImageName) {
4551
this(DockerImageName.parse(dockerImageName));
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package org.testcontainers.clickhouse;
2+
3+
import io.r2dbc.spi.ConnectionFactoryOptions;
4+
import org.testcontainers.r2dbc.R2DBCDatabaseContainer;
5+
6+
/**
7+
* ClickHouse R2DBC support
8+
*/
9+
public class ClickHouseR2DBCDatabaseContainer implements R2DBCDatabaseContainer {
10+
11+
private final ClickHouseContainer container;
12+
13+
public ClickHouseR2DBCDatabaseContainer(ClickHouseContainer container) {
14+
this.container = container;
15+
}
16+
17+
public static ConnectionFactoryOptions getOptions(ClickHouseContainer container) {
18+
ConnectionFactoryOptions options = ConnectionFactoryOptions
19+
.builder()
20+
.option(ConnectionFactoryOptions.DRIVER, ClickHouseR2DBCDatabaseContainerProvider.DRIVER)
21+
.build();
22+
23+
return new ClickHouseR2DBCDatabaseContainer(container).configure(options);
24+
}
25+
26+
@Override
27+
public void start() {
28+
this.container.start();
29+
}
30+
31+
@Override
32+
public void stop() {
33+
this.container.stop();
34+
}
35+
36+
@Override
37+
public ConnectionFactoryOptions configure(ConnectionFactoryOptions options) {
38+
return options
39+
.mutate()
40+
.option(ConnectionFactoryOptions.HOST, container.getHost())
41+
.option(ConnectionFactoryOptions.PORT, container.getMappedPort(ClickHouseContainer.HTTP_PORT))
42+
.option(ConnectionFactoryOptions.DATABASE, container.getDatabaseName())
43+
.option(ConnectionFactoryOptions.USER, container.getUsername())
44+
.option(ConnectionFactoryOptions.PASSWORD, container.getPassword())
45+
.option(ConnectionFactoryOptions.PROTOCOL, "http")
46+
.build();
47+
}
48+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package org.testcontainers.clickhouse;
2+
3+
import com.clickhouse.r2dbc.connection.ClickHouseConnectionFactoryProvider;
4+
import io.r2dbc.spi.ConnectionFactoryMetadata;
5+
import io.r2dbc.spi.ConnectionFactoryOptions;
6+
import org.testcontainers.r2dbc.R2DBCDatabaseContainer;
7+
import org.testcontainers.r2dbc.R2DBCDatabaseContainerProvider;
8+
9+
import javax.annotation.Nullable;
10+
11+
public class ClickHouseR2DBCDatabaseContainerProvider implements R2DBCDatabaseContainerProvider {
12+
13+
static final String DRIVER = ClickHouseConnectionFactoryProvider.CLICKHOUSE_DRIVER;
14+
15+
@Override
16+
public boolean supports(ConnectionFactoryOptions options) {
17+
return DRIVER.equals(options.getRequiredValue(ConnectionFactoryOptions.DRIVER));
18+
}
19+
20+
@Override
21+
public R2DBCDatabaseContainer createContainer(ConnectionFactoryOptions options) {
22+
String image =
23+
ClickHouseContainer.CLICKHOUSE_CLICKHOUSE_SERVER + ":" + options.getRequiredValue(IMAGE_TAG_OPTION);
24+
ClickHouseContainer container = new ClickHouseContainer(image)
25+
.withDatabaseName((String) options.getRequiredValue(ConnectionFactoryOptions.DATABASE));
26+
27+
if (Boolean.TRUE.equals(options.getValue(REUSABLE_OPTION))) {
28+
container.withReuse(true);
29+
}
30+
return new ClickHouseR2DBCDatabaseContainer(container);
31+
}
32+
33+
@Nullable
34+
@Override
35+
public ConnectionFactoryMetadata getMetadata(ConnectionFactoryOptions options) {
36+
ConnectionFactoryOptions.Builder builder = options.mutate();
37+
if (!options.hasOption(ConnectionFactoryOptions.USER)) {
38+
builder.option(ConnectionFactoryOptions.USER, ClickHouseContainer.DEFAULT_USER);
39+
}
40+
if (!options.hasOption(ConnectionFactoryOptions.PASSWORD)) {
41+
builder.option(ConnectionFactoryOptions.PASSWORD, ClickHouseContainer.DEFAULT_PASSWORD);
42+
}
43+
builder.option(ConnectionFactoryOptions.PROTOCOL, "http");
44+
return R2DBCDatabaseContainerProvider.super.getMetadata(builder.build());
45+
}
46+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
org.testcontainers.clickhouse.ClickHouseR2DBCDatabaseContainerProvider

modules/clickhouse/src/test/java/org/testcontainers/ClickhouseTestImages.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,5 @@
33
import org.testcontainers.utility.DockerImageName;
44

55
public interface ClickhouseTestImages {
6-
DockerImageName YANDEX_CLICKHOUSE_IMAGE = DockerImageName.parse("yandex/clickhouse-server:18.10.3");
76
DockerImageName CLICKHOUSE_IMAGE = DockerImageName.parse("clickhouse/clickhouse-server:21.9.2-alpine");
87
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package org.testcontainers.clickhouse;
2+
3+
import io.r2dbc.spi.ConnectionFactoryOptions;
4+
import org.testcontainers.r2dbc.AbstractR2DBCDatabaseContainerTest;
5+
6+
public class ClickHouseR2DBCDatabaseContainerTest extends AbstractR2DBCDatabaseContainerTest<ClickHouseContainer> {
7+
8+
@Override
9+
protected ConnectionFactoryOptions getOptions(ClickHouseContainer container) {
10+
return ClickHouseR2DBCDatabaseContainer.getOptions(container);
11+
}
12+
13+
@Override
14+
protected String createR2DBCUrl() {
15+
return "r2dbc:tc:clickhouse:///db?TC_IMAGE_TAG=21.9.2-alpine";
16+
}
17+
18+
@Override
19+
protected ClickHouseContainer createContainer() {
20+
return new ClickHouseContainer("clickhouse/clickhouse-server:21.9.2-alpine");
21+
}
22+
}

modules/clickhouse/src/test/java/org/testcontainers/junit/clickhouse/SimpleClickhouseTest.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ public SimpleClickhouseTest(DockerImageName imageName) {
2626
public static Object[][] data() {
2727
return new Object[][] { //
2828
{ ClickhouseTestImages.CLICKHOUSE_IMAGE },
29-
{ ClickhouseTestImages.YANDEX_CLICKHOUSE_IMAGE },
3029
};
3130
}
3231

0 commit comments

Comments
 (0)