From 283b27d1704e6635795163a990a6397813b96dab Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Wed, 25 Dec 2019 09:09:43 +0100 Subject: [PATCH] DATAES-719 - Add customization hook for reactive WebClient. Original PR: #363 (cherry picked from commit f7a14c1135189a62675a3345d70ccb1a6ec16af4) --- .../client/ClientConfiguration.java | 19 +++++++- .../client/ClientConfigurationBuilder.java | 15 +++++- .../client/DefaultClientConfiguration.java | 47 ++++--------------- .../DefaultReactiveElasticsearchClient.java | 4 +- .../client/reactive/WebClientProvider.java | 13 ++++- .../ReactiveMockClientTestsUtils.java | 5 ++ 6 files changed, 59 insertions(+), 44 deletions(-) diff --git a/src/main/java/org/springframework/data/elasticsearch/client/ClientConfiguration.java b/src/main/java/org/springframework/data/elasticsearch/client/ClientConfiguration.java index ad5ceb32f..ffdb3d04d 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/ClientConfiguration.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/ClientConfiguration.java @@ -20,11 +20,13 @@ import java.net.SocketAddress; import java.time.Duration; import java.util.List; import java.util.Optional; +import java.util.function.Function; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.SSLContext; import org.springframework.http.HttpHeaders; +import org.springframework.web.reactive.function.client.WebClient; /** * Configuration interface exposing common client configuration properties for Elasticsearch clients. @@ -161,6 +163,11 @@ public interface ClientConfiguration { */ Optional getProxy(); + /** + * @return the function for configuring a WebClient. + */ + Function getWebClientConfigurer(); + /** * @author Christoph Strobl */ @@ -314,9 +321,17 @@ public interface ClientConfiguration { /** * @param proxy a proxy formatted as String {@literal host:port}. - * @return the {@link MaybeSecureClientConfigurationBuilder}. + * @return the {@link TerminalClientConfigurationBuilder}. */ - MaybeSecureClientConfigurationBuilder withProxy(String proxy); + TerminalClientConfigurationBuilder withProxy(String proxy); + + /** + * set customization hook in case of a reactive configuration + * + * @param webClientConfigurer function to configure the WebClient + * @return the {@link TerminalClientConfigurationBuilder}. + */ + TerminalClientConfigurationBuilder withWebClientConfigurer(Function webClientConfigurer); /** * Build the {@link ClientConfiguration} object. diff --git a/src/main/java/org/springframework/data/elasticsearch/client/ClientConfigurationBuilder.java b/src/main/java/org/springframework/data/elasticsearch/client/ClientConfigurationBuilder.java index 5d5907b38..fa1b49a4a 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/ClientConfigurationBuilder.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/ClientConfigurationBuilder.java @@ -20,6 +20,7 @@ import java.time.Duration; import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.function.Function; import java.util.stream.Collectors; import javax.net.ssl.HostnameVerifier; @@ -31,6 +32,7 @@ import org.springframework.data.elasticsearch.client.ClientConfiguration.Termina import org.springframework.http.HttpHeaders; import org.springframework.lang.Nullable; import org.springframework.util.Assert; +import org.springframework.web.reactive.function.client.WebClient; /** * Default builder implementation for {@link ClientConfiguration}. @@ -56,6 +58,7 @@ class ClientConfigurationBuilder private String password; private String pathPrefix; private String proxy; + private Function webClientConfigurer; /* * (non-Javadoc) @@ -187,12 +190,20 @@ class ClientConfigurationBuilder @Override public TerminalClientConfigurationBuilder withPathPrefix(String pathPrefix) { - this.pathPrefix = pathPrefix; return this; } + @Override + public TerminalClientConfigurationBuilder withWebClientConfigurer(Function webClientConfigurer) { + + Assert.notNull(webClientConfigurer, "webClientConfigurer must not be null"); + + this.webClientConfigurer = webClientConfigurer; + return this; + } + /* * (non-Javadoc) * @see org.springframework.data.elasticsearch.client.ClientConfiguration.ClientConfigurationBuilderWithOptionalDefaultHeaders#build() @@ -208,7 +219,7 @@ class ClientConfigurationBuilder } return new DefaultClientConfiguration(hosts, headers, useSsl, sslContext, soTimeout, connectTimeout, pathPrefix, - hostnameVerifier, proxy); + hostnameVerifier, proxy, webClientConfigurer); } private static InetSocketAddress parse(String hostAndPort) { diff --git a/src/main/java/org/springframework/data/elasticsearch/client/DefaultClientConfiguration.java b/src/main/java/org/springframework/data/elasticsearch/client/DefaultClientConfiguration.java index 78ac4a6dd..72dbdfaa0 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/DefaultClientConfiguration.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/DefaultClientConfiguration.java @@ -21,12 +21,14 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Optional; +import java.util.function.Function; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.SSLContext; import org.springframework.http.HttpHeaders; import org.springframework.lang.Nullable; +import org.springframework.web.reactive.function.client.WebClient; /** * Default {@link ClientConfiguration} implementation. @@ -48,10 +50,11 @@ class DefaultClientConfiguration implements ClientConfiguration { private final String pathPrefix; private final @Nullable HostnameVerifier hostnameVerifier; private final String proxy; + private final Function webClientConfigurer; DefaultClientConfiguration(List hosts, HttpHeaders headers, boolean useSsl, @Nullable SSLContext sslContext, Duration soTimeout, Duration connectTimeout, @Nullable String pathPrefix, - @Nullable HostnameVerifier hostnameVerifier, String proxy) { + @Nullable HostnameVerifier hostnameVerifier, String proxy, Function webClientConfigurer) { this.hosts = Collections.unmodifiableList(new ArrayList<>(hosts)); this.headers = new HttpHeaders(headers); @@ -62,86 +65,56 @@ class DefaultClientConfiguration implements ClientConfiguration { this.pathPrefix = pathPrefix; this.hostnameVerifier = hostnameVerifier; this.proxy = proxy; + this.webClientConfigurer = webClientConfigurer; } - /* - * (non-Javadoc) - * @see org.springframework.data.elasticsearch.client.ClientConfiguration#getEndpoints() - */ @Override public List getEndpoints() { return this.hosts; } - /* - * (non-Javadoc) - * @see org.springframework.data.elasticsearch.client.ClientConfiguration#getDefaultHeaders() - */ @Override public HttpHeaders getDefaultHeaders() { return this.headers; } - /* - * (non-Javadoc) - * @see org.springframework.data.elasticsearch.client.ClientConfiguration#useSsl() - */ @Override public boolean useSsl() { return this.useSsl; } - /* - * (non-Javadoc) - * @see org.springframework.data.elasticsearch.client.ClientConfiguration#getSslContext() - */ @Override public Optional getSslContext() { return Optional.ofNullable(this.sslContext); } - /* - * (non-Javadoc) - * @see org.springframework.data.elasticsearch.client.ClientConfiguration#getHostNameVerifier() - */ @Override public Optional getHostNameVerifier() { return Optional.ofNullable(this.hostnameVerifier); } - /* - * (non-Javadoc) - * @see org.springframework.data.elasticsearch.client.ClientConfiguration#getConnectTimeout() - */ @Override public Duration getConnectTimeout() { return this.connectTimeout; } - /* - * (non-Javadoc) - * @see org.springframework.data.elasticsearch.client.ClientConfiguration#getSocketTimeout() - */ @Override public Duration getSocketTimeout() { return this.soTimeout; } - /* - * (non-Javadoc) - * @see org.springframework.data.elasticsearch.client.ClientConfiguration#getPathPrefix() - */ @Override public String getPathPrefix() { return this.pathPrefix; } - /* - * (non-Javadoc) - * @see org.springframework.data.elasticsearch.client.ClientConfiguration#getProxy() - */ @Override public Optional getProxy() { return Optional.ofNullable(proxy); } + + @Override + public Function getWebClientConfigurer() { + return webClientConfigurer != null ? webClientConfigurer : Function.identity(); + } } diff --git a/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java b/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java index db15bf141..cd7f627ee 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java @@ -226,7 +226,9 @@ public class DefaultReactiveElasticsearchClient implements ReactiveElasticsearch provider = provider.withPathPrefix(clientConfiguration.getPathPrefix()); } - return provider.withDefaultHeaders(clientConfiguration.getDefaultHeaders()); + provider = provider.withDefaultHeaders(clientConfiguration.getDefaultHeaders()) // + .withWebClientConfigurer(clientConfiguration.getWebClientConfigurer()); + return provider; } /* diff --git a/src/main/java/org/springframework/data/elasticsearch/client/reactive/WebClientProvider.java b/src/main/java/org/springframework/data/elasticsearch/client/reactive/WebClientProvider.java index 1982ddb7e..ba00f53c8 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/reactive/WebClientProvider.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/reactive/WebClientProvider.java @@ -17,6 +17,7 @@ package org.springframework.data.elasticsearch.client.reactive; import java.net.InetSocketAddress; import java.util.function.Consumer; +import java.util.function.Function; import org.springframework.http.HttpHeaders; import org.springframework.http.client.reactive.ClientHttpConnector; @@ -100,7 +101,7 @@ public interface WebClientProvider { /** * Obtain the {@link String pathPrefix} to be used. - * + * * @return the pathPrefix if set. * @since 3.2.4 */ @@ -124,10 +125,18 @@ public interface WebClientProvider { /** * Create a new instance of {@link WebClientProvider} where HTTP requests are called with the given path prefix. - * + * * @param pathPrefix Path prefix to add to requests * @return new instance of {@link WebClientProvider} * @since 3.2.4 */ WebClientProvider withPathPrefix(String pathPrefix); + + /** + * Create a new instance of {@link WebClientProvider} calling the given {@link Function} to configure the {@link WebClient}. + * @param webClientConfigurer configuration function + * @return new instance of {@link WebClientProvider} + * @since 3.2.4 + */ + WebClientProvider withWebClientConfigurer(Function webClientConfigurer); } diff --git a/src/test/java/org/springframework/data/elasticsearch/client/reactive/ReactiveMockClientTestsUtils.java b/src/test/java/org/springframework/data/elasticsearch/client/reactive/ReactiveMockClientTestsUtils.java index 86a18f5e7..49063946b 100644 --- a/src/test/java/org/springframework/data/elasticsearch/client/reactive/ReactiveMockClientTestsUtils.java +++ b/src/test/java/org/springframework/data/elasticsearch/client/reactive/ReactiveMockClientTestsUtils.java @@ -277,6 +277,11 @@ public class ReactiveMockClientTestsUtils { throw new UnsupportedOperationException(); } + @Override + public WebClientProvider withWebClientConfigurer(Function webClientConfigurer) { + throw new UnsupportedOperationException("not implemented"); + } + public Send when(String host) { InetSocketAddress inetSocketAddress = getInetSocketAddress(host); return new CallbackImpl(get(host), headersUriSpecMap.get(inetSocketAddress),