For the latest stable version, please use Spring Data Elasticsearch 5.4.0! |
Elasticsearch Clients
This chapter illustrates configuration and usage of supported Elasticsearch client implementations.
Spring Data Elasticsearch operates upon an Elasticsearch client (provided by Elasticsearch client libraries) that is connected to a single Elasticsearch node or a cluster. Although the Elasticsearch Client can be used directly to work with the cluster, applications using Spring Data Elasticsearch normally use the higher level abstractions of Elasticsearch Operations and Elasticsearch Repositories.
Imperative Rest Client
To use the imperative (non-reactive) client, a configuration bean must be configured like this:
import org.springframework.data.elasticsearch.client.elc.ElasticsearchConfiguration;
@Configuration
public class MyClientConfig extends ElasticsearchConfiguration {
@Override
public ClientConfiguration clientConfiguration() {
return ClientConfiguration.builder() (1)
.connectedTo("localhost:9200")
.build();
}
}
1 | for a detailed description of the builder methods see Client Configuration |
The ElasticsearchConfiguration
] class allows further configuration by overriding for example the jsonpMapper()
or transportOptions()
methods.
The following beans can then be injected in other Spring components:
import org.springframework.beans.factory.annotation.Autowired;@Autowired
ElasticsearchOperations operations; (1)
@Autowired
ElasticsearchClient elasticsearchClient; (2)
@Autowired
RestClient restClient; (3)
@Autowired
JsonpMapper jsonpMapper; (4)
1 | an implementation of ElasticsearchOperations |
2 | the co.elastic.clients.elasticsearch.ElasticsearchClient that is used. |
3 | the low level RestClient from the Elasticsearch libraries |
4 | the JsonpMapper user by the Elasticsearch Transport |
Basically one should just use the ElasticsearchOperations
to interact with the Elasticsearch cluster.
When using repositories, this instance is used under the hood as well.
Reactive Rest Client
When working with the reactive stack, the configuration must be derived from a different class:
import org.springframework.data.elasticsearch.client.elc.ReactiveElasticsearchConfiguration;
@Configuration
public class MyClientConfig extends ReactiveElasticsearchConfiguration {
@Override
public ClientConfiguration clientConfiguration() {
return ClientConfiguration.builder() (1)
.connectedTo("localhost:9200")
.build();
}
}
1 | for a detailed description of the builder methods see Client Configuration |
The ReactiveElasticsearchConfiguration
class allows further configuration by overriding for example the jsonpMapper()
or transportOptions()
methods.
The following beans can then be injected in other Spring components:
@Autowired
ReactiveElasticsearchOperations operations; (1)
@Autowired
ReactiveElasticsearchClient elasticsearchClient; (2)
@Autowired
RestClient restClient; (3)
@Autowired
JsonpMapper jsonpMapper; (4)
the following can be injected:
1 | an implementation of ReactiveElasticsearchOperations |
2 | the org.springframework.data.elasticsearch.client.elc.ReactiveElasticsearchClient that is used.
This is a reactive implementation based on the Elasticsearch client implementation. |
3 | the low level RestClient from the Elasticsearch libraries |
4 | the JsonpMapper user by the Elasticsearch Transport |
Basically one should just use the ReactiveElasticsearchOperations
to interact with the Elasticsearch cluster.
When using repositories, this instance is used under the hood as well.
Client Configuration
Client behaviour can be changed via the ClientConfiguration
that allows to set options for SSL, connect and socket timeouts, headers and other parameters.
import org.springframework.data.elasticsearch.client.ClientConfiguration;
import org.springframework.data.elasticsearch.support.HttpHeaders;
import static org.springframework.data.elasticsearch.client.elc.ElasticsearchClients.*;
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.add("some-header", "on every request") (1)
ClientConfiguration clientConfiguration = ClientConfiguration.builder()
.connectedTo("localhost:9200", "localhost:9291") (2)
.usingSsl() (3)
.withProxy("localhost:8888") (4)
.withPathPrefix("ela") (5)
.withConnectTimeout(Duration.ofSeconds(5)) (6)
.withSocketTimeout(Duration.ofSeconds(3)) (7)
.withDefaultHeaders(defaultHeaders) (8)
.withBasicAuth(username, password) (9)
.withHeaders(() -> { (10)
HttpHeaders headers = new HttpHeaders();
headers.add("currentTime", LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));
return headers;
})
.withClientConfigurer( (11)
ElasticsearchHttpClientConfigurationCallback.from(clientBuilder -> {
// ...
return clientBuilder;
}))
. // ... other options
.build();
1 | Define default headers, if they need to be customized |
2 | Use the builder to provide cluster addresses, set default HttpHeaders or enable SSL. |
3 | Optionally enable SSL.There exist overloads of this function that can take a SSLContext or as an alternative the fingerprint of the certificate as it is output by Elasticsearch 8 on startup. |
4 | Optionally set a proxy. |
5 | Optionally set a path prefix, mostly used when different clusters a behind some reverse proxy. |
6 | Set the connection timeout. |
7 | Set the socket timeout. |
8 | Optionally set headers. |
9 | Add basic authentication. |
10 | A Supplier<HttpHeaders> function can be specified which is called every time before a request is sent to Elasticsearch - here, as an example, the current time is written in a header. |
11 | a function to configure the created client (see Client configuration callbacks), can be added multiple times. |
Adding a Header supplier as shown in above example allows to inject headers that may change over the time, like authentication JWT tokens. If this is used in the reactive setup, the supplier function must not block! |
Client configuration callbacks
The ClientConfiguration
class offers the most common parameters to configure the client.
In the case this is not enough, the user can add callback functions by using the withClientConfigurer(ClientConfigurationCallback<?>)
method.
The following callbacks are provided:
Configuration of the low level Elasticsearch RestClient
:
This callback provides a org.elasticsearch.client.RestClientBuilder
that can be used to configure the Elasticsearch
RestClient
:
ClientConfiguration.builder()
.connectedTo("localhost:9200", "localhost:9291")
.withClientConfigurer(ElasticsearchClients.ElasticsearchRestClientConfigurationCallback.from(restClientBuilder -> {
// configure the Elasticsearch RestClient
return restClientBuilder;
}))
.build();
Configuration of the HttpAsyncClient used by the low level Elasticsearch RestClient
:
This callback provides a org.apache.http.impl.nio.client.HttpAsyncClientBuilder
to configure the HttpCLient that is
used by the RestClient
.
ClientConfiguration.builder()
.connectedTo("localhost:9200", "localhost:9291")
.withClientConfigurer(ElasticsearchClients.ElasticsearchHttpClientConfigurationCallback.from(httpAsyncClientBuilder -> {
// configure the HttpAsyncClient
return httpAsyncClientBuilder;
}))
.build();
Client Logging
To see what is actually sent to and received from the server Request
/ Response
logging on the transport level needs to be turned on as outlined in the snippet below.
This can be enabled in the Elasticsearch client by setting the level of the tracer
package to "trace" (see
www.elastic.co/guide/en/elasticsearch/client/java-api-client/current/java-rest-low-usage-logging.html)
<logger name="tracer" level="trace"/>