DATAES-650 - Add support for pathPrefix to configuration classes.

Original pull request: #320.
This commit is contained in:
Huw 2019-09-19 22:33:54 +01:00 committed by Peter-Josef Meisch
parent b820c9a422
commit 948d29ba65
9 changed files with 115 additions and 9 deletions

View File

@ -30,6 +30,7 @@ import org.springframework.http.HttpHeaders;
*
* @author Mark Paluch
* @author Peter-Josef Meisch
* @author Huw Ayling-Miller
* @since 3.2
*/
public interface ClientConfiguration {
@ -135,6 +136,14 @@ public interface ClientConfiguration {
*/
Duration getSocketTimeout();
/**
* Returns the path prefix that should be prepended to HTTP(s) requests for Elasticsearch behind a proxy.
*
* @return the path prefix.
* @since 4.0
*/
String getPathPrefix();
/**
* @author Christoph Strobl
*/
@ -267,6 +276,15 @@ public interface ClientConfiguration {
*/
TerminalClientConfigurationBuilder withBasicAuth(String username, String password);
/**
* Configure the path prefix that will be prepended to any HTTP(s) requests
*
* @param pathPrefix the pathPrefix.
* @return the {@link TerminalClientConfigurationBuilder}
* @since 4.0
*/
TerminalClientConfigurationBuilder withPathPrefix(String pathPrefix);
/**
* Build the {@link ClientConfiguration} object.
*

View File

@ -37,6 +37,7 @@ import org.springframework.util.Assert;
* @author Christoph Strobl
* @author Mark Paluch
* @author Peter-Josef Meisch
* @author Huw Ayling-Miller
* @since 3.2
*/
class ClientConfigurationBuilder
@ -50,6 +51,7 @@ class ClientConfigurationBuilder
private Duration soTimeout = Duration.ofSeconds(5);
private String username;
private String password;
private String pathPrefix;
/*
* (non-Javadoc)
@ -156,6 +158,14 @@ class ClientConfigurationBuilder
return this;
}
@Override
public TerminalClientConfigurationBuilder withPathPrefix(String pathPrefix) {
this.pathPrefix = pathPrefix;
return this;
}
/*
* (non-Javadoc)
* @see org.springframework.data.elasticsearch.client.ClientConfiguration.ClientConfigurationBuilderWithOptionalDefaultHeaders#build()
@ -171,7 +181,7 @@ class ClientConfigurationBuilder
}
return new DefaultClientConfiguration(this.hosts, this.headers, this.useSsl, this.sslContext, this.soTimeout,
this.connectTimeout);
this.connectTimeout, this.pathPrefix);
}
private static InetSocketAddress parse(String hostAndPort) {

View File

@ -32,6 +32,7 @@ import org.springframework.lang.Nullable;
*
* @author Mark Paluch
* @author Christoph Strobl
* @author Huw Ayling-Miller
* @since 3.2
*/
class DefaultClientConfiguration implements ClientConfiguration {
@ -42,9 +43,10 @@ class DefaultClientConfiguration implements ClientConfiguration {
private final @Nullable SSLContext sslContext;
private final Duration soTimeout;
private final Duration connectTimeout;
private final String pathPrefix;
DefaultClientConfiguration(List<InetSocketAddress> hosts, HttpHeaders headers, boolean useSsl,
@Nullable SSLContext sslContext, Duration soTimeout, Duration connectTimeout) {
@Nullable SSLContext sslContext, Duration soTimeout, Duration connectTimeout, @Nullable String pathPrefix) {
this.hosts = Collections.unmodifiableList(new ArrayList<>(hosts));
this.headers = new HttpHeaders(headers);
@ -52,6 +54,7 @@ class DefaultClientConfiguration implements ClientConfiguration {
this.sslContext = sslContext;
this.soTimeout = soTimeout;
this.connectTimeout = connectTimeout;
this.pathPrefix = pathPrefix;
}
/*
@ -108,4 +111,13 @@ class DefaultClientConfiguration implements ClientConfiguration {
return this.soTimeout;
}
/*
* (non-Javadoc)
* @see org.springframework.data.elasticsearch.client.ClientConfiguration#getPathPrefix()
*/
@Override
public String getPathPrefix() {
return this.pathPrefix;
}
}

View File

@ -52,6 +52,7 @@ import org.springframework.util.Assert;
*
* @author Christoph Strobl
* @author Mark Paluch
* @author Huw Ayling-Miller
* @since 3.2
*/
public final class RestClients {
@ -75,6 +76,11 @@ public final class RestClients {
HttpHost[] httpHosts = formattedHosts(clientConfiguration.getEndpoints(), clientConfiguration.useSsl()).stream()
.map(HttpHost::create).toArray(HttpHost[]::new);
RestClientBuilder builder = RestClient.builder(httpHosts);
if (clientConfiguration.getPathPrefix() != null) {
builder.setPathPrefix(clientConfiguration.getPathPrefix());
}
HttpHeaders headers = clientConfiguration.getDefaultHeaders();
if (!headers.isEmpty()) {

View File

@ -123,6 +123,7 @@ import org.springframework.web.reactive.function.client.WebClient.RequestBodySpe
* @author Christoph Strobl
* @author Mark Paluch
* @author Peter-Josef Meisch
* @author Huw Ayling-Miller
* @since 3.2
* @see ClientConfiguration
* @see ReactiveRestClients
@ -217,6 +218,10 @@ public class DefaultReactiveElasticsearchClient implements ReactiveElasticsearch
ReactorClientHttpConnector connector = new ReactorClientHttpConnector(httpClient);
WebClientProvider provider = WebClientProvider.create(scheme, connector);
if (clientConfiguration.getPathPrefix() != null) {
provider = provider.withPathPrefix(clientConfiguration.getPathPrefix());
}
return provider.withDefaultHeaders(clientConfiguration.getDefaultHeaders());
}

View File

@ -32,6 +32,7 @@ import org.springframework.web.reactive.function.client.WebClient.Builder;
*
* @author Mark Paluch
* @author Christoph Strobl
* @author Huw Ayling-Miller
* @since 3.2
*/
class DefaultWebClientProvider implements WebClientProvider {
@ -42,6 +43,7 @@ class DefaultWebClientProvider implements WebClientProvider {
private final @Nullable ClientHttpConnector connector;
private final Consumer<Throwable> errorListener;
private final HttpHeaders headers;
private final String pathPrefix;
/**
* Create new {@link DefaultWebClientProvider} with empty {@link HttpHeaders} and no-op {@literal error listener}.
@ -50,7 +52,7 @@ class DefaultWebClientProvider implements WebClientProvider {
* @param connector can be {@literal null}.
*/
DefaultWebClientProvider(String scheme, @Nullable ClientHttpConnector connector) {
this(scheme, connector, e -> {}, HttpHeaders.EMPTY);
this(scheme, connector, e -> {}, HttpHeaders.EMPTY, null);
}
/**
@ -62,7 +64,7 @@ class DefaultWebClientProvider implements WebClientProvider {
* @param headers must not be {@literal null}.
*/
private DefaultWebClientProvider(String scheme, @Nullable ClientHttpConnector connector,
Consumer<Throwable> errorListener, HttpHeaders headers) {
Consumer<Throwable> errorListener, HttpHeaders headers, @Nullable String pathPrefix) {
Assert.notNull(scheme, "Scheme must not be null! A common scheme would be 'http'.");
Assert.notNull(errorListener, "ErrorListener must not be null! You may want use a no-op one 'e -> {}' instead.");
@ -73,6 +75,7 @@ class DefaultWebClientProvider implements WebClientProvider {
this.connector = connector;
this.errorListener = errorListener;
this.headers = headers;
this.pathPrefix = pathPrefix;
}
/*
@ -109,7 +112,7 @@ class DefaultWebClientProvider implements WebClientProvider {
merged.addAll(this.headers);
merged.addAll(headers);
return new DefaultWebClientProvider(this.scheme, this.connector, errorListener, merged);
return new DefaultWebClientProvider(this.scheme, this.connector, errorListener, merged, this.pathPrefix);
}
/*
@ -121,6 +124,15 @@ class DefaultWebClientProvider implements WebClientProvider {
return this.errorListener;
}
/*
* (non-Javadoc)
* @see org.springframework.data.elasticsearch.client.reactive.WebClientProvider#getPathPrefix()
*/
@Override
public String getPathPrefix() {
return pathPrefix;
}
/*
* (non-Javadoc)
* @see org.springframework.data.elasticsearch.client.reactive.WebClientProvider#withErrorListener(java.util.function.Consumer)
@ -131,7 +143,18 @@ class DefaultWebClientProvider implements WebClientProvider {
Assert.notNull(errorListener, "Error listener must not be null.");
Consumer<Throwable> listener = this.errorListener.andThen(errorListener);
return new DefaultWebClientProvider(this.scheme, this.connector, listener, this.headers);
return new DefaultWebClientProvider(this.scheme, this.connector, listener, this.headers, this.pathPrefix);
}
/*
* (non-Javadoc)
* @see org.springframework.data.elasticsearch.client.reactive.WebClientProvider#withPathPrefix(java.lang.String)
*/
@Override
public WebClientProvider withPathPrefix(String pathPrefix) {
Assert.notNull(pathPrefix, "pathPrefix must not be null.");
return new DefaultWebClientProvider(this.scheme, this.connector, this.errorListener, this.headers, pathPrefix);
}
protected WebClient createWebClientForSocketAddress(InetSocketAddress socketAddress) {
@ -142,7 +165,8 @@ class DefaultWebClientProvider implements WebClientProvider {
builder = builder.clientConnector(connector);
}
String baseUrl = String.format("%s://%s:%d", this.scheme, socketAddress.getHostString(), socketAddress.getPort());
String baseUrl = String.format("%s://%s:%d%s", this.scheme, socketAddress.getHostString(), socketAddress.getPort(),
pathPrefix == null ? "" : "/" + pathPrefix);
return builder.baseUrl(baseUrl).filter((request, next) -> next.exchange(request).doOnError(errorListener)).build();
}
}

View File

@ -34,6 +34,7 @@ import org.springframework.web.reactive.function.client.WebClient;
*
* @author Christoph Strobl
* @author Mark Paluch
* @author Huw Ayling-Miller
* @since 3.2
*/
public interface WebClientProvider {
@ -96,6 +97,14 @@ public interface WebClientProvider {
*/
Consumer<Throwable> getErrorListener();
/**
* Obtain the {@link String pathPrefix} to be used.
*
* @return the pathPrefix if set.
* @since 4.0
*/
String getPathPrefix();
/**
* Create a new instance of {@link WebClientProvider} applying the given headers by default.
*
@ -111,4 +120,13 @@ public interface WebClientProvider {
* @return new instance of {@link WebClientProvider}.
*/
WebClientProvider withErrorListener(Consumer<Throwable> errorListener);
/**
* 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 4.0
*/
WebClientProvider withPathPrefix(String pathPrefix);
}

View File

@ -31,6 +31,7 @@ import org.springframework.http.HttpHeaders;
*
* @author Mark Paluch
* @author Peter-Josef Meisch
* @author Huw Ayling-Miller
*/
public class ClientConfigurationUnitTests {
@ -42,7 +43,7 @@ public class ClientConfigurationUnitTests {
assertThat(clientConfiguration.getEndpoints()).containsOnly(InetSocketAddress.createUnresolved("localhost", 9200));
}
@Test // DATAES-488, DATAES-504
@Test // DATAES-488, DATAES-504, DATAES-650
public void shouldCreateCustomizedConfiguration() {
HttpHeaders headers = new HttpHeaders();
@ -52,7 +53,8 @@ public class ClientConfigurationUnitTests {
.connectedTo("foo", "bar") //
.usingSsl() //
.withDefaultHeaders(headers) //
.withConnectTimeout(Duration.ofDays(1)).withSocketTimeout(Duration.ofDays(2)).build();
.withConnectTimeout(Duration.ofDays(1)).withSocketTimeout(Duration.ofDays(2)) //
.withPathPrefix("myPathPrefix").build();
assertThat(clientConfiguration.getEndpoints()).containsOnly(InetSocketAddress.createUnresolved("foo", 9200),
InetSocketAddress.createUnresolved("bar", 9200));
@ -60,6 +62,7 @@ public class ClientConfigurationUnitTests {
assertThat(clientConfiguration.getDefaultHeaders().get("foo")).containsOnly("bar");
assertThat(clientConfiguration.getConnectTimeout()).isEqualTo(Duration.ofDays(1));
assertThat(clientConfiguration.getSocketTimeout()).isEqualTo(Duration.ofDays(2));
assertThat(clientConfiguration.getPathPrefix()).isEqualTo("myPathPrefix");
}
@Test // DATAES-488, DATAES-504

View File

@ -263,6 +263,16 @@ public class ReactiveMockClientTestsUtils {
public WebClientProvider withErrorListener(Consumer<Throwable> errorListener) {
throw new UnsupportedOperationException();
}
@Override
public String getPathPrefix() {
return null;
}
@Override
public WebClientProvider withPathPrefix(String pathPrefix) {
throw new UnsupportedOperationException();
}
public Send when(String host) {
InetSocketAddress inetSocketAddress = getInetSocketAddress(host);