Skip to content

Commit 75ddd37

Browse files
authored
Multi-endpoint support (#956)
* Multi-endpoint support * Skip one more test * Add nullAsDefault JDBC option for handling null values * Fix compile error on JDK 8 * More test for nullAsDefault option * fix issues when fail over to different protocol or connecting to single-node * Failover on UnknownHostException * Correct exception handling * Correct words * support slash in connection parameter and case-insensitive enum value
1 parent 425bb85 commit 75ddd37

File tree

93 files changed

+5316
-1274
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

93 files changed

+5316
-1274
lines changed

clickhouse-benchmark/pom.xml

Lines changed: 1 addition & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
<scope>provided</scope>
3838
</dependency>
3939

40+
<!-- JDBC drivers -->
4041
<dependency>
4142
<groupId>ru.yandex.clickhouse</groupId>
4243
<artifactId>clickhouse-jdbc</artifactId>
@@ -49,33 +50,6 @@
4950
</exclusion>
5051
</exclusions>
5152
</dependency>
52-
<dependency>
53-
<groupId>${project.parent.groupId}</groupId>
54-
<artifactId>clickhouse-client</artifactId>
55-
<version>${revision}</version>
56-
</dependency>
57-
<dependency>
58-
<groupId>${project.parent.groupId}</groupId>
59-
<artifactId>clickhouse-grpc-client</artifactId>
60-
<version>${revision}</version>
61-
<!-- exclusions>
62-
<exclusion>
63-
<groupId>${project.parent.groupId}</groupId>
64-
<artifactId>io.grpc</artifactId>
65-
</exclusion>
66-
</exclusions -->
67-
</dependency>
68-
<dependency>
69-
<groupId>io.grpc</groupId>
70-
<artifactId>grpc-netty-shaded</artifactId>
71-
</dependency>
72-
<!-- separate classifier did not work well with flatten plugin -->
73-
<dependency>
74-
<groupId>io.grpc</groupId>
75-
<artifactId>grpc-okhttp</artifactId>
76-
</dependency>
77-
78-
<!-- JDBC drivers -->
7953
<dependency>
8054
<groupId>com.clickhouse</groupId>
8155
<artifactId>clickhouse-jdbc</artifactId>

clickhouse-cli-client/src/main/java/com/clickhouse/client/cli/ClickHouseCommandLine.java

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,8 @@ public class ClickHouseCommandLine implements AutoCloseable {
4646
private static final Logger log = LoggerFactory.getLogger(ClickHouseCommandLine.class);
4747

4848
public static final String DEFAULT_CLI_ARG_VERSION = "--version";
49-
public static final String DEFAULT_CLICKHOUSE_CLI_PATH = "clickhouse-client";
49+
public static final String DEFAULT_CLICKHOUSE_CLI_PATH = "clickhouse";
50+
public static final String DEFAULT_CLIENT_OPTION = "client";
5051
public static final String DEFAULT_DOCKER_CLI_PATH = "docker";
5152
public static final String DEFAULT_DOCKER_IMAGE = "clickhouse/clickhouse-server";
5253

@@ -103,9 +104,11 @@ static void dockerCommand(ClickHouseConfig config, String hostDir, String contai
103104
}
104105
String str = (String) config.getOption(ClickHouseCommandLineOption.CLI_CONTAINER_ID);
105106
if (!ClickHouseChecker.isNullOrBlank(str)) {
106-
if (!check(timeout, cli, "exec", str, DEFAULT_CLICKHOUSE_CLI_PATH, DEFAULT_CLI_ARG_VERSION)) {
107+
if (!check(timeout, cli, "exec", str, DEFAULT_CLICKHOUSE_CLI_PATH, DEFAULT_CLIENT_OPTION,
108+
DEFAULT_CLI_ARG_VERSION)) {
107109
synchronized (ClickHouseCommandLine.class) {
108-
if (!check(timeout, cli, "exec", str, DEFAULT_CLICKHOUSE_CLI_PATH, DEFAULT_CLI_ARG_VERSION)
110+
if (!check(timeout, cli, "exec", str, DEFAULT_CLICKHOUSE_CLI_PATH, DEFAULT_CLIENT_OPTION,
111+
DEFAULT_CLI_ARG_VERSION)
109112
&& !check(timeout, cli, "run", "--rm", "--name", str, "-v", hostDir + ':' + containerDir,
110113
"-d", img, "tail", "-f", "/dev/null")) {
111114
throw new IllegalStateException("Failed to start new container: " + str);
@@ -117,7 +120,8 @@ static void dockerCommand(ClickHouseConfig config, String hostDir, String contai
117120
commands.add("-i");
118121
commands.add(str);
119122
} else { // create new container for each query
120-
if (!check(timeout, cli, "run", "--rm", img, DEFAULT_CLICKHOUSE_CLI_PATH, DEFAULT_CLI_ARG_VERSION)) {
123+
if (!check(timeout, cli, "run", "--rm", img, DEFAULT_CLICKHOUSE_CLI_PATH, DEFAULT_CLIENT_OPTION,
124+
DEFAULT_CLI_ARG_VERSION)) {
121125
throw new IllegalStateException("Invalid ClickHouse docker image: " + img);
122126
}
123127
commands.add("run");
@@ -150,13 +154,14 @@ static Process startProcess(ClickHouseNode server, ClickHouseRequest<?> request)
150154
if (ClickHouseChecker.isNullOrBlank(cli)) {
151155
cli = DEFAULT_CLICKHOUSE_CLI_PATH;
152156
}
153-
if (!check(timeout, cli, DEFAULT_CLI_ARG_VERSION)) {
157+
if (!check(timeout, cli, DEFAULT_CLIENT_OPTION, DEFAULT_CLI_ARG_VERSION)) {
154158
// fallback to docker
155159
dockerCommand(config, hostDir, containerDir, timeout, commands);
156160
} else {
157161
commands.add(cli);
158162
containerDir = hostDir;
159163
}
164+
commands.add(DEFAULT_CLIENT_OPTION);
160165

161166
if (config.isSsl()) {
162167
commands.add("--secure");
Lines changed: 30 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
package com.clickhouse.client.cli;
22

33
import java.io.IOException;
4-
import java.util.concurrent.CompletableFuture;
5-
import java.util.concurrent.CompletionException;
4+
import java.util.Collection;
5+
import java.util.Collections;
6+
import java.util.List;
67

78
import com.clickhouse.client.AbstractClient;
89
import com.clickhouse.client.ClickHouseChecker;
@@ -24,6 +25,19 @@
2425
public class ClickHouseCommandLineClient extends AbstractClient<ClickHouseCommandLine> {
2526
private static final Logger log = LoggerFactory.getLogger(ClickHouseCommandLineClient.class);
2627

28+
static final List<ClickHouseProtocol> SUPPORTED = Collections.singletonList(ClickHouseProtocol.TCP);
29+
30+
@Override
31+
protected boolean checkHealth(ClickHouseNode server, int timeout) {
32+
try (ClickHouseCommandLine cli = getConnection(connect(server).query("select 1"));
33+
ClickHouseCommandLineResponse response = new ClickHouseCommandLineResponse(getConfig(), cli)) {
34+
return response.firstRecord().getValue(0).asInteger() == 1;
35+
} catch (Exception e) {
36+
// ignore
37+
}
38+
return false;
39+
}
40+
2741
@Override
2842
protected ClickHouseCommandLine newConnection(ClickHouseCommandLine conn, ClickHouseNode server,
2943
ClickHouseRequest<?> request) {
@@ -49,6 +63,16 @@ protected void closeConnection(ClickHouseCommandLine conn, boolean force) {
4963
}
5064
}
5165

66+
@Override
67+
protected Collection<ClickHouseProtocol> getSupportedProtocols() {
68+
return SUPPORTED;
69+
}
70+
71+
@Override
72+
protected ClickHouseResponse send(ClickHouseRequest<?> sealedRequest) throws ClickHouseException, IOException {
73+
return new ClickHouseCommandLineResponse(sealedRequest.getConfig(), getConnection(sealedRequest));
74+
}
75+
5276
@Override
5377
public boolean accept(ClickHouseProtocol protocol) {
5478
ClickHouseConfig config = getConfig();
@@ -65,50 +89,14 @@ public boolean accept(ClickHouseProtocol protocol) {
6589
docker = ClickHouseCommandLine.DEFAULT_DOCKER_CLI_PATH;
6690
}
6791
return ClickHouseProtocol.TCP == protocol
68-
&& (ClickHouseCommandLine.check(timeout, cli, ClickHouseCommandLine.DEFAULT_CLI_ARG_VERSION)
69-
|| ClickHouseCommandLine.check(timeout, docker, ClickHouseCommandLine.DEFAULT_CLI_ARG_VERSION));
70-
}
71-
72-
@Override
73-
public CompletableFuture<ClickHouseResponse> execute(ClickHouseRequest<?> request) {
74-
final ClickHouseRequest<?> sealedRequest = request.seal();
75-
final ClickHouseConfig config = sealedRequest.getConfig();
76-
final ClickHouseNode server = getServer();
77-
78-
if (config.isAsync()) {
79-
return CompletableFuture
80-
.supplyAsync(() -> {
81-
try {
82-
return new ClickHouseCommandLineResponse(config, getConnection(sealedRequest));
83-
} catch (IOException e) {
84-
throw new CompletionException(e);
85-
}
86-
});
87-
} else {
88-
try {
89-
return CompletableFuture
90-
.completedFuture(new ClickHouseCommandLineResponse(config, getConnection(sealedRequest)));
91-
} catch (IOException e) {
92-
throw new CompletionException(ClickHouseException.of(e, server));
93-
}
94-
}
92+
&& (ClickHouseCommandLine.check(timeout, cli, ClickHouseCommandLine.DEFAULT_CLIENT_OPTION,
93+
ClickHouseCommandLine.DEFAULT_CLI_ARG_VERSION)
94+
|| ClickHouseCommandLine.check(timeout, docker, ClickHouseCommandLine.DEFAULT_CLIENT_OPTION,
95+
ClickHouseCommandLine.DEFAULT_CLI_ARG_VERSION));
9596
}
9697

9798
@Override
9899
public final Class<? extends ClickHouseOption> getOptionClass() {
99100
return ClickHouseCommandLineOption.class;
100101
}
101-
102-
@Override
103-
public boolean ping(ClickHouseNode server, int timeout) {
104-
if (server != null) {
105-
try (ClickHouseCommandLine cli = getConnection(connect(server).query("select 1"));
106-
ClickHouseCommandLineResponse response = new ClickHouseCommandLineResponse(getConfig(), cli)) {
107-
return response.firstRecord().getValue(0).asInteger() == 1;
108-
} catch (Exception e) {
109-
// ignore
110-
}
111-
}
112-
return false;
113-
}
114102
}

clickhouse-cli-client/src/test/java/com/clickhouse/client/cli/ClickHouseCommandLineClientTest.java

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,12 @@ protected ClickHouseNode getServer() {
4747
return super.getServer();
4848
}
4949

50+
@Test(groups = { "integration" })
51+
@Override
52+
public void testCustomLoad() throws Exception {
53+
throw new SkipException("Skip due to time out error");
54+
}
55+
5056
@Test(groups = { "integration" })
5157
@Override
5258
public void testLoadRawData() throws Exception {
@@ -56,17 +62,23 @@ public void testLoadRawData() throws Exception {
5662
@Test(groups = { "integration" })
5763
@Override
5864
public void testMultipleQueries() throws Exception {
59-
// FIXME not sure if the occasional "Stream closed" exception is related to zeroturnaround/zt-exec#30 or not
65+
// FIXME not sure if the occasional "Stream closed" exception is related to
66+
// zeroturnaround/zt-exec#30 or not
6067
/*
61-
Caused by: java.io.IOException: Stream closed
62-
at java.io.BufferedInputStream.getBufIfOpen(BufferedInputStream.java:170)
63-
at java.io.BufferedInputStream.read(BufferedInputStream.java:336)
64-
at com.clickhouse.client.stream.WrappedInputStream.updateBuffer(WrappedInputStream.java:32)
65-
at com.clickhouse.client.stream.AbstractByteArrayInputStream.available(AbstractByteArrayInputStream.java:56)
66-
at com.clickhouse.client.ClickHouseDataProcessor.hasNext(ClickHouseDataProcessor.java:126)
68+
* Caused by: java.io.IOException: Stream closed
69+
* at java.io.BufferedInputStream.getBufIfOpen(BufferedInputStream.java:170)
70+
* at java.io.BufferedInputStream.read(BufferedInputStream.java:336)
71+
* at com.clickhouse.client.stream.WrappedInputStream.updateBuffer(
72+
* WrappedInputStream.java:32)
73+
* at com.clickhouse.client.stream.AbstractByteArrayInputStream.available(
74+
* AbstractByteArrayInputStream.java:56)
75+
* at
76+
* com.clickhouse.client.ClickHouseDataProcessor.hasNext(ClickHouseDataProcessor
77+
* .java:126)
6778
*/
6879
throw new SkipException("Skip due to unknown cause");
6980
}
81+
7082
@Test(groups = { "integration" })
7183
@Override
7284
public void testReadWriteGeoTypes() {

0 commit comments

Comments
 (0)