diff --git a/elasticsearch/src/main/java/org/apache/calcite/adapter/elasticsearch/ElasticsearchSchemaFactory.java b/elasticsearch/src/main/java/org/apache/calcite/adapter/elasticsearch/ElasticsearchSchemaFactory.java index b36ca1aa648..aeaec2fa0ff 100644 --- a/elasticsearch/src/main/java/org/apache/calcite/adapter/elasticsearch/ElasticsearchSchemaFactory.java +++ b/elasticsearch/src/main/java/org/apache/calcite/adapter/elasticsearch/ElasticsearchSchemaFactory.java @@ -45,6 +45,7 @@ import java.io.IOException; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; +import java.util.Comparator; import java.util.List; import java.util.Locale; import java.util.Map; @@ -159,6 +160,8 @@ public ElasticsearchSchemaFactory() { throw new IllegalArgumentException ("Both 'coordinates' and 'hosts' is missing in configuration. Provide one of them."); } + List sortedHost = getSortedHost(hosts); + final String pathPrefix = (String) map.get("pathPrefix"); // Enable or Disable SSL Verification @@ -174,7 +177,7 @@ public ElasticsearchSchemaFactory() { String username = (String) map.get("username"); String password = (String) map.get("password"); final RestClient client = - connect(hosts, pathPrefix, username, password, disableSSLVerification); + connect(sortedHost, pathPrefix, username, password, disableSSLVerification); final String index = (String) map.get("index"); return new ElasticsearchSchema(client, new ObjectMapper(), index); @@ -183,6 +186,15 @@ public ElasticsearchSchemaFactory() { } } + protected static List getSortedHost(List hosts) { + List sortedHosts = + hosts + .stream() + .sorted(Comparator.comparing(HttpHost::toString, String::compareTo)) + .collect(Collectors.toList()); + return sortedHosts; + } + /** * Builds Elastic rest client from user configuration. * diff --git a/elasticsearch/src/test/java/org/apache/calcite/adapter/elasticsearch/ElasticSearchAdapterTest.java b/elasticsearch/src/test/java/org/apache/calcite/adapter/elasticsearch/ElasticSearchAdapterTest.java index fb18e5b9fa4..578e0e7d634 100644 --- a/elasticsearch/src/test/java/org/apache/calcite/adapter/elasticsearch/ElasticSearchAdapterTest.java +++ b/elasticsearch/src/test/java/org/apache/calcite/adapter/elasticsearch/ElasticSearchAdapterTest.java @@ -26,6 +26,8 @@ import org.apache.calcite.util.Bug; import org.apache.calcite.util.TestUtil; +import org.apache.http.HttpHost; + import com.fasterxml.jackson.databind.node.ObjectNode; import com.google.common.collect.ImmutableMap; import com.google.common.io.LineProcessor; @@ -53,6 +55,7 @@ import java.util.Map; import java.util.function.Consumer; +import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static java.util.Objects.requireNonNull; @@ -771,4 +774,21 @@ private static Consumer sortedResultSetChecker(String column, "state=AR; EXPR$1=3; EXPR$2=3"); } + /** + * Test case for + * [CALCITE-6725] + * The caching mechanism key in ElasticsearchSchemaFactory is affected by the order of hosts. + */ + @Test void testSortHosts() { + HttpHost host1 = HttpHost.create("192.168.1.200:8080"); + HttpHost host2 = HttpHost.create("192.168.1.100:8080"); + HttpHost host3 = HttpHost.create("192.168.1.150:8080"); + List hosts = Arrays.asList(host1, host2, host3); + List sortedHosts = ElasticsearchSchemaFactory.getSortedHost(hosts); + assertEquals(3, sortedHosts.size()); + assertEquals("http://192.168.1.100:8080", sortedHosts.get(0).toString()); + assertEquals("http://192.168.1.150:8080", sortedHosts.get(1).toString()); + assertEquals("http://192.168.1.200:8080", sortedHosts.get(2).toString()); + } + }