[client] Handle non-default port in Cloud-Id (#61634)

The domain part of a Cloud-Id can contain an optional custom port, e.g.
cloud.example.org:9443. This feature is used for Elastic Cloud
Enterprise installations that can't use the default port 443.

This change fixes RestClient.build() to correctly handle custom ports.
This commit is contained in:
Sylvain Wallez 2020-08-27 17:51:12 +02:00 committed by GitHub
parent 5a83e89a2b
commit 05aaa2efdc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 45 additions and 3 deletions

View File

@ -142,14 +142,30 @@ public class RestClient implements Closeable {
}
String decoded = new String(Base64.getDecoder().decode(cloudId), UTF_8);
// once decoded the parts are separated by a $ character
// once decoded the parts are separated by a $ character.
// they are respectively domain name and optional port, elasticsearch id, kibana id
String[] decodedParts = decoded.split("\\$");
if (decodedParts.length != 3) {
throw new IllegalStateException("cloudId " + cloudId + " did not decode to a cluster identifier correctly");
}
String url = decodedParts[1] + "." + decodedParts[0];
return builder(new HttpHost(url, 443, "https"));
// domain name and optional port
String[] domainAndMaybePort = decodedParts[0].split(":", 2);
String domain = domainAndMaybePort[0];
int port;
if (domainAndMaybePort.length == 2) {
try {
port = Integer.parseInt(domainAndMaybePort[1]);
} catch (NumberFormatException nfe) {
throw new IllegalStateException("cloudId " + cloudId + " does not contain a valid port number");
}
} else {
port = 443;
}
String url = decodedParts[1] + "." + domain;
return builder(new HttpHost(url, port, "https"));
}
/**

View File

@ -193,6 +193,32 @@ public class RestClientBuilderTests extends RestClientTestCase {
client.close();
}
public void testBuildCloudIdWithPort() throws IOException {
String host = "us-east-1.aws.found.io";
String esId = "elasticsearch";
String kibanaId = "kibana";
String port = "9443";
String toEncode = host + ":" + port + "$" + esId + "$" + kibanaId;
String encodedId = Base64.getEncoder().encodeToString(toEncode.getBytes(UTF8));
RestClient client = RestClient.builder("humanReadable:" + encodedId).build();
assertThat(client.getNodes().size(), equalTo(1));
assertThat(client.getNodes().get(0).getHost().getPort(), equalTo(9443));
assertThat(client.getNodes().get(0).getHost().getHostName(), equalTo(esId + "." + host));
assertThat(client.getNodes().get(0).getHost().getSchemeName(), equalTo("https"));
client.close();
toEncode = host + ":" + "123:foo" + "$" + esId + "$" + kibanaId;
encodedId = Base64.getEncoder().encodeToString(toEncode.getBytes(UTF8));
try {
RestClient.builder("humanReadable:" + encodedId);
fail("should have failed");
} catch (IllegalStateException e) {
assertEquals("cloudId " + encodedId + " does not contain a valid port number", e.getMessage());
}
}
public void testSetPathPrefixNull() {
try {
RestClient.builder(new HttpHost("localhost", 9200)).setPathPrefix(null);