ElasticsearchClient API says Name does not resolve

I am converting my existing Java code to the new Elastic Java API. My system is ES 7.17.9. When I send a query, I get the following error:

2023-06-08 20:58:00.918Z ERROR [ForkJoinPool.commonPool-worker-9] c.n.b.a.h.c.ElasticsearchHealthCheck - Elasticsearch: failed: java.net.UnknownHostException: https://aln-nbadev4.labs.server.com:9200: Name does not resolve message: https://aln-nbadev4.labs.server.com:9200: Name does not resolve
[org.elasticsearch.client.RestClient.extractAndWrapCause(RestClient.java:937), org.elasticsearch.client.RestClient.performRequest(RestClient.java:300), org.elasticsearch.client.RestClient.performRequest(RestClient.java:288), co.elastic.clients.transport.rest_client.RestClientTransport.performRequest(RestClientTransport.java:152), co.elastic.clients.elasticsearch.ElasticsearchClient.search(ElasticsearchClient.java:1754), co.elastic.clients.elasticsearch.ElasticsearchClient.search(ElasticsearchClient.java:1771), com.server.bda.admintools.health.checks.ElasticsearchHealthCheck.fetchESResultsWithMustQuery(ElasticsearchHealthCheck.java:92), com.server.bda.admintools.health.checks.ElasticsearchHealthCheck.searchFilebeat(ElasticsearchHealthCheck.java:62), com.server.bda.admintools.health.checks.CollectionLoadTimeHealthCheck.lambda$execute$0(CollectionLoadTimeHealthCheck.java:50), java.base/java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java:1768), java.base/java.util.concurrent.CompletableFuture$AsyncSupply.exec(CompletableFuture.java:1760), java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:373), java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1182), java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1655), java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1622), java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:165)]

I have no problems pinging my Elasticsearch server:

[root@aln-nbadev4 admin-tools]# ping aln-nbadev4.labs.server.com
PING aln-nbadev4.labs.server.com (172.20.133.11) 56(84) bytes of data.
64 bytes from aln-nbadev4.labs.server.com (172.20.133.11): icmp_seq=1 ttl=64 time=0.032 ms
64 bytes from aln-nbadev4.labs.server.com (172.20.133.11): icmp_seq=2 ttl=64 time=0.030 ms

Does this mean that I am not connected to the Elasticsearch server?

My search code:

    public List<ESResult> fetchESResultsWithMustQuery(String index, List<Query> queryEntries) throws IOException {

        SearchResponse<ESResult> searchResponse = null;
        try {
            searchResponse = client.search(s ->
                    s.index(index).query(query-> query.bool(bool -> bool.must(queryEntries))),ESResult.class);
        } catch (Exception ex) {
            log.error("Elasticsearch: failed: {} message: {} \n{}", ex.getCause(), ex.getMessage(), ex.getStackTrace());
        }

        return searchResponse.hits().hits().stream().map(Hit::source).collect(Collectors.toList());

    }

My connection code:

        final HttpHost[] hosts = stream(host.split(",")).map(String::trim).map(HttpHost::create).toArray(HttpHost[]::new);
        final boolean hasCredentials = !isNullOrEmpty(esUser) && !isNullOrEmpty(esPass);
        if (!hasCredentials) {
            log.error("Must have credentials to start Elasticsearch!");
            return null;
        }
        final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
        credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(esUser, esPass));
        log.info ("Elasticsearch: hosts: {}", hosts);

        RestClientBuilder builder = RestClient.builder(new HttpHost(hosts[0].toString()))
                .setHttpClientConfigCallback(httpClientBuilder ->
                        httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider));


        // Create the low-level client
        RestClient restClient = builder.build();
        log.info("Elasticsearch: restClient: {}", restClient.getHttpClient().toString());

        // Create the transport with a jackson mapper
        ElasticsearchTransport transport = new RestClientTransport(
                restClient, new JacksonJsonpMapper());
        log.info("Elasticsearch: transport: {}", transport);

        // Now create the API client
        ElasticsearchClient esClient = new ElasticsearchClient(transport);
        log.info("Elasticsearch: esClient: {}", esClient);
2023-06-08 20:17:21.869Z INFO  [main] c.n.b.a.config.ElasticSearchConfig - Elasticsearch: hosts: https://aln-nbadev4.labs.server.com:9200
2023-06-08 20:17:21.870Z INFO  [main] c.n.b.a.config.ElasticSearchConfig - Elasticsearch: restClient: org.apache.http.impl.nio.client.InternalHttpAsyncClient@e97f115
2023-06-08 20:17:21.890Z INFO  [main] c.n.b.a.config.ElasticSearchConfig - Elasticsearch: transport: co.elastic.clients.transport.rest_client.RestClientTransport@6113a26f
2023-06-08 20:17:21.891Z INFO  [main] c.n.b.a.config.ElasticSearchConfig - Elasticsearch: esClient: co.elastic.clients.elasticsearch.ElasticsearchClient@2aac8ad7

Why this?

Instead you can write something like:

RestClientBuilder builder = RestClient.builder(hosts[0])

Or if you want to use the String version, use HttpHost.create(String)

RestClientBuilder builder = RestClient.builder(HttpHost.create(hosts[0].toString()))

Upgrade to 7.17 please. I'm not sure if the client works with this old not maintained version of Elasticsearch. And anyway, it's much safer for you to use the latest 7 version...

The .toString() was just an experiment to see if it would affect the issue. I've tried with and without it and get the same results.

Upgrade to 7.17 please. I'm not sure if the client works with this old not maintained version of Elasticsearch. And anyway, it's much safer for you to use the latest 7 version...

My version 7.17.9 was released in February. There has only been one patch since then. I'm working on converting to the ElasticClient so that I can upgrade to version 8.x in the next few weeks.

Is there a function call that I can do to test my connection? There definitely isn't a problem with my Elasticsearch/Kibana installation because it works just fine using the old RestHighLevelClient or sending commands via Postman.

The RestHighLevelClient and the Java API client use the exact same http layer which is RestClient.

In migration scenarios from HLRC to Java API, we recommend using the same RestClient instance for both clients.

Are you using the same RestClient instance? If not, is there a difference in the way the RestClient is created for the RestHighLevelClient and the way it is created for the Java API client?

Sorry. I misread and thought it was 7.9...

Since we will be going to version 8.x soon, I'm trying to go directly to the Java API and eliminate the RestHighLevelClient.

Reading again the error message, it says java.net.UnknownHostException: https://aln-nbadev4.labs.server.com:9200. The JVM is trying to resolve the entire URL as if it was a host name.

This comes from this expression: RestClient.builder(new HttpHost(hosts[0].toString())).

hosts[0] is already a HttpHost that has been parsed correctly using the first line of the code snippet.

So new HttpHost(hosts[0].toString()) transforms this HttpHost into its URL (using toString()) and then calls the HttpHost constructor that expects a host name as an argument.

That expression should be (also allowing several hosts) RestClient.builder(hosts)

Here's a test that shows this:

@Test
public void hostTest() {
    String host = "https://aln-nbadev4.labs.server.com:9200";
    final HttpHost[] hosts = Arrays.stream(host.split(",")).map(String::trim).map(HttpHost::create).toArray(HttpHost[]::new);

    HttpHost host0 = hosts[0];
    assertEquals("aln-nbadev4.labs.server.com", host0.getHostName());
    assertEquals("https", host0.getSchemeName());
    assertEquals(9200, host0.getPort());

    HttpHost host1 = new HttpHost(host0.toString());
    assertEquals("https://aln-nbadev4.labs.server.com:9200", host1.getHostName());
    assertEquals("http", host1.getSchemeName());
    assertEquals(-1, host1.getPort());
}
1 Like

Those tests were a good suggestion. I added them to my code and they confirmed that the hosts value was correct. I guess that some of my troubleshooting yesterday worked, because when I build and run today, instead of getting "name does not resolve", I get an authentication error. So that tells me that I'm at least attempting to connect. I need to work on that issue for a while before I ask for help on it.

Thanks.

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.