|
3 | 3 | import com.clickhouse.client.api.Client; |
4 | 4 | import com.clickhouse.client.api.ClientConfigProperties; |
5 | 5 | import com.clickhouse.client.api.ClientException; |
6 | | -import com.clickhouse.client.api.Session; |
7 | 6 | import com.clickhouse.client.api.ClientFaultCause; |
8 | 7 | import com.clickhouse.client.api.ClientMisconfigurationException; |
9 | 8 | import com.clickhouse.client.api.ConnectionInitiationException; |
10 | 9 | import com.clickhouse.client.api.ConnectionReuseStrategy; |
11 | 10 | import com.clickhouse.client.api.ServerException; |
| 11 | +import com.clickhouse.client.api.Session; |
12 | 12 | import com.clickhouse.client.api.command.CommandResponse; |
13 | 13 | import com.clickhouse.client.api.command.CommandSettings; |
14 | 14 | import com.clickhouse.client.api.data_formats.ClickHouseBinaryFormatReader; |
15 | 15 | import com.clickhouse.client.api.enums.Protocol; |
16 | 16 | import com.clickhouse.client.api.enums.ProxyType; |
17 | | -import com.clickhouse.client.api.insert.InsertSettings; |
18 | 17 | import com.clickhouse.client.api.insert.InsertResponse; |
| 18 | +import com.clickhouse.client.api.insert.InsertSettings; |
19 | 19 | import com.clickhouse.client.api.internal.DataTypeConverter; |
20 | 20 | import com.clickhouse.client.api.internal.ServerSettings; |
| 21 | +import com.clickhouse.client.api.internal.ValidationUtils; |
21 | 22 | import com.clickhouse.client.api.query.GenericRecord; |
22 | 23 | import com.clickhouse.client.api.query.QueryResponse; |
23 | 24 | import com.clickhouse.client.api.query.QuerySettings; |
|
57 | 58 | import java.util.UUID; |
58 | 59 | import java.util.concurrent.CompletableFuture; |
59 | 60 | import java.util.concurrent.ExecutionException; |
| 61 | +import java.util.concurrent.ThreadLocalRandom; |
60 | 62 | import java.util.concurrent.TimeUnit; |
61 | 63 | import java.util.concurrent.atomic.AtomicInteger; |
62 | 64 | import java.util.regex.Pattern; |
@@ -1047,8 +1049,9 @@ public void testBearerTokenAuth() throws Exception { |
1047 | 1049 | return; // mocked server |
1048 | 1050 | } |
1049 | 1051 |
|
| 1052 | + int randomPort = ThreadLocalRandom.current().nextInt(3000,65535); |
1050 | 1053 | WireMockServer mockServer = new WireMockServer( WireMockConfiguration |
1051 | | - .options().port(9090).notifier(new ConsoleNotifier(false))); |
| 1054 | + .options().port(randomPort).notifier(new ConsoleNotifier(false))); |
1052 | 1055 | mockServer.start(); |
1053 | 1056 |
|
1054 | 1057 | try { |
@@ -1108,14 +1111,95 @@ public void testBearerTokenAuth() throws Exception { |
1108 | 1111 | .build()); |
1109 | 1112 |
|
1110 | 1113 | client.updateBearerToken(jwtToken2); |
| 1114 | + client.execute("SELECT 1").get(); |
| 1115 | + |
| 1116 | + Assert.expectThrows(ValidationUtils.SettingsValidationException.class, () -> client.updateBearerToken(null)); |
| 1117 | + Assert.expectThrows(ValidationUtils.SettingsValidationException.class, () -> client.updateBearerToken("")); |
| 1118 | + } |
| 1119 | + } finally { |
| 1120 | + mockServer.stop(); |
| 1121 | + } |
| 1122 | + } |
| 1123 | + |
| 1124 | + @Test(groups = { "integration" }) |
| 1125 | + public void testAccessTokenAuth() throws Exception { |
| 1126 | + if (isCloud()) { |
| 1127 | + return; // mocked server |
| 1128 | + } |
| 1129 | + |
| 1130 | + int randomPort = ThreadLocalRandom.current().nextInt(3000,65535); |
| 1131 | + WireMockServer mockServer = new WireMockServer( WireMockConfiguration |
| 1132 | + .options().port(randomPort).notifier(new ConsoleNotifier(false))); |
| 1133 | + mockServer.start(); |
| 1134 | + |
| 1135 | + try { |
| 1136 | + String accessToken1 = Arrays.stream( |
| 1137 | + new String[]{"header", "payload", "signature"}) |
| 1138 | + .map(s -> Base64.getEncoder().encodeToString(s.getBytes(StandardCharsets.UTF_8))) |
| 1139 | + .reduce((s1, s2) -> s1 + "." + s2).get(); |
| 1140 | + try (Client client = new Client.Builder().addEndpoint(Protocol.HTTP, "localhost", mockServer.port(), false) |
| 1141 | + .setAccessToken(accessToken1) |
| 1142 | + .compressServerResponse(false) |
| 1143 | + .build()) { |
1111 | 1144 |
|
| 1145 | + mockServer.addStubMapping(WireMock.post(WireMock.anyUrl()) |
| 1146 | + .withHeader("Authorization", WireMock.equalTo(accessToken1)) |
| 1147 | + .willReturn(WireMock.aResponse() |
| 1148 | + .withHeader("X-ClickHouse-Summary", |
| 1149 | + "{ \"read_bytes\": \"10\", \"read_rows\": \"1\"}")).build()); |
| 1150 | + |
| 1151 | + try (QueryResponse response = client.query("SELECT 1").get(1, TimeUnit.SECONDS)) { |
| 1152 | + Assert.assertEquals(response.getReadBytes(), 10); |
| 1153 | + } catch (Exception e) { |
| 1154 | + Assert.fail("Unexpected exception", e); |
| 1155 | + } |
| 1156 | + } |
| 1157 | + |
| 1158 | + String accessToken2 = Arrays.stream( |
| 1159 | + new String[]{"header2", "payload2", "signature2"}) |
| 1160 | + .map(s -> Base64.getEncoder().encodeToString(s.getBytes(StandardCharsets.UTF_8))) |
| 1161 | + .reduce((s1, s2) -> s1 + "." + s2).get(); |
| 1162 | + |
| 1163 | + mockServer.resetAll(); |
| 1164 | + mockServer.addStubMapping(WireMock.post(WireMock.anyUrl()) |
| 1165 | + .withHeader("Authorization", WireMock.equalTo(accessToken1)) |
| 1166 | + .willReturn(WireMock.aResponse() |
| 1167 | + .withStatus(HttpStatus.SC_UNAUTHORIZED)) |
| 1168 | + .build()); |
| 1169 | + |
| 1170 | + try (Client client = new Client.Builder().addEndpoint(Protocol.HTTP, "localhost", mockServer.port(), false) |
| 1171 | + .setAccessToken(accessToken1) |
| 1172 | + .compressServerResponse(false) |
| 1173 | + .build()) { |
| 1174 | + |
| 1175 | + try { |
| 1176 | + client.execute("SELECT 1").get(); |
| 1177 | + fail("Exception expected"); |
| 1178 | + } catch (ServerException e) { |
| 1179 | + Assert.assertEquals(e.getTransportProtocolCode(), HttpStatus.SC_UNAUTHORIZED); |
| 1180 | + } |
| 1181 | + |
| 1182 | + mockServer.resetAll(); |
| 1183 | + mockServer.addStubMapping(WireMock.post(WireMock.anyUrl()) |
| 1184 | + .withHeader("Authorization", WireMock.equalTo(accessToken2)) |
| 1185 | + .willReturn(WireMock.aResponse() |
| 1186 | + .withHeader("X-ClickHouse-Summary", |
| 1187 | + "{ \"read_bytes\": \"10\", \"read_rows\": \"1\"}")) |
| 1188 | + |
| 1189 | + .build()); |
| 1190 | + |
| 1191 | + client.updateAccessToken(accessToken2); |
1112 | 1192 | client.execute("SELECT 1").get(); |
| 1193 | + |
| 1194 | + Assert.expectThrows(ValidationUtils.SettingsValidationException.class, () -> client.updateAccessToken(null)); |
| 1195 | + Assert.expectThrows(ValidationUtils.SettingsValidationException.class, () -> client.updateAccessToken("")); |
1113 | 1196 | } |
1114 | 1197 | } finally { |
1115 | 1198 | mockServer.stop(); |
1116 | 1199 | } |
1117 | 1200 | } |
1118 | 1201 |
|
| 1202 | + |
1119 | 1203 | @Test(groups = { "integration" }) |
1120 | 1204 | public void testUpdateSessionIdAtRuntime() throws Exception { |
1121 | 1205 | if (isCloud()) { |
|
0 commit comments