diff --git a/pom.xml b/pom.xml index 389fc926c..0fe7e6f2f 100644 --- a/pom.xml +++ b/pom.xml @@ -248,6 +248,24 @@ test + + com.github.tomakehurst + wiremock-jre8 + 2.25.1 + test + + + + commons-logging + commons-logging + + + org.ow2.asm + asm + + + + org.apache.xbean @@ -258,8 +276,8 @@ javax.servlet - servlet-api - 3.0-alpha-1 + javax.servlet-api + 3.1.0 test 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 30c444cb1..8a429fd96 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/ClientConfiguration.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/ClientConfiguration.java @@ -144,6 +144,14 @@ public interface ClientConfiguration { */ Duration getSocketTimeout(); + /** + * returns an optionally set proxy in the form host:port + * + * @return the optional proxy + * @since 4.0 + */ + Optional getProxy(); + /** * @author Christoph Strobl */ @@ -212,8 +220,8 @@ public interface ClientConfiguration { TerminalClientConfigurationBuilder usingSsl(SSLContext sslContext); /** - * Connect via {@literal https} using the givens {@link SSLContext} and HostnameVerifier {@link HostnameVerifier} .
- * + * Connect via {@literal https} using the givens {@link SSLContext} and HostnameVerifier {@link HostnameVerifier} + * .
* NOTE You need to leave out the protocol in * {@link ClientConfigurationBuilderWithRequiredEndpoint#connectedTo(String)}. * @@ -286,6 +294,12 @@ public interface ClientConfiguration { */ TerminalClientConfigurationBuilder withBasicAuth(String username, String password); + /** + * @param proxy a proxy formatted as String {@literal host:port}. + * @return the {@link MaybeSecureClientConfigurationBuilder}. + */ + MaybeSecureClientConfigurationBuilder withProxy(String proxy); + /** * 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 09f755ab1..96f83ec9a 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/ClientConfigurationBuilder.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/ClientConfigurationBuilder.java @@ -53,6 +53,7 @@ class ClientConfigurationBuilder private Duration soTimeout = Duration.ofSeconds(5); private String username; private String password; + private String proxy; /* * (non-Javadoc) @@ -81,6 +82,13 @@ class ClientConfigurationBuilder return this; } + @Override + public MaybeSecureClientConfigurationBuilder withProxy(String proxy) { + Assert.hasLength(proxy, "proxy must not be null or empty"); + this.proxy = proxy; + return this; + } + /* * (non-Javadoc) * @see org.springframework.data.elasticsearch.client.ClientConfiguration.MaybeSecureClientConfigurationBuilder#usingSsl() @@ -189,8 +197,8 @@ class ClientConfigurationBuilder headers.setBasicAuth(username, password); } - return new DefaultClientConfiguration(this.hosts, this.headers, this.useSsl, this.sslContext, this.soTimeout, - this.connectTimeout, this.hostnameVerifier); + return new DefaultClientConfiguration(hosts, headers, useSsl, sslContext, soTimeout, connectTimeout, + hostnameVerifier, proxy); } 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 4a47f39dd..d52b4654d 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/DefaultClientConfiguration.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/DefaultClientConfiguration.java @@ -44,9 +44,11 @@ class DefaultClientConfiguration implements ClientConfiguration { private final Duration soTimeout; private final Duration connectTimeout; private final @Nullable HostnameVerifier hostnameVerifier; + private final String proxy; DefaultClientConfiguration(List hosts, HttpHeaders headers, boolean useSsl, - @Nullable SSLContext sslContext, Duration soTimeout, Duration connectTimeout, @Nullable HostnameVerifier hostnameVerifier) { + @Nullable SSLContext sslContext, Duration soTimeout, Duration connectTimeout, + @Nullable HostnameVerifier hostnameVerifier, String proxy) { this.hosts = Collections.unmodifiableList(new ArrayList<>(hosts)); this.headers = new HttpHeaders(headers); @@ -55,6 +57,7 @@ class DefaultClientConfiguration implements ClientConfiguration { this.soTimeout = soTimeout; this.connectTimeout = connectTimeout; this.hostnameVerifier = hostnameVerifier; + this.proxy = proxy; } /* @@ -120,4 +123,12 @@ class DefaultClientConfiguration implements ClientConfiguration { return this.soTimeout; } + /* + * (non-Javadoc) + * @see org.springframework.data.elasticsearch.client.ClientConfiguration#getProxy() + */ + @Override + public Optional getProxy() { + return Optional.ofNullable(proxy); + } } diff --git a/src/main/java/org/springframework/data/elasticsearch/client/RestClients.java b/src/main/java/org/springframework/data/elasticsearch/client/RestClients.java index b18e5e1e6..dfa5442dd 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/RestClients.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/RestClients.java @@ -118,6 +118,8 @@ public final class RestClients { clientBuilder.setDefaultRequestConfig(requestConfigBuilder.build()); + clientConfiguration.getProxy().map(HttpHost::create).ifPresent(clientBuilder::setProxy); + return clientBuilder; }); diff --git a/src/test/java/org/springframework/data/elasticsearch/client/ClientConfigurationUnitTests.java b/src/test/java/org/springframework/data/elasticsearch/client/ClientConfigurationUnitTests.java index b37028bc2..e764356b8 100644 --- a/src/test/java/org/springframework/data/elasticsearch/client/ClientConfigurationUnitTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/client/ClientConfigurationUnitTests.java @@ -44,7 +44,7 @@ public class ClientConfigurationUnitTests { assertThat(clientConfiguration.getEndpoints()).containsOnly(InetSocketAddress.createUnresolved("localhost", 9200)); } - @Test // DATAES-488, DATAES-504 + @Test // DATAES-488, DATAES-504, DATAES-650, DATAES-700 public void shouldCreateCustomizedConfiguration() { HttpHeaders headers = new HttpHeaders(); @@ -54,7 +54,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)) // + .withProxy("localhost:8080").build(); assertThat(clientConfiguration.getEndpoints()).containsOnly(InetSocketAddress.createUnresolved("foo", 9200), InetSocketAddress.createUnresolved("bar", 9200)); @@ -62,6 +63,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.getProxy()).contains("localhost:8080"); } @Test // DATAES-488, DATAES-504 diff --git a/src/test/java/org/springframework/data/elasticsearch/client/RestClientsTest.java b/src/test/java/org/springframework/data/elasticsearch/client/RestClientsTest.java new file mode 100644 index 000000000..a4cd82325 --- /dev/null +++ b/src/test/java/org/springframework/data/elasticsearch/client/RestClientsTest.java @@ -0,0 +1,48 @@ +package org.springframework.data.elasticsearch.client; + +import static com.github.tomakehurst.wiremock.client.WireMock.*; +import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.options; + +import java.io.IOException; + +import org.elasticsearch.client.RequestOptions; +import org.elasticsearch.client.RestHighLevelClient; + +import com.github.tomakehurst.wiremock.WireMockServer; +import com.github.tomakehurst.wiremock.client.WireMock; +import org.junit.Test; + +/** + * @author Peter-Josef Meisch + */ +public class RestClientsTest { + + @Test + // DATAES-700 + public void shouldUseConfiguredProxy() throws IOException { + + WireMockServer wireMockServer = new WireMockServer(options() // + .dynamicPort() // + .usingFilesUnderDirectory("src/test/resources/wiremock-mappings")); // needed, otherwise Wiremock goes to + // test/resources/mappings + wireMockServer.start(); + try { + WireMock.configureFor(wireMockServer.port()); + + ClientConfigurationBuilder configurationBuilder = new ClientConfigurationBuilder(); + ClientConfiguration clientConfiguration = configurationBuilder // + .connectedTo("localhost:9200")// + .withProxy("localhost:" + wireMockServer.port()) // + .build(); + + RestHighLevelClient restClient = RestClients.create(clientConfiguration).rest(); + restClient.ping(RequestOptions.DEFAULT); + + verify(headRequestedFor(urlEqualTo("/"))); + + } finally { + wireMockServer.shutdown(); + } + } + +}