From 3cd37a5c60b09db30d9625d3b16e5089dc8fdf84 Mon Sep 17 00:00:00 2001 From: Laura Trotta Date: Tue, 15 Jul 2025 14:48:13 +0200 Subject: [PATCH 1/4] add config callback to rest5 builder --- .../low_level/Rest5ClientBuilder.java | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/java-client/src/main/java/co/elastic/clients/transport/rest5_client/low_level/Rest5ClientBuilder.java b/java-client/src/main/java/co/elastic/clients/transport/rest5_client/low_level/Rest5ClientBuilder.java index b4d5f573e..23c10472f 100644 --- a/java-client/src/main/java/co/elastic/clients/transport/rest5_client/low_level/Rest5ClientBuilder.java +++ b/java-client/src/main/java/co/elastic/clients/transport/rest5_client/low_level/Rest5ClientBuilder.java @@ -75,6 +75,7 @@ public final class Rest5ClientBuilder { private final List nodes; private CloseableHttpAsyncClient httpClient; + private HttpClientConfigCallback httpClientConfigCallback; private Header[] defaultHeaders = EMPTY_HEADERS; private Rest5Client.FailureListener failureListener; private SSLContext sslContext; @@ -320,6 +321,36 @@ public Rest5ClientBuilder setMetaHeaderEnabled(boolean metadataEnabled) { return this; } + /** + * Sets the {@link HttpClientConfigCallback} to be used to customize http client configuration + * + * @throws NullPointerException if {@code httpClientConfigCallback} is {@code null}. + */ + public Rest5ClientBuilder setHttpClientConfigCallback(HttpClientConfigCallback httpClientConfigCallback) { + Objects.requireNonNull(httpClientConfigCallback, "httpClientConfigCallback must not be null"); + this.httpClientConfigCallback = httpClientConfigCallback; + return this; + } + + /** + * Callback used to customize the {@link CloseableHttpAsyncClient} instance used by a + * {@link Rest5Client} instance. + * Allows to customize default {@link RequestConfig} being set to the client and any parameter that + * can be set through {@link HttpAsyncClientBuilder} + */ + public interface HttpClientConfigCallback { + /** + * Allows to customize the {@link CloseableHttpAsyncClient} being created and used by the + * {@link Rest5Client}. + * Commonly used to customize {@link HttpAsyncClientBuilder} without losing any other useful default + * value that the {@link Rest5ClientBuilder} internally sets, except if RequestConfig, + * ConnectionConfig + * and ConnectionManager are set through this callback. + * In those cases, all default values set by the {@link Rest5ClientBuilder} are lost. + */ + HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpClientBuilder); + } + /** * Creates a new {@link Rest5Client} based on the provided configuration. */ @@ -407,6 +438,9 @@ private CloseableHttpAsyncClient createHttpClient() { if (this.routePlanner != null) { httpClientBuilder.setRoutePlanner(this.routePlanner); } + if (httpClientConfigCallback != null) { + httpClientBuilder = httpClientConfigCallback.customizeHttpClient(httpClientBuilder); + } return httpClientBuilder.build(); } catch (NoSuchAlgorithmException e) { From 7af771eeed04f34bf8a31113104ca99f19a056f3 Mon Sep 17 00:00:00 2001 From: Laura Trotta Date: Tue, 15 Jul 2025 15:39:24 +0200 Subject: [PATCH 2/4] modern java, updated docs --- .../config/basic_authentication.md | 8 ++--- .../rest5-client/config/number_of_threads.md | 12 +++---- .../transport/rest5-client/config/timeouts.md | 22 ++++++------ .../low_level/Rest5ClientBuilder.java | 34 ++++++------------- .../rest5_client/RestClientDocumentation.java | 31 ++++++----------- 5 files changed, 39 insertions(+), 68 deletions(-) diff --git a/docs/reference/transport/rest5-client/config/basic_authentication.md b/docs/reference/transport/rest5-client/config/basic_authentication.md index 077fbee17..2e8f99756 100644 --- a/docs/reference/transport/rest5-client/config/basic_authentication.md +++ b/docs/reference/transport/rest5-client/config/basic_authentication.md @@ -16,7 +16,7 @@ Rest5ClientBuilder restClient = Rest5Client ``` -Preemptive Authentication can be disabled, which means that every request will be sent without authorization headers to see if it is accepted and, upon receiving an HTTP 401 response, it will resend the exact same request with the basic authentication header. If you wish to do this, then you can do so by disabling it via the `HttpAsyncClientBuilder`: +Preemptive Authentication can be disabled, which means that every request will be sent without authorization headers to see if it is accepted and, upon receiving an HTTP 401 response, it will resend the exact same request with the basic authentication header. If you wish to do this, then you can do so by disabling it via the `HttpClientConfigCallback`: % :::{include-code} src={{doc-tests-src}}/rest5_client/RestClientDocumentation.java tag=rest-client-config-disable-preemptive-auth ```java @@ -24,13 +24,9 @@ HttpHost host = new HttpHost("http", "localhost", 9200); var creds = Base64.getEncoder().encodeToString("user:test-user-password".getBytes()); -CloseableHttpAsyncClient httpclient = HttpAsyncClients.custom() - .disableAuthCaching() // <1> - .build(); - Rest5ClientBuilder restClient = Rest5Client .builder(new HttpHost("https", "localhost", 9200)) - .setHttpClient(httpclient) + .setHttpClientConfigCallback(HttpAsyncClientBuilder::disableAuthCaching) .setDefaultHeaders(new Header[]{ new BasicHeader("Authorization", "Basic " + creds) }); diff --git a/docs/reference/transport/rest5-client/config/number_of_threads.md b/docs/reference/transport/rest5-client/config/number_of_threads.md index a5be90de1..8825e6448 100644 --- a/docs/reference/transport/rest5-client/config/number_of_threads.md +++ b/docs/reference/transport/rest5-client/config/number_of_threads.md @@ -5,13 +5,11 @@ The Apache Http Async Client starts by default one dispatcher thread, and a numb % :::{include-code} src={{doc-tests-src}}/rest5_client/RestClientDocumentation.java tag=rest-client-config-threads ```java -CloseableHttpAsyncClient httpclient = HttpAsyncClients.custom() - .setIOReactorConfig( - IOReactorConfig.custom().setIoThreadCount(1).build() - ) - .build(); - Rest5ClientBuilder builder = Rest5Client .builder(new HttpHost("localhost", 9200)) - .setHttpClient(httpclient); + .setHttpClientConfigCallback(c -> c + .setIOReactorConfig(IOReactorConfig.custom() + .setIoThreadCount(1).build() + ) + ); ``` diff --git a/docs/reference/transport/rest5-client/config/timeouts.md b/docs/reference/transport/rest5-client/config/timeouts.md index 5b43b9b19..b5747ac44 100644 --- a/docs/reference/transport/rest5-client/config/timeouts.md +++ b/docs/reference/transport/rest5-client/config/timeouts.md @@ -1,23 +1,22 @@ # Timeouts -Configuring requests timeouts can be done by providing an instance of `RequestConfigCallback` while building the `RestClient` through its builder. The interface has one method that receives an instance of [`org.apache.http.client.config.RequestConfig.Builder`](https://hc.apache.org/httpcomponents-client-4.5.x/current/httpclient/apidocs/org/apache/http/client/config/RequestConfig.Builder.html) as an argument and has the same return type. The request config builder can be modified and then returned. In the following example we increase the connect timeout (defaults to 1 second) and the socket timeout (defaults to 30 seconds). +Configuring requests timeouts can be done by using the `setHttpClientConfigCallback` method while building the `RestClient` and then calling `setDefaultRequestConfig`. In the following example we increase the connect timeout (defaults to 30 second) and the response timeout (defaults to 0, which is infinite). % :::{include-code} src={{doc-tests-src}}/rest5_client/RestClientDocumentation.java tag=rest-client-config-timeouts ```java -RequestConfig.Builder requestConfigBuilder = RequestConfig.custom() - .setConnectTimeout(Timeout.of(5000, TimeUnit.MILLISECONDS)); - -CloseableHttpAsyncClient httpclient = HttpAsyncClients.custom() - .setDefaultRequestConfig(requestConfigBuilder.build()) - .build(); - Rest5ClientBuilder builder = Rest5Client .builder(new HttpHost("localhost", 9200)) - .setHttpClient(httpclient); + .setHttpClientConfigCallback(c -> c + .setDefaultRequestConfig(RequestConfig.custom() + .setConnectTimeout(Timeout.of(5000, TimeUnit.MILLISECONDS)) + .setResponseTimeout(Timeout.of(30000, TimeUnit.MILLISECONDS)) + .build() + ) + ); ``` -Timeouts also can be set per request with RequestOptions, which overrides RestClient customizeRequestConfig. +Timeouts also can be set per request with RequestOptions, which overrides RestClient's builder. The RequestOptions can then be set in the Rest5ClientTransport constructor. % :::{include-code} src={{doc-tests-src}}/rest5_client/RestClientDocumentation.java tag=rest-client-config-request-options-timeouts ```java @@ -29,5 +28,8 @@ RequestConfig requestConfig = RequestConfig.custom() RequestOptions options = RequestOptions.DEFAULT.toBuilder() .setRequestConfig(requestConfig) .build(); + +ElasticsearchTransport transport = new Rest5ClientTransport( + restClient, new JacksonJsonpMapper(), options); ``` diff --git a/java-client/src/main/java/co/elastic/clients/transport/rest5_client/low_level/Rest5ClientBuilder.java b/java-client/src/main/java/co/elastic/clients/transport/rest5_client/low_level/Rest5ClientBuilder.java index 23c10472f..e00ce69b0 100644 --- a/java-client/src/main/java/co/elastic/clients/transport/rest5_client/low_level/Rest5ClientBuilder.java +++ b/java-client/src/main/java/co/elastic/clients/transport/rest5_client/low_level/Rest5ClientBuilder.java @@ -46,6 +46,7 @@ import java.util.concurrent.ThreadFactory; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicLong; +import java.util.function.Consumer; import static co.elastic.clients.transport.rest5_client.low_level.LanguageRuntimeVersions.getRuntimeMetadata; @@ -75,7 +76,7 @@ public final class Rest5ClientBuilder { private final List nodes; private CloseableHttpAsyncClient httpClient; - private HttpClientConfigCallback httpClientConfigCallback; + private Consumer httpClientConfigCallback; private Header[] defaultHeaders = EMPTY_HEADERS; private Rest5Client.FailureListener failureListener; private SSLContext sslContext; @@ -322,35 +323,20 @@ public Rest5ClientBuilder setMetaHeaderEnabled(boolean metadataEnabled) { } /** - * Sets the {@link HttpClientConfigCallback} to be used to customize http client configuration - * + * Allows to customize the {@link CloseableHttpAsyncClient} being created and used by the + * {@link Rest5Client}. + * Commonly used to customize {@link HttpAsyncClientBuilder} without losing any other useful default + * value that the {@link Rest5ClientBuilder} internally sets, except if RequestConfig, + * ConnectionConfig and ConnectionManager are set through this callback. + * In those cases, all default values set by the {@link Rest5ClientBuilder} are lost. * @throws NullPointerException if {@code httpClientConfigCallback} is {@code null}. */ - public Rest5ClientBuilder setHttpClientConfigCallback(HttpClientConfigCallback httpClientConfigCallback) { + public Rest5ClientBuilder setHttpClientConfigCallback(Consumer httpClientConfigCallback) { Objects.requireNonNull(httpClientConfigCallback, "httpClientConfigCallback must not be null"); this.httpClientConfigCallback = httpClientConfigCallback; return this; } - /** - * Callback used to customize the {@link CloseableHttpAsyncClient} instance used by a - * {@link Rest5Client} instance. - * Allows to customize default {@link RequestConfig} being set to the client and any parameter that - * can be set through {@link HttpAsyncClientBuilder} - */ - public interface HttpClientConfigCallback { - /** - * Allows to customize the {@link CloseableHttpAsyncClient} being created and used by the - * {@link Rest5Client}. - * Commonly used to customize {@link HttpAsyncClientBuilder} without losing any other useful default - * value that the {@link Rest5ClientBuilder} internally sets, except if RequestConfig, - * ConnectionConfig - * and ConnectionManager are set through this callback. - * In those cases, all default values set by the {@link Rest5ClientBuilder} are lost. - */ - HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpClientBuilder); - } - /** * Creates a new {@link Rest5Client} based on the provided configuration. */ @@ -439,7 +425,7 @@ private CloseableHttpAsyncClient createHttpClient() { httpClientBuilder.setRoutePlanner(this.routePlanner); } if (httpClientConfigCallback != null) { - httpClientBuilder = httpClientConfigCallback.customizeHttpClient(httpClientBuilder); + httpClientConfigCallback.accept(httpClientBuilder); } return httpClientBuilder.build(); diff --git a/java-client/src/test/java/co/elastic/clients/documentation/rest5_client/RestClientDocumentation.java b/java-client/src/test/java/co/elastic/clients/documentation/rest5_client/RestClientDocumentation.java index fb8756033..6a06d349d 100644 --- a/java-client/src/test/java/co/elastic/clients/documentation/rest5_client/RestClientDocumentation.java +++ b/java-client/src/test/java/co/elastic/clients/documentation/rest5_client/RestClientDocumentation.java @@ -31,6 +31,7 @@ import co.elastic.clients.transport.rest5_client.low_level.Rest5ClientBuilder; import org.apache.hc.client5.http.config.RequestConfig; import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient; +import org.apache.hc.client5.http.impl.async.HttpAsyncClientBuilder; import org.apache.hc.client5.http.impl.async.HttpAsyncClients; import org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManager; import org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManagerBuilder; @@ -183,13 +184,11 @@ public void onFailure(Node node) { .setMaxConnPerRoute(5) .build(); - CloseableHttpAsyncClient httpclient = HttpAsyncClients.custom() - .setConnectionManager(connectionManager) - .build(); - Rest5ClientBuilder builder = Rest5Client .builder(new HttpHost("http", "localhost", 9200)) - .setHttpClient(httpclient); + .setHttpClientConfigCallback(c -> c + .setConnectionManager(connectionManager) + ); //end::rest-client-init-request-config-callback } @@ -319,13 +318,10 @@ public void commonConfiguration() throws Exception { RequestConfig.Builder requestConfigBuilder = RequestConfig.custom() .setConnectTimeout(Timeout.of(5000, TimeUnit.MILLISECONDS)); - CloseableHttpAsyncClient httpclient = HttpAsyncClients.custom() - .setDefaultRequestConfig(requestConfigBuilder.build()) - .build(); - Rest5ClientBuilder builder = Rest5Client .builder(new HttpHost("localhost", 9200)) - .setHttpClient(httpclient); + .setHttpClientConfigCallback(c -> c + .setDefaultRequestConfig(requestConfigBuilder.build())); //end::rest-client-config-timeouts } { @@ -342,15 +338,12 @@ public void commonConfiguration() throws Exception { } { //tag::rest-client-config-threads - CloseableHttpAsyncClient httpclient = HttpAsyncClients.custom() - .setIOReactorConfig( - IOReactorConfig.custom().setIoThreadCount(1).build() - ) - .build(); Rest5ClientBuilder builder = Rest5Client .builder(new HttpHost("localhost", 9200)) - .setHttpClient(httpclient); + .setHttpClientConfigCallback(c -> c + .setIOReactorConfig(IOReactorConfig.custom().setIoThreadCount(1).build() + )); //end::rest-client-config-threads } { @@ -372,13 +365,9 @@ public void commonConfiguration() throws Exception { var creds = Base64.getEncoder().encodeToString("user:test-user-password".getBytes()); - CloseableHttpAsyncClient httpclient = HttpAsyncClients.custom() - .disableAuthCaching() // <1> - .build(); - Rest5ClientBuilder restClient = Rest5Client .builder(new HttpHost("https", "localhost", 9200)) - .setHttpClient(httpclient) + .setHttpClientConfigCallback(HttpAsyncClientBuilder::disableAuthCaching) // <1> .setDefaultHeaders(new Header[]{ new BasicHeader("Authorization", "Basic " + creds) }); From d1a386a0214fa45246e79999a3b828215f040537 Mon Sep 17 00:00:00 2001 From: Laura Trotta Date: Tue, 15 Jul 2025 15:49:52 +0200 Subject: [PATCH 3/4] checkstyle --- .../documentation/rest5_client/RestClientDocumentation.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/java-client/src/test/java/co/elastic/clients/documentation/rest5_client/RestClientDocumentation.java b/java-client/src/test/java/co/elastic/clients/documentation/rest5_client/RestClientDocumentation.java index 6a06d349d..9e539b2d2 100644 --- a/java-client/src/test/java/co/elastic/clients/documentation/rest5_client/RestClientDocumentation.java +++ b/java-client/src/test/java/co/elastic/clients/documentation/rest5_client/RestClientDocumentation.java @@ -30,9 +30,7 @@ import co.elastic.clients.transport.rest5_client.low_level.Rest5Client; import co.elastic.clients.transport.rest5_client.low_level.Rest5ClientBuilder; import org.apache.hc.client5.http.config.RequestConfig; -import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient; import org.apache.hc.client5.http.impl.async.HttpAsyncClientBuilder; -import org.apache.hc.client5.http.impl.async.HttpAsyncClients; import org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManager; import org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManagerBuilder; import org.apache.hc.core5.http.ContentType; From 951124f94d502bd45c4a477bb21d47b8a3c04f3f Mon Sep 17 00:00:00 2001 From: Laura Trotta Date: Tue, 15 Jul 2025 17:55:58 +0200 Subject: [PATCH 4/4] more callbacks --- .../transport/rest5-client/config/timeouts.md | 12 ++- .../low_level/Rest5ClientBuilder.java | 81 +++++++++++++++---- 2 files changed, 70 insertions(+), 23 deletions(-) diff --git a/docs/reference/transport/rest5-client/config/timeouts.md b/docs/reference/transport/rest5-client/config/timeouts.md index b5747ac44..4151dfcee 100644 --- a/docs/reference/transport/rest5-client/config/timeouts.md +++ b/docs/reference/transport/rest5-client/config/timeouts.md @@ -1,18 +1,16 @@ # Timeouts -Configuring requests timeouts can be done by using the `setHttpClientConfigCallback` method while building the `RestClient` and then calling `setDefaultRequestConfig`. In the following example we increase the connect timeout (defaults to 30 second) and the response timeout (defaults to 0, which is infinite). +Configuring requests timeouts can be done by using the `setRequestConfigCallback` method while building the `RestClient`. In the following example we increase the connect timeout (defaults to 30 second) and the response timeout (defaults to 0, which is infinite). % :::{include-code} src={{doc-tests-src}}/rest5_client/RestClientDocumentation.java tag=rest-client-config-timeouts ```java Rest5ClientBuilder builder = Rest5Client .builder(new HttpHost("localhost", 9200)) - .setHttpClientConfigCallback(c -> c - .setDefaultRequestConfig(RequestConfig.custom() - .setConnectTimeout(Timeout.of(5000, TimeUnit.MILLISECONDS)) - .setResponseTimeout(Timeout.of(30000, TimeUnit.MILLISECONDS)) - .build() - ) + .setRequestConfigCallback(r -> r + .setConnectTimeout(Timeout.of(5000, TimeUnit.MILLISECONDS)) + .setResponseTimeout(Timeout.of(30000, TimeUnit.MILLISECONDS)) + .build() ); ``` diff --git a/java-client/src/main/java/co/elastic/clients/transport/rest5_client/low_level/Rest5ClientBuilder.java b/java-client/src/main/java/co/elastic/clients/transport/rest5_client/low_level/Rest5ClientBuilder.java index e00ce69b0..e093efe78 100644 --- a/java-client/src/main/java/co/elastic/clients/transport/rest5_client/low_level/Rest5ClientBuilder.java +++ b/java-client/src/main/java/co/elastic/clients/transport/rest5_client/low_level/Rest5ClientBuilder.java @@ -77,6 +77,9 @@ public final class Rest5ClientBuilder { private final List nodes; private CloseableHttpAsyncClient httpClient; private Consumer httpClientConfigCallback; + private Consumer requestConfigCallback; + private Consumer connectionConfigCallback; + private Consumer connectionManagerCallback; private Header[] defaultHeaders = EMPTY_HEADERS; private Rest5Client.FailureListener failureListener; private SSLContext sslContext; @@ -326,9 +329,7 @@ public Rest5ClientBuilder setMetaHeaderEnabled(boolean metadataEnabled) { * Allows to customize the {@link CloseableHttpAsyncClient} being created and used by the * {@link Rest5Client}. * Commonly used to customize {@link HttpAsyncClientBuilder} without losing any other useful default - * value that the {@link Rest5ClientBuilder} internally sets, except if RequestConfig, - * ConnectionConfig and ConnectionManager are set through this callback. - * In those cases, all default values set by the {@link Rest5ClientBuilder} are lost. + * value that the {@link Rest5ClientBuilder} internally sets. * @throws NullPointerException if {@code httpClientConfigCallback} is {@code null}. */ public Rest5ClientBuilder setHttpClientConfigCallback(Consumer httpClientConfigCallback) { @@ -337,6 +338,45 @@ public Rest5ClientBuilder setHttpClientConfigCallback(Consumer requestConfigCallback) { + Objects.requireNonNull(requestConfigCallback, "requestConfigCallback must not be null"); + this.requestConfigCallback = requestConfigCallback; + return this; + } + + /** + * Allows to customize the {@link ConnectionConfig} created by the {@link Rest5Client} + * and used by the {@link CloseableHttpAsyncClient}. + * Commonly used to customize {@link ConnectionConfig} without losing any other useful default + * value that the {@link Rest5ClientBuilder} internally sets. + * @throws NullPointerException if {@code connectionConfigCallback} is {@code null}. + */ + public Rest5ClientBuilder setConnectionConfigCallback(Consumer connectionConfigCallback) { + Objects.requireNonNull(connectionConfigCallback, "connectionConfigCallback must not be null"); + this.connectionConfigCallback = connectionConfigCallback; + return this; + } + + /** + * Allows to customize the {@link PoolingAsyncClientConnectionManager} created by the {@link Rest5Client} + * and used by the {@link CloseableHttpAsyncClient}. + * Commonly used to customize {@link PoolingAsyncClientConnectionManager} without losing any other useful default + * value that the {@link Rest5ClientBuilder} internally sets. + * @throws NullPointerException if {@code connectionManagerCallback} is {@code null}. + */ + public Rest5ClientBuilder setConnectionManagerCallback(Consumer connectionManagerCallback) { + Objects.requireNonNull(connectionManagerCallback, "connectionManagerCallback must not be null"); + this.connectionManagerCallback = connectionManagerCallback; + return this; + } + /** * Creates a new {@link Rest5Client} based on the provided configuration. */ @@ -386,31 +426,40 @@ private CloseableHttpAsyncClient createHttpClient() { return this.httpClient; } // otherwise, creating a default instance of CloseableHttpAsyncClient - // default timeouts are all 3 mins - RequestConfig requestConfigBuilder = RequestConfig.custom() + + // default timeouts are all 3 mins, replacing those + RequestConfig.Builder requestConfigBuilder = RequestConfig.custom() .setConnectionRequestTimeout(Timeout.of(DEFAULT_SOCKET_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS)) - .setResponseTimeout(Timeout.of(DEFAULT_RESPONSE_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS)) - .build(); + .setResponseTimeout(Timeout.of(DEFAULT_RESPONSE_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS)); + + if (requestConfigCallback != null) { + requestConfigCallback.accept(requestConfigBuilder); + } try { SSLContext sslContext = this.sslContext != null ? this.sslContext : SSLContext.getDefault(); - ConnectionConfig connectionConfig = ConnectionConfig.custom() - .setConnectTimeout(Timeout.of(DEFAULT_CONNECT_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS)) - .build(); + ConnectionConfig.Builder connectionConfigBuilder = ConnectionConfig.custom() + .setConnectTimeout(Timeout.of(DEFAULT_CONNECT_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS)); + if (connectionConfigCallback != null) { + connectionConfigCallback.accept(connectionConfigBuilder); + } - PoolingAsyncClientConnectionManager defaultConnectionManager = + PoolingAsyncClientConnectionManagerBuilder connectionManagerBuilder = PoolingAsyncClientConnectionManagerBuilder.create() - .setDefaultConnectionConfig(connectionConfig) + .setDefaultConnectionConfig(connectionConfigBuilder.build()) .setMaxConnPerRoute(DEFAULT_MAX_CONN_PER_ROUTE) .setMaxConnTotal(DEFAULT_MAX_CONN_TOTAL) - .setTlsStrategy(new BasicClientTlsStrategy(sslContext)) - .build(); + .setTlsStrategy(new BasicClientTlsStrategy(sslContext)); + + if (connectionManagerCallback != null) { + connectionManagerCallback.accept(connectionManagerBuilder); + } HttpAsyncClientBuilder httpClientBuilder = HttpAsyncClientBuilder.create() - .setDefaultRequestConfig(requestConfigBuilder) - .setConnectionManager(defaultConnectionManager) + .setDefaultRequestConfig(requestConfigBuilder.build()) + .setConnectionManager(connectionManagerBuilder.build()) .setUserAgent(USER_AGENT_HEADER_VALUE) .setTargetAuthenticationStrategy(new DefaultAuthenticationStrategy()) .setThreadFactory(new RestClientThreadFactory());