Elasticsearch: Java High Level Rest Client

Image by Gerd Altmann from Pixabay

This article describe how to configure the new Elasticsearch Java High level rest client in a Java Application.

Introduction

Elasticsearch 5.0.0 released it first Java REST Client. This client was called low-level client as the Java users had to build the JSON request and parse the results. Later, Elasticsearch 5.6 introduced  Java High Level REST Client which accepts request objects and returns response objects for the most important APIs(info, get, index, delete, update, bulk, search, search-scroll, and clear-scroll). For other APIs, we still have to use the low-level client.

Dependencies

It depends of the following artifacts and their transitive dependencies:

  • org.elasticsearch.client:elasticsearch-rest-client
  • org.elasticsearch:elasticsearch

The minimum Java version required is 1.8

If you are using maven then it can declared as follows

<dependency>
    <groupId>org.elasticsearch.client</groupId>
    <artifactId>elasticsearch-rest-high-level-client</artifactId>
    <version>${elasticsearch.version}</version>
</dependency>

The Gradle users can declare the dependencies as

dependencies {
    compile "org.elasticsearch.client:elasticsearch-rest-high-level-client:${elasticsearch.version}"
}  

Replace the ${elasticsearch.version} as appropriate.

Initialization

The RestHighLevelClient is built on top of the REST low-level client builder. The following code will instantiate a low level RestClientBuilder.

RestClientBuilder  restClientBuilder  = RestClient.builder(
    new HttpHost("localhost", 9200, "http"),
    new HttpHost("localhost", 9201, "http"));

If the Elasticsearch is secured with user name and password then we need to provide the credentials using the CredentialsProvider as shown below. After that we can set a callback that allows to modify the http client configuration. 

final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(
        <elasticSearchUsername>, <elasticSearchPassword>));
restClientBuilder.setHttpClientConfigCallback(new HttpClientConfigCallback() {
      @Override
      public HttpAsyncClientBuilder customizeHttpClient(
          HttpAsyncClientBuilder httpClientBuilder) {
        return httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
      }
    });
/*
Using the Java 8 syntax, we can replace the above code like this
builder.setHttpClientConfigCallback(
        httpClientBuilder -> httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider));
*/

After this we can initialize the RestHighLevelClient as follows

RestHighLevelClient client = new RestHighLevelClient(restClientBuilder);

Usage

Each APIs in High Level REST Client can be called synchronously or asynchronously. In case of synchronous call it returns a response object. It can throw an IOException if either of the following occurs:

  • The request times out.
  • The client fails to parse the REST response
  • There is no response coming back from the server
SearchRequest searchRequest = new SearchRequest("posts");
searchRequest.source(searchSourceBuilder);
SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);  

The following shows how to call a method asynchronously. We need to define an ActionListener which define how to handle the response and error if any. The following shows the code example for that:

// Asynchronous call example
ActionListener<SearchResponse> listener = new ActionListener<SearchResponse>() {
    @Override
    public void onResponse(SearchResponse searchResponse) {
         //write the logic to parse the search response. 
    }

    @Override
    public void onFailure(Exception e) {
        //Code to handle the exception goes here.
    }
};
client.searchAsync(searchRequest, RequestOptions.DEFAULT, listener);

Once we are done with the processing, the client can closed as follows:

client.close();

A working code example is present in this git repository.

References

  • https://github.com/ahmadimt/elasticsearch_samples/tree/main/high_level_rest_client
  • https://www.elastic.co/blog/state-of-the-official-elasticsearch-java-clients
  • https://www.elastic.co/guide/en/elasticsearch/client/java-rest/master/java-rest-high.html
  • https://www.elastic.co/guide/en/elasticsearch/client/java-rest/master/java-rest-low.html
  • https://pixabay.com/illustrations/ball-round-cable-lan-connected-563972/

The classic TransportClient is deprecated in Elasticsearch 7.0 and will be removed in version 8.0.

Comments