Skip to content

Commit

Permalink
[client] Handle non-default port in Cloud-Id (#61581)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
swallez authored Aug 27, 2020
1 parent c291b6d commit 648ac53
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 3 deletions.
22 changes: 19 additions & 3 deletions client/rest/src/main/java/org/elasticsearch/client/RestClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -142,14 +142,30 @@ public static RestClientBuilder builder(String cloudId) {
}

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"));
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,32 @@ public void testBuildCloudId() throws IOException {
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);
Expand Down

0 comments on commit 648ac53

Please sign in to comment.