mirror of
https://github.com/honeymoose/OpenSearch.git
synced 2025-02-17 02:14:54 +00:00
Merge pull request #19373 from javanna/enhancement/rest_client_builder_callback
Rest Client: add callback to customize http client settings
This commit is contained in:
commit
f6aec3fdb5
@ -37,8 +37,6 @@ import org.apache.http.client.methods.HttpPut;
|
|||||||
import org.apache.http.client.methods.HttpRequestBase;
|
import org.apache.http.client.methods.HttpRequestBase;
|
||||||
import org.apache.http.client.methods.HttpTrace;
|
import org.apache.http.client.methods.HttpTrace;
|
||||||
import org.apache.http.client.utils.URIBuilder;
|
import org.apache.http.client.utils.URIBuilder;
|
||||||
import org.apache.http.config.Registry;
|
|
||||||
import org.apache.http.conn.socket.ConnectionSocketFactory;
|
|
||||||
import org.apache.http.entity.ContentType;
|
import org.apache.http.entity.ContentType;
|
||||||
import org.apache.http.impl.client.CloseableHttpClient;
|
import org.apache.http.impl.client.CloseableHttpClient;
|
||||||
import org.apache.http.impl.client.HttpClientBuilder;
|
import org.apache.http.impl.client.HttpClientBuilder;
|
||||||
@ -91,7 +89,7 @@ public final class RestClient implements Closeable {
|
|||||||
private final ConcurrentMap<HttpHost, DeadHostState> blacklist = new ConcurrentHashMap<>();
|
private final ConcurrentMap<HttpHost, DeadHostState> blacklist = new ConcurrentHashMap<>();
|
||||||
private final FailureListener failureListener;
|
private final FailureListener failureListener;
|
||||||
|
|
||||||
private RestClient(CloseableHttpClient client, long maxRetryTimeoutMillis, Header[] defaultHeaders,
|
RestClient(CloseableHttpClient client, long maxRetryTimeoutMillis, Header[] defaultHeaders,
|
||||||
HttpHost[] hosts, FailureListener failureListener) {
|
HttpHost[] hosts, FailureListener failureListener) {
|
||||||
this.client = client;
|
this.client = client;
|
||||||
this.maxRetryTimeoutMillis = maxRetryTimeoutMillis;
|
this.maxRetryTimeoutMillis = maxRetryTimeoutMillis;
|
||||||
@ -393,10 +391,11 @@ public final class RestClient implements Closeable {
|
|||||||
private static final Header[] EMPTY_HEADERS = new Header[0];
|
private static final Header[] EMPTY_HEADERS = new Header[0];
|
||||||
|
|
||||||
private final HttpHost[] hosts;
|
private final HttpHost[] hosts;
|
||||||
private CloseableHttpClient httpClient;
|
|
||||||
private int maxRetryTimeout = DEFAULT_MAX_RETRY_TIMEOUT_MILLIS;
|
private int maxRetryTimeout = DEFAULT_MAX_RETRY_TIMEOUT_MILLIS;
|
||||||
private Header[] defaultHeaders = EMPTY_HEADERS;
|
private Header[] defaultHeaders = EMPTY_HEADERS;
|
||||||
private FailureListener failureListener;
|
private FailureListener failureListener;
|
||||||
|
private HttpClientConfigCallback httpClientConfigCallback;
|
||||||
|
private RequestConfigCallback requestConfigCallback;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new builder instance and sets the hosts that the client will send requests to.
|
* Creates a new builder instance and sets the hosts that the client will send requests to.
|
||||||
@ -408,17 +407,6 @@ public final class RestClient implements Closeable {
|
|||||||
this.hosts = hosts;
|
this.hosts = hosts;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the http client. A new default one will be created if not
|
|
||||||
* specified, by calling {@link #createDefaultHttpClient(Registry)})}.
|
|
||||||
*
|
|
||||||
* @see CloseableHttpClient
|
|
||||||
*/
|
|
||||||
public Builder setHttpClient(CloseableHttpClient httpClient) {
|
|
||||||
this.httpClient = httpClient;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the maximum timeout (in milliseconds) to honour in case of multiple retries of the same request.
|
* Sets the maximum timeout (in milliseconds) to honour in case of multiple retries of the same request.
|
||||||
* {@link #DEFAULT_MAX_RETRY_TIMEOUT_MILLIS} if not specified.
|
* {@link #DEFAULT_MAX_RETRY_TIMEOUT_MILLIS} if not specified.
|
||||||
@ -434,12 +422,10 @@ public final class RestClient implements Closeable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the default request headers, to be used when creating the default http client instance.
|
* Sets the default request headers, to be used sent with every request unless overridden on a per request basis
|
||||||
* In case the http client is set through {@link #setHttpClient(CloseableHttpClient)}, the default headers need to be
|
|
||||||
* set to it externally during http client construction.
|
|
||||||
*/
|
*/
|
||||||
public Builder setDefaultHeaders(Header[] defaultHeaders) {
|
public Builder setDefaultHeaders(Header[] defaultHeaders) {
|
||||||
Objects.requireNonNull(defaultHeaders, "default headers must not be null");
|
Objects.requireNonNull(defaultHeaders, "defaultHeaders must not be null");
|
||||||
for (Header defaultHeader : defaultHeaders) {
|
for (Header defaultHeader : defaultHeaders) {
|
||||||
Objects.requireNonNull(defaultHeader, "default header must not be null");
|
Objects.requireNonNull(defaultHeader, "default header must not be null");
|
||||||
}
|
}
|
||||||
@ -451,46 +437,92 @@ public final class RestClient implements Closeable {
|
|||||||
* Sets the {@link FailureListener} to be notified for each request failure
|
* Sets the {@link FailureListener} to be notified for each request failure
|
||||||
*/
|
*/
|
||||||
public Builder setFailureListener(FailureListener failureListener) {
|
public Builder setFailureListener(FailureListener failureListener) {
|
||||||
Objects.requireNonNull(failureListener, "failure listener must not be null");
|
Objects.requireNonNull(failureListener, "failureListener must not be null");
|
||||||
this.failureListener = failureListener;
|
this.failureListener = failureListener;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the {@link HttpClientConfigCallback} to be used to customize http client configuration
|
||||||
|
*/
|
||||||
|
public Builder setHttpClientConfigCallback(HttpClientConfigCallback httpClientConfigCallback) {
|
||||||
|
Objects.requireNonNull(httpClientConfigCallback, "httpClientConfigCallback must not be null");
|
||||||
|
this.httpClientConfigCallback = httpClientConfigCallback;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the {@link RequestConfigCallback} to be used to customize http client configuration
|
||||||
|
*/
|
||||||
|
public Builder setRequestConfigCallback(RequestConfigCallback requestConfigCallback) {
|
||||||
|
Objects.requireNonNull(requestConfigCallback, "requestConfigCallback must not be null");
|
||||||
|
this.requestConfigCallback = requestConfigCallback;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new {@link RestClient} based on the provided configuration.
|
* Creates a new {@link RestClient} based on the provided configuration.
|
||||||
*/
|
*/
|
||||||
public RestClient build() {
|
public RestClient build() {
|
||||||
if (httpClient == null) {
|
|
||||||
httpClient = createDefaultHttpClient(null);
|
|
||||||
}
|
|
||||||
if (failureListener == null) {
|
if (failureListener == null) {
|
||||||
failureListener = new FailureListener();
|
failureListener = new FailureListener();
|
||||||
}
|
}
|
||||||
|
CloseableHttpClient httpClient = createHttpClient();
|
||||||
return new RestClient(httpClient, maxRetryTimeout, defaultHeaders, hosts, failureListener);
|
return new RestClient(httpClient, maxRetryTimeout, defaultHeaders, hosts, failureListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private CloseableHttpClient createHttpClient() {
|
||||||
* Creates a {@link CloseableHttpClient} with default settings. Used when the http client instance is not provided.
|
//default timeouts are all infinite
|
||||||
*
|
RequestConfig.Builder requestConfigBuilder = RequestConfig.custom().setConnectTimeout(DEFAULT_CONNECT_TIMEOUT_MILLIS)
|
||||||
* @see CloseableHttpClient
|
.setSocketTimeout(DEFAULT_SOCKET_TIMEOUT_MILLIS)
|
||||||
*/
|
.setConnectionRequestTimeout(DEFAULT_CONNECTION_REQUEST_TIMEOUT_MILLIS);
|
||||||
public static CloseableHttpClient createDefaultHttpClient(Registry<ConnectionSocketFactory> socketFactoryRegistry) {
|
|
||||||
PoolingHttpClientConnectionManager connectionManager;
|
if (requestConfigCallback != null) {
|
||||||
if (socketFactoryRegistry == null) {
|
requestConfigCallback.customizeRequestConfig(requestConfigBuilder);
|
||||||
connectionManager = new PoolingHttpClientConnectionManager();
|
|
||||||
} else {
|
|
||||||
connectionManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
|
|
||||||
}
|
}
|
||||||
|
RequestConfig requestConfig = requestConfigBuilder.build();
|
||||||
|
|
||||||
|
PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager();
|
||||||
//default settings may be too constraining
|
//default settings may be too constraining
|
||||||
connectionManager.setDefaultMaxPerRoute(10);
|
connectionManager.setDefaultMaxPerRoute(10);
|
||||||
connectionManager.setMaxTotal(30);
|
connectionManager.setMaxTotal(30);
|
||||||
|
|
||||||
//default timeouts are all infinite
|
HttpClientBuilder httpClientBuilder = HttpClientBuilder.create().setConnectionManager(connectionManager)
|
||||||
RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(DEFAULT_CONNECT_TIMEOUT_MILLIS)
|
.setDefaultRequestConfig(requestConfig);
|
||||||
.setSocketTimeout(DEFAULT_SOCKET_TIMEOUT_MILLIS)
|
|
||||||
.setConnectionRequestTimeout(DEFAULT_CONNECTION_REQUEST_TIMEOUT_MILLIS).build();
|
if (httpClientConfigCallback != null) {
|
||||||
return HttpClientBuilder.create().setConnectionManager(connectionManager).setDefaultRequestConfig(requestConfig).build();
|
httpClientConfigCallback.customizeHttpClient(httpClientBuilder);
|
||||||
}
|
}
|
||||||
|
return httpClientBuilder.build();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback used the default {@link RequestConfig} being set to the {@link CloseableHttpClient}
|
||||||
|
* @see HttpClientBuilder#setDefaultRequestConfig
|
||||||
|
*/
|
||||||
|
public interface RequestConfigCallback {
|
||||||
|
/**
|
||||||
|
* Allows to customize the {@link RequestConfig} that will be used with each request.
|
||||||
|
* It is common to customize the different timeout values through this method without losing any other useful default
|
||||||
|
* value that the {@link RestClient.Builder} internally sets.
|
||||||
|
*/
|
||||||
|
void customizeRequestConfig(RequestConfig.Builder requestConfigBuilder);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback used to customize the {@link CloseableHttpClient} instance used by a {@link RestClient} instance.
|
||||||
|
* Allows to customize default {@link RequestConfig} being set to the client and any parameter that
|
||||||
|
* can be set through {@link HttpClientBuilder}
|
||||||
|
*/
|
||||||
|
public interface HttpClientConfigCallback {
|
||||||
|
/**
|
||||||
|
* Allows to customize the {@link CloseableHttpClient} being created and used by the {@link RestClient}.
|
||||||
|
* It is common to customzie the default {@link org.apache.http.client.CredentialsProvider} through this method,
|
||||||
|
* without losing any other useful default value that the {@link RestClient.Builder} internally sets.
|
||||||
|
* Also useful to setup ssl through {@link SSLSocketFactoryHttpConfigCallback}.
|
||||||
|
*/
|
||||||
|
void customizeHttpClient(HttpClientBuilder httpClientBuilder);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to Elasticsearch under one or more contributor
|
||||||
|
* license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright
|
||||||
|
* ownership. Elasticsearch licenses this file to you under
|
||||||
|
* the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
* not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.elasticsearch.client;
|
||||||
|
|
||||||
|
import org.apache.http.config.Registry;
|
||||||
|
import org.apache.http.config.RegistryBuilder;
|
||||||
|
import org.apache.http.conn.socket.ConnectionSocketFactory;
|
||||||
|
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
|
||||||
|
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
|
||||||
|
import org.apache.http.impl.client.HttpClientBuilder;
|
||||||
|
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helps configuring the http client when needing to communicate over ssl. It effectively replaces the connection manager
|
||||||
|
* with one that has ssl properly configured thanks to the provided {@link SSLConnectionSocketFactory}.
|
||||||
|
*/
|
||||||
|
public class SSLSocketFactoryHttpConfigCallback implements RestClient.HttpClientConfigCallback {
|
||||||
|
|
||||||
|
private final SSLConnectionSocketFactory sslSocketFactory;
|
||||||
|
|
||||||
|
public SSLSocketFactoryHttpConfigCallback(SSLConnectionSocketFactory sslSocketFactory) {
|
||||||
|
this.sslSocketFactory = sslSocketFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void customizeHttpClient(HttpClientBuilder httpClientBuilder) {
|
||||||
|
Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
|
||||||
|
.register("http", PlainConnectionSocketFactory.getSocketFactory())
|
||||||
|
.register("https", sslSocketFactory).build();
|
||||||
|
PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
|
||||||
|
//default settings may be too constraining
|
||||||
|
connectionManager.setDefaultMaxPerRoute(10);
|
||||||
|
connectionManager.setMaxTotal(30);
|
||||||
|
httpClientBuilder.setConnectionManager(connectionManager);
|
||||||
|
}
|
||||||
|
}
|
@ -22,6 +22,7 @@ package org.elasticsearch.client;
|
|||||||
import com.carrotsearch.randomizedtesting.generators.RandomInts;
|
import com.carrotsearch.randomizedtesting.generators.RandomInts;
|
||||||
import org.apache.http.Header;
|
import org.apache.http.Header;
|
||||||
import org.apache.http.HttpHost;
|
import org.apache.http.HttpHost;
|
||||||
|
import org.apache.http.client.config.RequestConfig;
|
||||||
import org.apache.http.impl.client.HttpClientBuilder;
|
import org.apache.http.impl.client.HttpClientBuilder;
|
||||||
import org.apache.http.message.BasicHeader;
|
import org.apache.http.message.BasicHeader;
|
||||||
|
|
||||||
@ -67,7 +68,7 @@ public class RestClientBuilderTests extends RestClientTestCase {
|
|||||||
RestClient.builder(new HttpHost("localhost", 9200)).setDefaultHeaders(null);
|
RestClient.builder(new HttpHost("localhost", 9200)).setDefaultHeaders(null);
|
||||||
fail("should have failed");
|
fail("should have failed");
|
||||||
} catch(NullPointerException e) {
|
} catch(NullPointerException e) {
|
||||||
assertEquals("default headers must not be null", e.getMessage());
|
assertEquals("defaultHeaders must not be null", e.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -81,7 +82,21 @@ public class RestClientBuilderTests extends RestClientTestCase {
|
|||||||
RestClient.builder(new HttpHost("localhost", 9200)).setFailureListener(null);
|
RestClient.builder(new HttpHost("localhost", 9200)).setFailureListener(null);
|
||||||
fail("should have failed");
|
fail("should have failed");
|
||||||
} catch(NullPointerException e) {
|
} catch(NullPointerException e) {
|
||||||
assertEquals("failure listener must not be null", e.getMessage());
|
assertEquals("failureListener must not be null", e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
RestClient.builder(new HttpHost("localhost", 9200)).setHttpClientConfigCallback(null);
|
||||||
|
fail("should have failed");
|
||||||
|
} catch(NullPointerException e) {
|
||||||
|
assertEquals("httpClientConfigCallback must not be null", e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
RestClient.builder(new HttpHost("localhost", 9200)).setRequestConfigCallback(null);
|
||||||
|
fail("should have failed");
|
||||||
|
} catch(NullPointerException e) {
|
||||||
|
assertEquals("requestConfigCallback must not be null", e.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
int numNodes = RandomInts.randomIntBetween(getRandom(), 1, 5);
|
int numNodes = RandomInts.randomIntBetween(getRandom(), 1, 5);
|
||||||
@ -91,7 +106,18 @@ public class RestClientBuilderTests extends RestClientTestCase {
|
|||||||
}
|
}
|
||||||
RestClient.Builder builder = RestClient.builder(hosts);
|
RestClient.Builder builder = RestClient.builder(hosts);
|
||||||
if (getRandom().nextBoolean()) {
|
if (getRandom().nextBoolean()) {
|
||||||
builder.setHttpClient(HttpClientBuilder.create().build());
|
builder.setHttpClientConfigCallback(new RestClient.HttpClientConfigCallback() {
|
||||||
|
@Override
|
||||||
|
public void customizeHttpClient(HttpClientBuilder httpClientBuilder) {
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (getRandom().nextBoolean()) {
|
||||||
|
builder.setRequestConfigCallback(new RestClient.RequestConfigCallback() {
|
||||||
|
@Override
|
||||||
|
public void customizeRequestConfig(RequestConfig.Builder requestConfigBuilder) {
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
if (getRandom().nextBoolean()) {
|
if (getRandom().nextBoolean()) {
|
||||||
int numHeaders = RandomInts.randomIntBetween(getRandom(), 1, 5);
|
int numHeaders = RandomInts.randomIntBetween(getRandom(), 1, 5);
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
package org.elasticsearch.client;
|
package org.elasticsearch.client;
|
||||||
|
|
||||||
import com.carrotsearch.randomizedtesting.generators.RandomInts;
|
import com.carrotsearch.randomizedtesting.generators.RandomInts;
|
||||||
|
import org.apache.http.Header;
|
||||||
import org.apache.http.HttpHost;
|
import org.apache.http.HttpHost;
|
||||||
import org.apache.http.HttpRequest;
|
import org.apache.http.HttpRequest;
|
||||||
import org.apache.http.ProtocolVersion;
|
import org.apache.http.ProtocolVersion;
|
||||||
@ -91,7 +92,7 @@ public class RestClientMultipleHostsTests extends RestClientTestCase {
|
|||||||
httpHosts[i] = new HttpHost("localhost", 9200 + i);
|
httpHosts[i] = new HttpHost("localhost", 9200 + i);
|
||||||
}
|
}
|
||||||
failureListener = new TrackingFailureListener();
|
failureListener = new TrackingFailureListener();
|
||||||
restClient = RestClient.builder(httpHosts).setHttpClient(httpClient).setFailureListener(failureListener).build();
|
restClient = new RestClient(httpClient, 10000, new Header[0], httpHosts, failureListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testRoundRobinOkStatusCodes() throws Exception {
|
public void testRoundRobinOkStatusCodes() throws Exception {
|
||||||
|
@ -128,8 +128,7 @@ public class RestClientSingleHostTests extends RestClientTestCase {
|
|||||||
}
|
}
|
||||||
httpHost = new HttpHost("localhost", 9200);
|
httpHost = new HttpHost("localhost", 9200);
|
||||||
failureListener = new TrackingFailureListener();
|
failureListener = new TrackingFailureListener();
|
||||||
restClient = RestClient.builder(httpHost).setHttpClient(httpClient).setDefaultHeaders(defaultHeaders)
|
restClient = new RestClient(httpClient, 10000, defaultHeaders, new HttpHost[]{httpHost}, failureListener);
|
||||||
.setFailureListener(failureListener).build();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -23,8 +23,7 @@ import org.apache.http.HttpException;
|
|||||||
import org.apache.http.HttpHeaders;
|
import org.apache.http.HttpHeaders;
|
||||||
import org.apache.http.HttpResponseInterceptor;
|
import org.apache.http.HttpResponseInterceptor;
|
||||||
import org.apache.http.entity.StringEntity;
|
import org.apache.http.entity.StringEntity;
|
||||||
import org.apache.http.impl.client.CloseableHttpClient;
|
import org.apache.http.impl.client.HttpClientBuilder;
|
||||||
import org.apache.http.impl.client.HttpClients;
|
|
||||||
import org.apache.http.message.BasicHeader;
|
import org.apache.http.message.BasicHeader;
|
||||||
import org.apache.http.protocol.HttpContext;
|
import org.apache.http.protocol.HttpContext;
|
||||||
import org.elasticsearch.client.Response;
|
import org.elasticsearch.client.Response;
|
||||||
@ -50,7 +49,7 @@ public class HttpCompressionIT extends ESIntegTestCase {
|
|||||||
ensureGreen();
|
ensureGreen();
|
||||||
// we need to intercept early, otherwise internal logic in HttpClient will just remove the header and we cannot verify it
|
// we need to intercept early, otherwise internal logic in HttpClient will just remove the header and we cannot verify it
|
||||||
ContentEncodingHeaderExtractor headerExtractor = new ContentEncodingHeaderExtractor();
|
ContentEncodingHeaderExtractor headerExtractor = new ContentEncodingHeaderExtractor();
|
||||||
try (RestClient client = createRestClient(HttpClients.custom().addInterceptorFirst(headerExtractor).build())) {
|
try (RestClient client = createRestClient(new ContentEncodingHeaderExtractorConfigCallback(headerExtractor))) {
|
||||||
try (Response response = client.performRequest("GET", "/", new BasicHeader(HttpHeaders.ACCEPT_ENCODING, GZIP_ENCODING))) {
|
try (Response response = client.performRequest("GET", "/", new BasicHeader(HttpHeaders.ACCEPT_ENCODING, GZIP_ENCODING))) {
|
||||||
assertEquals(200, response.getStatusLine().getStatusCode());
|
assertEquals(200, response.getStatusLine().getStatusCode());
|
||||||
assertTrue(headerExtractor.hasContentEncodingHeader());
|
assertTrue(headerExtractor.hasContentEncodingHeader());
|
||||||
@ -62,8 +61,7 @@ public class HttpCompressionIT extends ESIntegTestCase {
|
|||||||
public void testUncompressedResponseByDefault() throws Exception {
|
public void testUncompressedResponseByDefault() throws Exception {
|
||||||
ensureGreen();
|
ensureGreen();
|
||||||
ContentEncodingHeaderExtractor headerExtractor = new ContentEncodingHeaderExtractor();
|
ContentEncodingHeaderExtractor headerExtractor = new ContentEncodingHeaderExtractor();
|
||||||
CloseableHttpClient httpClient = HttpClients.custom().disableContentCompression().addInterceptorFirst(headerExtractor).build();
|
try (RestClient client = createRestClient(new NoContentCompressionConfigCallback(headerExtractor))) {
|
||||||
try (RestClient client = createRestClient(httpClient)) {
|
|
||||||
try (Response response = client.performRequest("GET", "/")) {
|
try (Response response = client.performRequest("GET", "/")) {
|
||||||
assertEquals(200, response.getStatusLine().getStatusCode());
|
assertEquals(200, response.getStatusLine().getStatusCode());
|
||||||
assertFalse(headerExtractor.hasContentEncodingHeader());
|
assertFalse(headerExtractor.hasContentEncodingHeader());
|
||||||
@ -75,8 +73,7 @@ public class HttpCompressionIT extends ESIntegTestCase {
|
|||||||
ensureGreen();
|
ensureGreen();
|
||||||
ContentEncodingHeaderExtractor headerExtractor = new ContentEncodingHeaderExtractor();
|
ContentEncodingHeaderExtractor headerExtractor = new ContentEncodingHeaderExtractor();
|
||||||
// this disable content compression in both directions (request and response)
|
// this disable content compression in both directions (request and response)
|
||||||
CloseableHttpClient httpClient = HttpClients.custom().disableContentCompression().addInterceptorFirst(headerExtractor).build();
|
try (RestClient client = createRestClient(new NoContentCompressionConfigCallback(headerExtractor))) {
|
||||||
try (RestClient client = createRestClient(httpClient)) {
|
|
||||||
try (Response response = client.performRequest("POST", "/company/employees/1",
|
try (Response response = client.performRequest("POST", "/company/employees/1",
|
||||||
Collections.emptyMap(), SAMPLE_DOCUMENT)) {
|
Collections.emptyMap(), SAMPLE_DOCUMENT)) {
|
||||||
assertEquals(201, response.getStatusLine().getStatusCode());
|
assertEquals(201, response.getStatusLine().getStatusCode());
|
||||||
@ -89,7 +86,7 @@ public class HttpCompressionIT extends ESIntegTestCase {
|
|||||||
ensureGreen();
|
ensureGreen();
|
||||||
ContentEncodingHeaderExtractor headerExtractor = new ContentEncodingHeaderExtractor();
|
ContentEncodingHeaderExtractor headerExtractor = new ContentEncodingHeaderExtractor();
|
||||||
// we don't call #disableContentCompression() hence the client will send the content compressed
|
// we don't call #disableContentCompression() hence the client will send the content compressed
|
||||||
try (RestClient client = createRestClient(HttpClients.custom().addInterceptorFirst(headerExtractor).build())) {
|
try (RestClient client = createRestClient(new ContentEncodingHeaderExtractorConfigCallback(headerExtractor))) {
|
||||||
try (Response response = client.performRequest("POST", "/company/employees/2",
|
try (Response response = client.performRequest("POST", "/company/employees/2",
|
||||||
Collections.emptyMap(), SAMPLE_DOCUMENT)) {
|
Collections.emptyMap(), SAMPLE_DOCUMENT)) {
|
||||||
assertEquals(201, response.getStatusLine().getStatusCode());
|
assertEquals(201, response.getStatusLine().getStatusCode());
|
||||||
@ -119,4 +116,30 @@ public class HttpCompressionIT extends ESIntegTestCase {
|
|||||||
return contentEncodingHeader;
|
return contentEncodingHeader;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static class NoContentCompressionConfigCallback extends ContentEncodingHeaderExtractorConfigCallback {
|
||||||
|
NoContentCompressionConfigCallback(ContentEncodingHeaderExtractor contentEncodingHeaderExtractor) {
|
||||||
|
super(contentEncodingHeaderExtractor);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void customizeHttpClient(HttpClientBuilder httpClientBuilder) {
|
||||||
|
super.customizeHttpClient(httpClientBuilder);
|
||||||
|
httpClientBuilder.disableContentCompression();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class ContentEncodingHeaderExtractorConfigCallback implements RestClient.HttpClientConfigCallback {
|
||||||
|
|
||||||
|
private final ContentEncodingHeaderExtractor contentEncodingHeaderExtractor;
|
||||||
|
|
||||||
|
ContentEncodingHeaderExtractorConfigCallback(ContentEncodingHeaderExtractor contentEncodingHeaderExtractor) {
|
||||||
|
this.contentEncodingHeaderExtractor = contentEncodingHeaderExtractor;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void customizeHttpClient(HttpClientBuilder httpClientBuilder) {
|
||||||
|
httpClientBuilder.addInterceptorFirst(contentEncodingHeaderExtractor);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,6 @@ import com.carrotsearch.randomizedtesting.annotations.TestGroup;
|
|||||||
import com.carrotsearch.randomizedtesting.generators.RandomInts;
|
import com.carrotsearch.randomizedtesting.generators.RandomInts;
|
||||||
import com.carrotsearch.randomizedtesting.generators.RandomPicks;
|
import com.carrotsearch.randomizedtesting.generators.RandomPicks;
|
||||||
import org.apache.http.HttpHost;
|
import org.apache.http.HttpHost;
|
||||||
import org.apache.http.impl.client.CloseableHttpClient;
|
|
||||||
import org.apache.lucene.util.IOUtils;
|
import org.apache.lucene.util.IOUtils;
|
||||||
import org.apache.lucene.util.LuceneTestCase;
|
import org.apache.lucene.util.LuceneTestCase;
|
||||||
import org.apache.lucene.util.TestUtil;
|
import org.apache.lucene.util.TestUtil;
|
||||||
@ -2075,11 +2074,11 @@ public abstract class ESIntegTestCase extends ESTestCase {
|
|||||||
return restClient;
|
return restClient;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static RestClient createRestClient(CloseableHttpClient httpClient) {
|
protected static RestClient createRestClient(RestClient.HttpClientConfigCallback httpClientConfigCallback) {
|
||||||
return createRestClient(httpClient, "http");
|
return createRestClient(httpClientConfigCallback, "http");
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static RestClient createRestClient(CloseableHttpClient httpClient, String protocol) {
|
protected static RestClient createRestClient(RestClient.HttpClientConfigCallback httpClientConfigCallback, String protocol) {
|
||||||
final NodesInfoResponse nodeInfos = client().admin().cluster().prepareNodesInfo().get();
|
final NodesInfoResponse nodeInfos = client().admin().cluster().prepareNodesInfo().get();
|
||||||
final List<NodeInfo> nodes = nodeInfos.getNodes();
|
final List<NodeInfo> nodes = nodeInfos.getNodes();
|
||||||
assertFalse(nodeInfos.hasFailures());
|
assertFalse(nodeInfos.hasFailures());
|
||||||
@ -2093,8 +2092,8 @@ public abstract class ESIntegTestCase extends ESTestCase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
RestClient.Builder builder = RestClient.builder(hosts.toArray(new HttpHost[hosts.size()]));
|
RestClient.Builder builder = RestClient.builder(hosts.toArray(new HttpHost[hosts.size()]));
|
||||||
if (httpClient != null) {
|
if (httpClientConfigCallback != null) {
|
||||||
builder.setHttpClient(httpClient);
|
builder.setHttpClientConfigCallback(httpClientConfigCallback);
|
||||||
}
|
}
|
||||||
return builder.build();
|
return builder.build();
|
||||||
}
|
}
|
||||||
|
@ -22,16 +22,8 @@ import com.carrotsearch.randomizedtesting.RandomizedTest;
|
|||||||
import org.apache.http.Header;
|
import org.apache.http.Header;
|
||||||
import org.apache.http.HttpEntity;
|
import org.apache.http.HttpEntity;
|
||||||
import org.apache.http.HttpHost;
|
import org.apache.http.HttpHost;
|
||||||
import org.apache.http.client.config.RequestConfig;
|
|
||||||
import org.apache.http.config.Registry;
|
|
||||||
import org.apache.http.config.RegistryBuilder;
|
|
||||||
import org.apache.http.conn.socket.ConnectionSocketFactory;
|
|
||||||
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
|
|
||||||
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
|
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
|
||||||
import org.apache.http.entity.StringEntity;
|
import org.apache.http.entity.StringEntity;
|
||||||
import org.apache.http.impl.client.CloseableHttpClient;
|
|
||||||
import org.apache.http.impl.client.HttpClientBuilder;
|
|
||||||
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
|
|
||||||
import org.apache.http.message.BasicHeader;
|
import org.apache.http.message.BasicHeader;
|
||||||
import org.apache.http.ssl.SSLContexts;
|
import org.apache.http.ssl.SSLContexts;
|
||||||
import org.apache.lucene.util.IOUtils;
|
import org.apache.lucene.util.IOUtils;
|
||||||
@ -39,6 +31,7 @@ import org.elasticsearch.Version;
|
|||||||
import org.elasticsearch.client.Response;
|
import org.elasticsearch.client.Response;
|
||||||
import org.elasticsearch.client.ResponseException;
|
import org.elasticsearch.client.ResponseException;
|
||||||
import org.elasticsearch.client.RestClient;
|
import org.elasticsearch.client.RestClient;
|
||||||
|
import org.elasticsearch.client.SSLSocketFactoryHttpConfigCallback;
|
||||||
import org.elasticsearch.common.Strings;
|
import org.elasticsearch.common.Strings;
|
||||||
import org.elasticsearch.common.io.PathUtils;
|
import org.elasticsearch.common.io.PathUtils;
|
||||||
import org.elasticsearch.common.logging.ESLogger;
|
import org.elasticsearch.common.logging.ESLogger;
|
||||||
@ -82,11 +75,6 @@ public class RestTestClient implements Closeable {
|
|||||||
public static final String TRUSTSTORE_PATH = "truststore.path";
|
public static final String TRUSTSTORE_PATH = "truststore.path";
|
||||||
public static final String TRUSTSTORE_PASSWORD = "truststore.password";
|
public static final String TRUSTSTORE_PASSWORD = "truststore.password";
|
||||||
|
|
||||||
public static final int CONNECT_TIMEOUT_MILLIS = 1000;
|
|
||||||
public static final int SOCKET_TIMEOUT_MILLIS = 30000;
|
|
||||||
public static final int MAX_RETRY_TIMEOUT_MILLIS = SOCKET_TIMEOUT_MILLIS;
|
|
||||||
public static final int CONNECTION_REQUEST_TIMEOUT_MILLIS = 500;
|
|
||||||
|
|
||||||
private static final ESLogger logger = Loggers.getLogger(RestTestClient.class);
|
private static final ESLogger logger = Loggers.getLogger(RestTestClient.class);
|
||||||
//query_string params that don't need to be declared in the spec, thay are supported by default
|
//query_string params that don't need to be declared in the spec, thay are supported by default
|
||||||
private static final Set<String> ALWAYS_ACCEPTED_QUERY_STRING_PARAMS = Sets.newHashSet("pretty", "source", "filter_path");
|
private static final Set<String> ALWAYS_ACCEPTED_QUERY_STRING_PARAMS = Sets.newHashSet("pretty", "source", "filter_path");
|
||||||
@ -274,7 +262,15 @@ public class RestTestClient implements Closeable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static RestClient createRestClient(URL[] urls, Settings settings) throws IOException {
|
private static RestClient createRestClient(URL[] urls, Settings settings) throws IOException {
|
||||||
SSLConnectionSocketFactory sslsf;
|
String protocol = settings.get(PROTOCOL, "http");
|
||||||
|
HttpHost[] hosts = new HttpHost[urls.length];
|
||||||
|
for (int i = 0; i < hosts.length; i++) {
|
||||||
|
URL url = urls[i];
|
||||||
|
hosts[i] = new HttpHost(url.getHost(), url.getPort(), protocol);
|
||||||
|
}
|
||||||
|
RestClient.Builder builder = RestClient.builder(hosts).setMaxRetryTimeoutMillis(30000)
|
||||||
|
.setRequestConfigCallback(requestConfigBuilder -> requestConfigBuilder.setSocketTimeout(30000));
|
||||||
|
|
||||||
String keystorePath = settings.get(TRUSTSTORE_PATH);
|
String keystorePath = settings.get(TRUSTSTORE_PATH);
|
||||||
if (keystorePath != null) {
|
if (keystorePath != null) {
|
||||||
final String keystorePass = settings.get(TRUSTSTORE_PASSWORD);
|
final String keystorePass = settings.get(TRUSTSTORE_PASSWORD);
|
||||||
@ -291,38 +287,13 @@ public class RestTestClient implements Closeable {
|
|||||||
keyStore.load(is, keystorePass.toCharArray());
|
keyStore.load(is, keystorePass.toCharArray());
|
||||||
}
|
}
|
||||||
SSLContext sslcontext = SSLContexts.custom().loadTrustMaterial(keyStore, null).build();
|
SSLContext sslcontext = SSLContexts.custom().loadTrustMaterial(keyStore, null).build();
|
||||||
sslsf = new SSLConnectionSocketFactory(sslcontext);
|
SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(sslcontext);
|
||||||
|
builder.setHttpClientConfigCallback(new SSLSocketFactoryHttpConfigCallback(sslConnectionSocketFactory));
|
||||||
} catch (KeyStoreException|NoSuchAlgorithmException|KeyManagementException|CertificateException e) {
|
} catch (KeyStoreException|NoSuchAlgorithmException|KeyManagementException|CertificateException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
sslsf = SSLConnectionSocketFactory.getSocketFactory();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
|
|
||||||
.register("http", PlainConnectionSocketFactory.getSocketFactory())
|
|
||||||
.register("https", sslsf)
|
|
||||||
.build();
|
|
||||||
PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
|
|
||||||
//default settings may be too constraining
|
|
||||||
connectionManager.setDefaultMaxPerRoute(10);
|
|
||||||
connectionManager.setMaxTotal(30);
|
|
||||||
|
|
||||||
//default timeouts are all infinite
|
|
||||||
RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(CONNECT_TIMEOUT_MILLIS)
|
|
||||||
.setSocketTimeout(SOCKET_TIMEOUT_MILLIS)
|
|
||||||
.setConnectionRequestTimeout(CONNECTION_REQUEST_TIMEOUT_MILLIS).build();
|
|
||||||
CloseableHttpClient httpClient = HttpClientBuilder.create()
|
|
||||||
.setConnectionManager(connectionManager).setDefaultRequestConfig(requestConfig).build();
|
|
||||||
|
|
||||||
String protocol = settings.get(PROTOCOL, "http");
|
|
||||||
HttpHost[] hosts = new HttpHost[urls.length];
|
|
||||||
for (int i = 0; i < hosts.length; i++) {
|
|
||||||
URL url = urls[i];
|
|
||||||
hosts[i] = new HttpHost(url.getHost(), url.getPort(), protocol);
|
|
||||||
}
|
|
||||||
|
|
||||||
RestClient.Builder builder = RestClient.builder(hosts).setHttpClient(httpClient).setMaxRetryTimeoutMillis(MAX_RETRY_TIMEOUT_MILLIS);
|
|
||||||
try (ThreadContext threadContext = new ThreadContext(settings)) {
|
try (ThreadContext threadContext = new ThreadContext(settings)) {
|
||||||
Header[] defaultHeaders = new Header[threadContext.getHeaders().size()];
|
Header[] defaultHeaders = new Header[threadContext.getHeaders().size()];
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user