DATAES-700 - Enable proxy support for RestClient.

This commit is contained in:
Peter-Josef Meisch 2019-11-30 23:30:59 +01:00
parent c47fd2cfce
commit bae4db8a7f
7 changed files with 112 additions and 9 deletions

22
pom.xml
View File

@ -248,6 +248,24 @@
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.github.tomakehurst</groupId>
<artifactId>wiremock-jre8</artifactId>
<version>2.25.1</version>
<scope>test</scope>
<exclusions>
<!-- these exclusions are needed because of Elasticsearch JarHell-->
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
<exclusion>
<groupId>org.ow2.asm</groupId>
<artifactId>asm</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- Upgrade xbean to 4.5 to prevent incompatibilities due to ASM versions -->
<dependency>
<groupId>org.apache.xbean</groupId>
@ -258,8 +276,8 @@
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>3.0-alpha-1</version>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>test</scope>
</dependency>

View File

@ -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<String> 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} .<br />
*
* Connect via {@literal https} using the givens {@link SSLContext} and HostnameVerifier {@link HostnameVerifier}
* .<br />
* <strong>NOTE</strong> 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.
*

View File

@ -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) {

View File

@ -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<InetSocketAddress> 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<String> getProxy() {
return Optional.ofNullable(proxy);
}
}

View File

@ -118,6 +118,8 @@ public final class RestClients {
clientBuilder.setDefaultRequestConfig(requestConfigBuilder.build());
clientConfiguration.getProxy().map(HttpHost::create).ifPresent(clientBuilder::setProxy);
return clientBuilder;
});

View File

@ -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

View File

@ -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();
}
}
}