Skip to content

Commit bbfb6ff

Browse files
authored
Allow providing a custom ElasticsearchTransport in the configuration classes.
Original Pull Request #2703 Closes #2702
1 parent de87dd4 commit bbfb6ff

File tree

3 files changed

+128
-46
lines changed

3 files changed

+128
-46
lines changed

src/main/java/org/springframework/data/elasticsearch/client/elc/ElasticsearchClients.java

+76-30
Original file line numberDiff line numberDiff line change
@@ -57,16 +57,18 @@
5757
* @author Peter-Josef Meisch
5858
* @since 4.4
5959
*/
60+
@SuppressWarnings("unused")
6061
public final class ElasticsearchClients {
6162
/**
6263
* Name of whose value can be used to correlate log messages for this request.
6364
*/
6465
private static final String X_SPRING_DATA_ELASTICSEARCH_CLIENT = "X-SpringDataElasticsearch-Client";
65-
private static final String IMPERATIVE_CLIENT = "imperative";
66-
private static final String REACTIVE_CLIENT = "reactive";
66+
public static final String IMPERATIVE_CLIENT = "imperative";
67+
public static final String REACTIVE_CLIENT = "reactive";
6768

6869
private static final JsonpMapper DEFAULT_JSONP_MAPPER = new JacksonJsonpMapper();
6970

71+
// region reactive client
7072
/**
7173
* Creates a new {@link ReactiveElasticsearchClient}
7274
*
@@ -131,10 +133,28 @@ public static ReactiveElasticsearchClient createReactive(RestClient restClient)
131133
*/
132134
public static ReactiveElasticsearchClient createReactive(RestClient restClient,
133135
@Nullable TransportOptions transportOptions, JsonpMapper jsonpMapper) {
134-
return new ReactiveElasticsearchClient(
135-
getElasticsearchTransport(restClient, REACTIVE_CLIENT, transportOptions, jsonpMapper));
136+
137+
Assert.notNull(restClient, "restClient must not be null");
138+
139+
var transport = getElasticsearchTransport(restClient, REACTIVE_CLIENT, transportOptions, jsonpMapper);
140+
return createReactive(transport);
136141
}
137142

143+
/**
144+
* Creates a new {@link ReactiveElasticsearchClient} that uses the given {@link ElasticsearchTransport}.
145+
*
146+
* @param transport the transport to use
147+
* @return the {@link ElasticsearchClient
148+
*/
149+
public static ReactiveElasticsearchClient createReactive(ElasticsearchTransport transport) {
150+
151+
Assert.notNull(transport, "transport must not be null");
152+
153+
return new ReactiveElasticsearchClient(transport);
154+
}
155+
// endregion
156+
157+
// region imperative client
138158
/**
139159
* Creates a new imperative {@link ElasticsearchClient}
140160
*
@@ -183,8 +203,40 @@ public static ElasticsearchClient createImperative(RestClient restClient, @Nulla
183203
ElasticsearchTransport transport = getElasticsearchTransport(restClient, IMPERATIVE_CLIENT, transportOptions,
184204
jsonpMapper);
185205

206+
return createImperative(transport);
207+
}
208+
209+
/**
210+
* Creates a new {@link ElasticsearchClient} that uses the given {@link ElasticsearchTransport}.
211+
*
212+
* @param transport the transport to use
213+
* @return the {@link ElasticsearchClient
214+
*/
215+
public static AutoCloseableElasticsearchClient createImperative(ElasticsearchTransport transport) {
216+
217+
Assert.notNull(transport, "transport must not be null");
218+
186219
return new AutoCloseableElasticsearchClient(transport);
187220
}
221+
// endregion
222+
223+
// region low level RestClient
224+
private static RestClientOptions.Builder getRestClientOptionsBuilder(@Nullable TransportOptions transportOptions) {
225+
226+
if (transportOptions instanceof RestClientOptions restClientOptions) {
227+
return restClientOptions.toBuilder();
228+
}
229+
230+
var builder = new RestClientOptions.Builder(RequestOptions.DEFAULT.toBuilder());
231+
232+
if (transportOptions != null) {
233+
transportOptions.headers().forEach(header -> builder.addHeader(header.getKey(), header.getValue()));
234+
transportOptions.queryParameters().forEach(builder::setParameter);
235+
builder.onWarnings(transportOptions.onWarnings());
236+
}
237+
238+
return builder;
239+
}
188240

189241
/**
190242
* Creates a low level {@link RestClient} for the given configuration.
@@ -256,10 +308,26 @@ private static RestClientBuilder getRestClientBuilder(ClientConfiguration client
256308
}
257309
return builder;
258310
}
311+
// endregion
259312

260-
private static ElasticsearchTransport getElasticsearchTransport(RestClient restClient, String clientType,
313+
// region Elasticsearch transport
314+
/**
315+
* Creates an {@link ElasticsearchTransport} that will use the given client that additionally is customized with a
316+
* header to contain the clientType
317+
*
318+
* @param restClient the client to use
319+
* @param clientType the client type to pass in each request as header
320+
* @param transportOptions options for the transport
321+
* @param jsonpMapper mapper for the transport
322+
* @return ElasticsearchTransport
323+
*/
324+
public static ElasticsearchTransport getElasticsearchTransport(RestClient restClient, String clientType,
261325
@Nullable TransportOptions transportOptions, JsonpMapper jsonpMapper) {
262326

327+
Assert.notNull(restClient, "restClient must not be null");
328+
Assert.notNull(clientType, "clientType must not be null");
329+
Assert.notNull(jsonpMapper, "jsonpMapper must not be null");
330+
263331
TransportOptions.Builder transportOptionsBuilder = transportOptions != null ? transportOptions.toBuilder()
264332
: new RestClientOptions(RequestOptions.DEFAULT).toBuilder();
265333

@@ -285,26 +353,10 @@ private static ElasticsearchTransport getElasticsearchTransport(RestClient restC
285353

286354
return new RestClientTransport(restClient, jsonpMapper, restClientOptionsBuilder.build());
287355
}
288-
289-
private static RestClientOptions.Builder getRestClientOptionsBuilder(@Nullable TransportOptions transportOptions) {
290-
291-
if (transportOptions instanceof RestClientOptions restClientOptions) {
292-
return restClientOptions.toBuilder();
293-
}
294-
295-
var builder = new RestClientOptions.Builder(RequestOptions.DEFAULT.toBuilder());
296-
297-
if (transportOptions != null) {
298-
transportOptions.headers().forEach(header -> builder.addHeader(header.getKey(), header.getValue()));
299-
transportOptions.queryParameters().forEach(builder::setParameter);
300-
builder.onWarnings(transportOptions.onWarnings());
301-
}
302-
303-
return builder;
304-
}
356+
// endregion
305357

306358
private static List<String> formattedHosts(List<InetSocketAddress> hosts, boolean useSsl) {
307-
return hosts.stream().map(it -> (useSsl ? "https" : "http") + "://" + it.getHostString() + ":" + it.getPort())
359+
return hosts.stream().map(it -> (useSsl ? "https" : "http") + "://" + it.getHostString() + ':' + it.getPort())
308360
.collect(Collectors.toList());
309361
}
310362

@@ -320,13 +372,7 @@ private static org.apache.http.Header[] toHeaderArray(HttpHeaders headers) {
320372
*
321373
* @since 4.4
322374
*/
323-
private static class CustomHeaderInjector implements HttpRequestInterceptor {
324-
325-
public CustomHeaderInjector(Supplier<HttpHeaders> headersSupplier) {
326-
this.headersSupplier = headersSupplier;
327-
}
328-
329-
private final Supplier<HttpHeaders> headersSupplier;
375+
private record CustomHeaderInjector(Supplier<HttpHeaders> headersSupplier) implements HttpRequestInterceptor {
330376

331377
@Override
332378
public void process(HttpRequest request, HttpContext context) {

src/main/java/org/springframework/data/elasticsearch/client/elc/ElasticsearchConfiguration.java

+26-9
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,12 @@
1818
import co.elastic.clients.elasticsearch.ElasticsearchClient;
1919
import co.elastic.clients.json.JsonpMapper;
2020
import co.elastic.clients.json.jackson.JacksonJsonpMapper;
21+
import co.elastic.clients.transport.ElasticsearchTransport;
2122
import co.elastic.clients.transport.TransportOptions;
2223
import co.elastic.clients.transport.rest_client.RestClientOptions;
2324

2425
import org.elasticsearch.client.RequestOptions;
2526
import org.elasticsearch.client.RestClient;
26-
import org.jetbrains.annotations.NotNull;
2727
import org.springframework.context.annotation.Bean;
2828
import org.springframework.data.elasticsearch.client.ClientConfiguration;
2929
import org.springframework.data.elasticsearch.config.ElasticsearchConfigurationSupport;
@@ -33,7 +33,8 @@
3333

3434
/**
3535
* Base class for a @{@link org.springframework.context.annotation.Configuration} class to set up the Elasticsearch
36-
* connection using the Elasticsearch Client.
36+
* connection using the Elasticsearch Client. This class exposes different parts of the setup as Spring beans. Deriving
37+
* classes must provide the {@link ClientConfiguration} to use.
3738
*
3839
* @author Peter-Josef Meisch
3940
* @since 4.4
@@ -49,7 +50,7 @@ public abstract class ElasticsearchConfiguration extends ElasticsearchConfigurat
4950
public abstract ClientConfiguration clientConfiguration();
5051

5152
/**
52-
* Provides the underlying low level RestClient.
53+
* Provides the underlying low level Elasticsearch RestClient.
5354
*
5455
* @param clientConfiguration configuration for the client, must not be {@literal null}
5556
* @return RestClient
@@ -62,19 +63,35 @@ public RestClient elasticsearchRestClient(ClientConfiguration clientConfiguratio
6263
return ElasticsearchClients.getRestClient(clientConfiguration);
6364
}
6465

66+
/**
67+
* Provides the Elasticsearch transport to be used. The default implementation uses the {@link RestClient} bean and
68+
* the {@link JsonpMapper} bean provided in this class.
69+
*
70+
* @return the {@link ElasticsearchTransport}
71+
* @since 5.2
72+
*/
73+
@Bean
74+
public ElasticsearchTransport elasticsearchTransport(RestClient restClient, JsonpMapper jsonpMapper) {
75+
76+
Assert.notNull(restClient, "restClient must not be null");
77+
Assert.notNull(jsonpMapper, "jsonpMapper must not be null");
78+
79+
return ElasticsearchClients.getElasticsearchTransport(restClient, ElasticsearchClients.IMPERATIVE_CLIENT,
80+
transportOptions(), jsonpMapper);
81+
}
82+
6583
/**
6684
* Provides the {@link ElasticsearchClient} to be used.
6785
*
68-
* @param restClient the low level RestClient to use
69-
* @param jsonpMapper the JsonpMapper to use
86+
* @param transport the {@link ElasticsearchTransport} to use
7087
* @return ElasticsearchClient instance
7188
*/
7289
@Bean
73-
public ElasticsearchClient elasticsearchClient(RestClient restClient, JsonpMapper jsonpMapper) {
90+
public ElasticsearchClient elasticsearchClient(ElasticsearchTransport transport) {
7491

75-
Assert.notNull(restClient, "restClient must not be null");
92+
Assert.notNull(transport, "transport must not be null");
7693

77-
return ElasticsearchClients.createImperative(restClient, transportOptions(), jsonpMapper);
94+
return ElasticsearchClients.createImperative(transport);
7895
}
7996

8097
/**
@@ -94,7 +111,7 @@ public ElasticsearchOperations elasticsearchOperations(ElasticsearchConverter el
94111
}
95112

96113
/**
97-
* Provides the JsonpMapper bean that is used in the {@link #elasticsearchClient(RestClient, JsonpMapper)} method.
114+
* Provides the JsonpMapper bean that is used in the {@link #elasticsearchTransport(RestClient, JsonpMapper)} method.
98115
*
99116
* @return the {@link JsonpMapper} to use
100117
* @since 5.2

src/main/java/org/springframework/data/elasticsearch/client/elc/ReactiveElasticsearchConfiguration.java

+26-7
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
import co.elastic.clients.json.JsonpMapper;
1919
import co.elastic.clients.json.jackson.JacksonJsonpMapper;
20+
import co.elastic.clients.transport.ElasticsearchTransport;
2021
import co.elastic.clients.transport.TransportOptions;
2122
import co.elastic.clients.transport.rest_client.RestClientOptions;
2223

@@ -31,7 +32,8 @@
3132

3233
/**
3334
* Base class for a @{@link org.springframework.context.annotation.Configuration} class to set up the Elasticsearch
34-
* connection using the {@link ReactiveElasticsearchClient}.
35+
* connection using the {@link ReactiveElasticsearchClient}. This class exposes different parts of the setup as Spring
36+
* beans. Deriving * classes must provide the {@link ClientConfiguration} to use.
3537
*
3638
* @author Peter-Josef Meisch
3739
* @since 4.4
@@ -60,18 +62,35 @@ public RestClient elasticsearchRestClient(ClientConfiguration clientConfiguratio
6062
return ElasticsearchClients.getRestClient(clientConfiguration);
6163
}
6264

65+
/**
66+
* Provides the Elasticsearch transport to be used. The default implementation uses the {@link RestClient} bean and
67+
* the {@link JsonpMapper} bean provided in this class.
68+
*
69+
* @return the {@link ElasticsearchTransport}
70+
* @since 5.2
71+
*/
72+
@Bean
73+
public ElasticsearchTransport elasticsearchTransport(RestClient restClient, JsonpMapper jsonpMapper) {
74+
75+
Assert.notNull(restClient, "restClient must not be null");
76+
Assert.notNull(jsonpMapper, "jsonpMapper must not be null");
77+
78+
return ElasticsearchClients.getElasticsearchTransport(restClient, ElasticsearchClients.REACTIVE_CLIENT,
79+
transportOptions(), jsonpMapper);
80+
}
81+
6382
/**
6483
* Provides the {@link ReactiveElasticsearchClient} instance used.
6584
*
66-
* @param restClient the low level RestClient to use
85+
* @param transport the ElasticsearchTransport to use
6786
* @return ReactiveElasticsearchClient instance.
6887
*/
6988
@Bean
70-
public ReactiveElasticsearchClient reactiveElasticsearchClient(RestClient restClient, JsonpMapper jsonpMapper) {
89+
public ReactiveElasticsearchClient reactiveElasticsearchClient(ElasticsearchTransport transport) {
7190

72-
Assert.notNull(restClient, "restClient must not be null");
91+
Assert.notNull(transport, "transport must not be null");
7392

74-
return ElasticsearchClients.createReactive(restClient, transportOptions(), jsonpMapper);
93+
return ElasticsearchClients.createReactive(transport);
7594
}
7695

7796
/**
@@ -91,8 +110,8 @@ public ReactiveElasticsearchOperations reactiveElasticsearchOperations(Elasticse
91110
}
92111

93112
/**
94-
* Provides the JsonpMapper that is used in the {@link #reactiveElasticsearchClient(RestClient, JsonpMapper)} method
95-
* and exposes it as a bean.
113+
* Provides the JsonpMapper that is used in the {@link #elasticsearchTransport(RestClient, JsonpMapper)} method and
114+
* exposes it as a bean.
96115
*
97116
* @return the {@link JsonpMapper} to use
98117
* @since 5.2

0 commit comments

Comments
 (0)