mirror of
https://github.com/spring-projects/spring-data-elasticsearch.git
synced 2025-06-22 03:52:10 +00:00
Refine the configuration callbacks in the ClientConfiguration.
Original Pull Request #2237 Closes #2149
This commit is contained in:
parent
373be49f97
commit
1c31a31e11
@ -38,16 +38,17 @@ ElasticsearchClient elasticsearchClient; <.>
|
|||||||
@Autowired
|
@Autowired
|
||||||
RestClient restClient; <.>
|
RestClient restClient; <.>
|
||||||
----
|
----
|
||||||
|
|
||||||
the following can be injected:
|
the following can be injected:
|
||||||
|
|
||||||
<.> an implementation of `ElasticsearchOperations`
|
<.> an implementation of `ElasticsearchOperations`
|
||||||
<.> the `co.elastic.clients.elasticsearch.ElasticsearchClient` that is used. This is new Elasticsearch client
|
<.> the `co.elastic.clients.elasticsearch.ElasticsearchClient` that is used.
|
||||||
implementation.
|
This is new Elasticsearch client implementation.
|
||||||
<.> the low level `RestClient` from the Elasticsearch libraries
|
<.> the low level `RestClient` from the Elasticsearch libraries
|
||||||
====
|
====
|
||||||
|
|
||||||
Basically one should just use the `ElasticsearchOperations` to interact with the Elasticsearch cluster. When using
|
Basically one should just use the `ElasticsearchOperations` to interact with the Elasticsearch cluster.
|
||||||
repositories, this instance is used under the hood as well.
|
When using repositories, this instance is used under the hood as well.
|
||||||
|
|
||||||
[[elasticsearch.clients.reactiverestclient]]
|
[[elasticsearch.clients.reactiverestclient]]
|
||||||
== Reactive Rest Client
|
== Reactive Rest Client
|
||||||
@ -81,16 +82,17 @@ ReactiveElasticsearchClient elasticsearchClient; <.>
|
|||||||
@Autowired
|
@Autowired
|
||||||
RestClient restClient; <.>
|
RestClient restClient; <.>
|
||||||
----
|
----
|
||||||
|
|
||||||
the following can be injected:
|
the following can be injected:
|
||||||
|
|
||||||
<.> an implementation of `ElasticsearchOperations`
|
<.> an implementation of `ElasticsearchOperations`
|
||||||
<.> the `org.springframework.data.elasticsearch.client.elc.ReactiveElasticsearchClient` that is used. This is based
|
<.> the `org.springframework.data.elasticsearch.client.elc.ReactiveElasticsearchClient` that is used.
|
||||||
on the new Elasticsearch client implementation.
|
This is based on the new Elasticsearch client implementation.
|
||||||
<.> the low level `RestClient` from the Elasticsearch libraries
|
<.> the low level `RestClient` from the Elasticsearch libraries
|
||||||
====
|
====
|
||||||
|
|
||||||
Basically one should just use the `ReactiveElasticsearchOperations` to interact with the Elasticsearch cluster. When
|
Basically one should just use the `ReactiveElasticsearchOperations` to interact with the Elasticsearch cluster.
|
||||||
using repositories, this instance is used under the hood as well.
|
When using repositories, this instance is used under the hood as well.
|
||||||
|
|
||||||
[[elasticsearch.clients.resthighlevelclient]]
|
[[elasticsearch.clients.resthighlevelclient]]
|
||||||
== High Level REST Client (deprecated)
|
== High Level REST Client (deprecated)
|
||||||
@ -231,12 +233,49 @@ Default is 5 sec.
|
|||||||
<.> Optionally set headers.
|
<.> Optionally set headers.
|
||||||
<.> Add basic authentication.
|
<.> Add basic authentication.
|
||||||
<.> A `Supplier<Header>` 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.
|
<.> A `Supplier<Header>` 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.
|
||||||
<.> a function configuring the low level REST client (the same for the imperative and reactive stack)
|
<.> a function to configure the created client (see <<elasticsearch.clients.configuration.callbacks>>), can be added multiple times.
|
||||||
====
|
====
|
||||||
|
|
||||||
IMPORTANT: Adding a Header supplier as shown in above example allows to inject headers that may change over the time, like authentication JWT tokens.
|
IMPORTANT: 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!
|
If this is used in the reactive setup, the supplier function *must not* block!
|
||||||
|
|
||||||
|
[[elasticsearch.clients.configuration.callbacks]]
|
||||||
|
=== 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`:
|
||||||
|
|
||||||
|
====
|
||||||
|
[source,java]
|
||||||
|
----
|
||||||
|
ClientConfiguration.builder()
|
||||||
|
.withClientConfigurer(ElasticsearchClients.ElasticsearchRestClientConfigurationCallback.from(restClientBuilder -> {
|
||||||
|
// configure the Elasticsearch RestClient
|
||||||
|
return restClientBuilder;
|
||||||
|
}))
|
||||||
|
.build();
|
||||||
|
----
|
||||||
|
====
|
||||||
|
|
||||||
|
==== Configuration of the HttpAsyncClient used by the low level Elasticsearch `RestClient`:
|
||||||
|
|
||||||
|
====
|
||||||
|
[source,java]
|
||||||
|
----
|
||||||
|
ClientConfiguration.builder()
|
||||||
|
.withClientConfigurer(ElasticsearchClients.ElasticsearchHttpClientConfigurationCallback.from(httpAsyncClientBuilder -> {
|
||||||
|
// configure the HttpAsyncClient
|
||||||
|
return httpAsyncClientBuilder;
|
||||||
|
}))
|
||||||
|
.build();
|
||||||
|
----
|
||||||
|
====
|
||||||
|
|
||||||
|
|
||||||
=== Elasticsearch 7 compatibility headers
|
=== Elasticsearch 7 compatibility headers
|
||||||
|
|
||||||
When using the deprecated `RestHighLevelClient` and accessing an Elasticsearch cluster that is running on version 8, it is necessary to set the compatibility headers
|
When using the deprecated `RestHighLevelClient` and accessing an Elasticsearch cluster that is running on version 8, it is necessary to set the compatibility headers
|
||||||
|
@ -56,7 +56,6 @@ import org.springframework.http.HttpHeaders;
|
|||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.lang.Nullable;
|
import org.springframework.lang.Nullable;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
import org.springframework.web.reactive.function.client.WebClient;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utility class to create the different Elasticsearch clients
|
* Utility class to create the different Elasticsearch clients
|
||||||
@ -229,14 +228,20 @@ public final class ElasticsearchClients {
|
|||||||
|
|
||||||
for (ClientConfiguration.ClientConfigurationCallback<?> clientConfigurer : clientConfiguration
|
for (ClientConfiguration.ClientConfigurationCallback<?> clientConfigurer : clientConfiguration
|
||||||
.getClientConfigurers()) {
|
.getClientConfigurers()) {
|
||||||
if (clientConfigurer instanceof ElasticsearchClientConfigurationCallback) {
|
if (clientConfigurer instanceof ElasticsearchHttpClientConfigurationCallback restClientConfigurationCallback) {
|
||||||
ElasticsearchClientConfigurationCallback restClientConfigurationCallback = (ElasticsearchClientConfigurationCallback) clientConfigurer;
|
|
||||||
clientBuilder = restClientConfigurationCallback.configure(clientBuilder);
|
clientBuilder = restClientConfigurationCallback.configure(clientBuilder);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return clientBuilder;
|
return clientBuilder;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
for (ClientConfiguration.ClientConfigurationCallback<?> clientConfigurationCallback : clientConfiguration
|
||||||
|
.getClientConfigurers()) {
|
||||||
|
if (clientConfigurationCallback instanceof ElasticsearchRestClientConfigurationCallback configurationCallback) {
|
||||||
|
builder = configurationCallback.configure(builder);
|
||||||
|
}
|
||||||
|
}
|
||||||
return builder;
|
return builder;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -360,37 +365,39 @@ public final class ElasticsearchClients {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link org.springframework.data.elasticsearch.client.ClientConfiguration.ClientConfigurationCallback} to configure
|
* {@link org.springframework.data.elasticsearch.client.ClientConfiguration.ClientConfigurationCallback} to configure
|
||||||
* the RestClient with a {@link HttpAsyncClientBuilder}
|
* the Elasticsearch RestClient's Http client with a {@link HttpAsyncClientBuilder}
|
||||||
*
|
*
|
||||||
* @since 4.4
|
* @since 4.4
|
||||||
*/
|
*/
|
||||||
public interface ElasticsearchClientConfigurationCallback
|
public interface ElasticsearchHttpClientConfigurationCallback
|
||||||
extends ClientConfiguration.ClientConfigurationCallback<HttpAsyncClientBuilder> {
|
extends ClientConfiguration.ClientConfigurationCallback<HttpAsyncClientBuilder> {
|
||||||
|
|
||||||
static ElasticsearchClientConfigurationCallback from(
|
static ElasticsearchHttpClientConfigurationCallback from(
|
||||||
Function<HttpAsyncClientBuilder, HttpAsyncClientBuilder> clientBuilderCallback) {
|
Function<HttpAsyncClientBuilder, HttpAsyncClientBuilder> httpClientBuilderCallback) {
|
||||||
|
|
||||||
Assert.notNull(clientBuilderCallback, "clientBuilderCallback must not be null");
|
Assert.notNull(httpClientBuilderCallback, "httpClientBuilderCallback must not be null");
|
||||||
|
|
||||||
// noinspection NullableProblems
|
// noinspection NullableProblems
|
||||||
return clientBuilderCallback::apply;
|
return httpClientBuilderCallback::apply;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link org.springframework.data.elasticsearch.client.ClientConfiguration.ClientConfigurationCallback} to configure
|
* {@link org.springframework.data.elasticsearch.client.ClientConfiguration.ClientConfigurationCallback} to configure
|
||||||
* the ReactiveElasticsearchClient with a {@link WebClient}
|
* the RestClient client with a {@link RestClientBuilder}
|
||||||
*
|
*
|
||||||
* @since 4.4
|
* @since 5.0
|
||||||
*/
|
*/
|
||||||
public interface WebClientConfigurationCallback extends ClientConfiguration.ClientConfigurationCallback<WebClient> {
|
public interface ElasticsearchRestClientConfigurationCallback
|
||||||
|
extends ClientConfiguration.ClientConfigurationCallback<RestClientBuilder> {
|
||||||
|
|
||||||
static WebClientConfigurationCallback from(Function<WebClient, WebClient> webClientCallback) {
|
static ElasticsearchRestClientConfigurationCallback from(
|
||||||
|
Function<RestClientBuilder, RestClientBuilder> restClientBuilderCallback) {
|
||||||
|
|
||||||
Assert.notNull(webClientCallback, "webClientCallback must not be null");
|
Assert.notNull(restClientBuilderCallback, "restClientBuilderCallback must not be null");
|
||||||
|
|
||||||
// noinspection NullableProblems
|
// noinspection NullableProblems
|
||||||
return webClientCallback::apply;
|
return restClientBuilderCallback::apply;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -72,7 +72,9 @@ public final class ReactiveRestClients {
|
|||||||
* the ReactiveElasticsearchClient with a {@link WebClient}
|
* the ReactiveElasticsearchClient with a {@link WebClient}
|
||||||
*
|
*
|
||||||
* @since 4.3
|
* @since 4.3
|
||||||
|
* @deprecated
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public interface WebClientConfigurationCallback extends ClientConfiguration.ClientConfigurationCallback<WebClient> {
|
public interface WebClientConfigurationCallback extends ClientConfiguration.ClientConfigurationCallback<WebClient> {
|
||||||
|
|
||||||
static WebClientConfigurationCallback from(Function<WebClient, WebClient> webClientCallback) {
|
static WebClientConfigurationCallback from(Function<WebClient, WebClient> webClientCallback) {
|
||||||
|
@ -252,7 +252,9 @@ public final class RestClients {
|
|||||||
* the RestClient with a {@link HttpAsyncClientBuilder}
|
* the RestClient with a {@link HttpAsyncClientBuilder}
|
||||||
*
|
*
|
||||||
* @since 4.3
|
* @since 4.3
|
||||||
|
* @deprecated since 5.0
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public interface RestClientConfigurationCallback
|
public interface RestClientConfigurationCallback
|
||||||
extends ClientConfiguration.ClientConfigurationCallback<HttpAsyncClientBuilder> {
|
extends ClientConfiguration.ClientConfigurationCallback<HttpAsyncClientBuilder> {
|
||||||
|
|
||||||
|
@ -35,7 +35,6 @@ import java.util.function.Function;
|
|||||||
import javax.net.ssl.SSLContext;
|
import javax.net.ssl.SSLContext;
|
||||||
|
|
||||||
import org.springframework.data.elasticsearch.client.ClientConfiguration;
|
import org.springframework.data.elasticsearch.client.ClientConfiguration;
|
||||||
import org.springframework.data.elasticsearch.client.elc.ElasticsearchClients;
|
|
||||||
import org.springframework.http.HttpHeaders;
|
import org.springframework.http.HttpHeaders;
|
||||||
import org.springframework.http.client.reactive.ClientHttpConnector;
|
import org.springframework.http.client.reactive.ClientHttpConnector;
|
||||||
import org.springframework.http.client.reactive.ReactorClientHttpConnector;
|
import org.springframework.http.client.reactive.ReactorClientHttpConnector;
|
||||||
@ -240,11 +239,6 @@ public interface WebClientProvider {
|
|||||||
ReactiveRestClients.WebClientConfigurationCallback webClientConfigurationCallback = (ReactiveRestClients.WebClientConfigurationCallback) clientConfigurer;
|
ReactiveRestClients.WebClientConfigurationCallback webClientConfigurationCallback = (ReactiveRestClients.WebClientConfigurationCallback) clientConfigurer;
|
||||||
webClient = webClientConfigurationCallback.configure(webClient);
|
webClient = webClientConfigurationCallback.configure(webClient);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (clientConfigurer instanceof ElasticsearchClients.WebClientConfigurationCallback) {
|
|
||||||
ElasticsearchClients.WebClientConfigurationCallback webClientConfigurationCallback = (ElasticsearchClients.WebClientConfigurationCallback) clientConfigurer;
|
|
||||||
webClient = webClientConfigurationCallback.configure(webClient);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return webClient;
|
return webClient;
|
||||||
};
|
};
|
||||||
|
@ -103,7 +103,8 @@ public class RestClientsTest {
|
|||||||
defaultHeaders.add("def2", "def2-1");
|
defaultHeaders.add("def2", "def2-1");
|
||||||
|
|
||||||
AtomicInteger supplierCount = new AtomicInteger(1);
|
AtomicInteger supplierCount = new AtomicInteger(1);
|
||||||
AtomicInteger clientConfigurerCount = new AtomicInteger(0);
|
AtomicInteger httpClientConfigurerCount = new AtomicInteger(0);
|
||||||
|
AtomicInteger restClientConfigurerCount = new AtomicInteger(0);
|
||||||
|
|
||||||
ClientConfigurationBuilder configurationBuilder = new ClientConfigurationBuilder();
|
ClientConfigurationBuilder configurationBuilder = new ClientConfigurationBuilder();
|
||||||
configurationBuilder //
|
configurationBuilder //
|
||||||
@ -120,26 +121,36 @@ public class RestClientsTest {
|
|||||||
if (clientUnderTestFactory instanceof ERHLCUnderTestFactory) {
|
if (clientUnderTestFactory instanceof ERHLCUnderTestFactory) {
|
||||||
configurationBuilder
|
configurationBuilder
|
||||||
.withClientConfigurer(RestClients.RestClientConfigurationCallback.from(httpClientBuilder -> {
|
.withClientConfigurer(RestClients.RestClientConfigurationCallback.from(httpClientBuilder -> {
|
||||||
clientConfigurerCount.incrementAndGet();
|
httpClientConfigurerCount.incrementAndGet();
|
||||||
return httpClientBuilder;
|
return httpClientBuilder;
|
||||||
}));
|
}));
|
||||||
} else if (clientUnderTestFactory instanceof ReactiveERHLCUnderTestFactory) {
|
} else if (clientUnderTestFactory instanceof ReactiveERHLCUnderTestFactory) {
|
||||||
configurationBuilder.withClientConfigurer(ReactiveRestClients.WebClientConfigurationCallback.from(webClient -> {
|
configurationBuilder.withClientConfigurer(ReactiveRestClients.WebClientConfigurationCallback.from(webClient -> {
|
||||||
clientConfigurerCount.incrementAndGet();
|
httpClientConfigurerCount.incrementAndGet();
|
||||||
return webClient;
|
return webClient;
|
||||||
}));
|
}));
|
||||||
} else if (clientUnderTestFactory instanceof ELCUnderTestFactory) {
|
} else if (clientUnderTestFactory instanceof ELCUnderTestFactory) {
|
||||||
configurationBuilder.withClientConfigurer(
|
configurationBuilder.withClientConfigurer(
|
||||||
ElasticsearchClients.ElasticsearchClientConfigurationCallback.from(httpClientBuilder -> {
|
ElasticsearchClients.ElasticsearchHttpClientConfigurationCallback.from(httpClientBuilder -> {
|
||||||
clientConfigurerCount.incrementAndGet();
|
httpClientConfigurerCount.incrementAndGet();
|
||||||
return httpClientBuilder;
|
return httpClientBuilder;
|
||||||
}));
|
}));
|
||||||
|
configurationBuilder.withClientConfigurer(
|
||||||
|
ElasticsearchClients.ElasticsearchRestClientConfigurationCallback.from(restClientBuilder -> {
|
||||||
|
restClientConfigurerCount.incrementAndGet();
|
||||||
|
return restClientBuilder;
|
||||||
|
}));
|
||||||
} else if (clientUnderTestFactory instanceof ReactiveELCUnderTestFactory) {
|
} else if (clientUnderTestFactory instanceof ReactiveELCUnderTestFactory) {
|
||||||
configurationBuilder
|
configurationBuilder
|
||||||
.withClientConfigurer(ElasticsearchClients.ElasticsearchClientConfigurationCallback.from(webClient -> {
|
.withClientConfigurer(ElasticsearchClients.ElasticsearchHttpClientConfigurationCallback.from(webClient -> {
|
||||||
clientConfigurerCount.incrementAndGet();
|
httpClientConfigurerCount.incrementAndGet();
|
||||||
return webClient;
|
return webClient;
|
||||||
}));
|
}));
|
||||||
|
configurationBuilder.withClientConfigurer(
|
||||||
|
ElasticsearchClients.ElasticsearchRestClientConfigurationCallback.from(restClientBuilder -> {
|
||||||
|
restClientConfigurerCount.incrementAndGet();
|
||||||
|
return restClientBuilder;
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
ClientConfiguration clientConfiguration = configurationBuilder.build();
|
ClientConfiguration clientConfiguration = configurationBuilder.build();
|
||||||
@ -162,7 +173,8 @@ public class RestClientsTest {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
assertThat(clientConfigurerCount).hasValue(1);
|
assertThat(httpClientConfigurerCount).hasValue(1);
|
||||||
|
assertThat(restClientConfigurerCount).hasValue(clientUnderTestFactory.getExpectedRestClientConfigCalls());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -328,11 +340,16 @@ public class RestClientsTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected abstract String getDisplayName();
|
protected abstract String getDisplayName();
|
||||||
|
|
||||||
|
protected Integer getExpectedRestClientConfigCalls() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link ClientUnderTestFactory} implementation for the old {@link RestHighLevelClient}.
|
* {@link ClientUnderTestFactory} implementation for the old {@link RestHighLevelClient}.
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
static class ERHLCUnderTestFactory extends ClientUnderTestFactory {
|
static class ERHLCUnderTestFactory extends ClientUnderTestFactory {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -363,7 +380,6 @@ public class RestClientsTest {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -376,6 +392,11 @@ public class RestClientsTest {
|
|||||||
return "ElasticsearchClient";
|
return "ElasticsearchClient";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Integer getExpectedRestClientConfigCalls() {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
ClientUnderTest create(ClientConfiguration clientConfiguration) {
|
ClientUnderTest create(ClientConfiguration clientConfiguration) {
|
||||||
|
|
||||||
@ -403,6 +424,7 @@ public class RestClientsTest {
|
|||||||
* {@link ClientUnderTestFactory} implementation for the
|
* {@link ClientUnderTestFactory} implementation for the
|
||||||
* {@link org.springframework.data.elasticsearch.client.erhlc.ReactiveElasticsearchClient}.
|
* {@link org.springframework.data.elasticsearch.client.erhlc.ReactiveElasticsearchClient}.
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
static class ReactiveERHLCUnderTestFactory extends ClientUnderTestFactory {
|
static class ReactiveERHLCUnderTestFactory extends ClientUnderTestFactory {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -446,6 +468,11 @@ public class RestClientsTest {
|
|||||||
return "ReactiveElasticsearchClient (ELC based)";
|
return "ReactiveElasticsearchClient (ELC based)";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Integer getExpectedRestClientConfigCalls() {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
ClientUnderTest create(ClientConfiguration clientConfiguration) {
|
ClientUnderTest create(ClientConfiguration clientConfiguration) {
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user