From 8e3a33de2922f0005cb4f37bf6cf3bde82cc4b38 Mon Sep 17 00:00:00 2001 From: Olga Maciaszek-Sharma Date: Wed, 8 Jan 2025 12:43:26 +0100 Subject: [PATCH] Add possibility to customise HC5 RequestConfig. Signed-off-by: Olga Maciaszek-Sharma --- ...urekaClientHttpRequestFactorySupplier.java | 52 ++++++++++++++----- ...urekaClientHttpRequestFactorySupplier.java | 8 +++ 2 files changed, 47 insertions(+), 13 deletions(-) diff --git a/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/http/DefaultEurekaClientHttpRequestFactorySupplier.java b/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/http/DefaultEurekaClientHttpRequestFactorySupplier.java index ab368a522..98dfdaab6 100644 --- a/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/http/DefaultEurekaClientHttpRequestFactorySupplier.java +++ b/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/http/DefaultEurekaClientHttpRequestFactorySupplier.java @@ -16,11 +16,15 @@ package org.springframework.cloud.netflix.eureka.http; +import java.util.Collections; +import java.util.Optional; +import java.util.Set; import java.util.concurrent.TimeUnit; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.SSLContext; +import org.apache.hc.client5.http.config.ConnectionConfig; import org.apache.hc.client5.http.config.RequestConfig; import org.apache.hc.client5.http.impl.classic.CloseableHttpClient; import org.apache.hc.client5.http.impl.classic.HttpClientBuilder; @@ -31,6 +35,7 @@ import org.apache.hc.client5.http.ssl.SSLConnectionSocketFactoryBuilder; import org.apache.hc.core5.http.io.SocketConfig; import org.apache.hc.core5.util.Timeout; +import org.springframework.beans.factory.ObjectProvider; import org.springframework.cloud.netflix.eureka.RestTemplateTimeoutProperties; import org.springframework.cloud.netflix.eureka.TimeoutProperties; import org.springframework.http.client.ClientHttpRequestFactory; @@ -49,10 +54,12 @@ import org.springframework.lang.Nullable; public class DefaultEurekaClientHttpRequestFactorySupplier implements EurekaClientHttpRequestFactorySupplier { private final TimeoutProperties timeoutProperties; + // TODO: switch to final after removing deprecated interfaces + private ObjectProvider> requestConfigCustomizers; /** * @deprecated in favour of - * {@link DefaultEurekaClientHttpRequestFactorySupplier#DefaultEurekaClientHttpRequestFactorySupplier(TimeoutProperties)} + * {@link DefaultEurekaClientHttpRequestFactorySupplier#DefaultEurekaClientHttpRequestFactorySupplier(TimeoutProperties, ObjectProvider)} */ @Deprecated(forRemoval = true) public DefaultEurekaClientHttpRequestFactorySupplier() { @@ -61,17 +68,28 @@ public class DefaultEurekaClientHttpRequestFactorySupplier implements EurekaClie /** * @deprecated in favour of - * {@link DefaultEurekaClientHttpRequestFactorySupplier#DefaultEurekaClientHttpRequestFactorySupplier(TimeoutProperties)} + * {@link DefaultEurekaClientHttpRequestFactorySupplier#DefaultEurekaClientHttpRequestFactorySupplier(TimeoutProperties, ObjectProvider)} */ @Deprecated(forRemoval = true) public DefaultEurekaClientHttpRequestFactorySupplier(RestTemplateTimeoutProperties timeoutProperties) { this.timeoutProperties = timeoutProperties; } + /** + * @deprecated in favour of + * {@link DefaultEurekaClientHttpRequestFactorySupplier#DefaultEurekaClientHttpRequestFactorySupplier(TimeoutProperties, ObjectProvider)} + */ + @Deprecated(forRemoval = true) public DefaultEurekaClientHttpRequestFactorySupplier(TimeoutProperties timeoutProperties) { this.timeoutProperties = timeoutProperties; } + public DefaultEurekaClientHttpRequestFactorySupplier(TimeoutProperties timeoutProperties, + ObjectProvider> requestConfigCustomizers) { + this.timeoutProperties = timeoutProperties; + this.requestConfigCustomizers = requestConfigCustomizers; + } + @Override public ClientHttpRequestFactory get(SSLContext sslContext, @Nullable HostnameVerifier hostnameVerifier) { HttpClientBuilder httpClientBuilder = HttpClientBuilder.create(); @@ -79,9 +97,7 @@ public class DefaultEurekaClientHttpRequestFactorySupplier implements EurekaClie httpClientBuilder .setConnectionManager(buildConnectionManager(sslContext, hostnameVerifier, timeoutProperties)); } - if (timeoutProperties != null) { - httpClientBuilder.setDefaultRequestConfig(buildRequestConfig()); - } + httpClientBuilder.setDefaultRequestConfig(buildRequestConfig()); CloseableHttpClient httpClient = httpClientBuilder.build(); HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(); @@ -90,7 +106,7 @@ public class DefaultEurekaClientHttpRequestFactorySupplier implements EurekaClie } private HttpClientConnectionManager buildConnectionManager(SSLContext sslContext, HostnameVerifier hostnameVerifier, - TimeoutProperties restTemplateTimeoutProperties) { + TimeoutProperties timeoutProperties) { PoolingHttpClientConnectionManagerBuilder connectionManagerBuilder = PoolingHttpClientConnectionManagerBuilder .create(); SSLConnectionSocketFactoryBuilder sslConnectionSocketFactoryBuilder = SSLConnectionSocketFactoryBuilder @@ -102,20 +118,30 @@ public class DefaultEurekaClientHttpRequestFactorySupplier implements EurekaClie sslConnectionSocketFactoryBuilder.setHostnameVerifier(hostnameVerifier); } connectionManagerBuilder.setSSLSocketFactory(sslConnectionSocketFactoryBuilder.build()); - if (restTemplateTimeoutProperties != null) { + if (timeoutProperties != null) { connectionManagerBuilder.setDefaultSocketConfig(SocketConfig.custom() - .setSoTimeout(Timeout.of(restTemplateTimeoutProperties.getSocketTimeout(), TimeUnit.MILLISECONDS)) + .setSoTimeout(Timeout.of(timeoutProperties.getSocketTimeout(), TimeUnit.MILLISECONDS)) .build()); + connectionManagerBuilder.setDefaultConnectionConfig(ConnectionConfig.custom(). + setConnectTimeout(Timeout.of(timeoutProperties.getConnectTimeout(), + TimeUnit.MILLISECONDS)).build() + ); } return connectionManagerBuilder.build(); } private RequestConfig buildRequestConfig() { - return RequestConfig.custom() - .setConnectTimeout(Timeout.of(timeoutProperties.getConnectTimeout(), TimeUnit.MILLISECONDS)) - .setConnectionRequestTimeout( - Timeout.of(timeoutProperties.getConnectRequestTimeout(), TimeUnit.MILLISECONDS)) - .build(); + RequestConfig.Builder requestConfigBuilder = RequestConfig.custom(); + if (timeoutProperties != null) { + requestConfigBuilder.setConnectionRequestTimeout( + Timeout.of(timeoutProperties.getConnectRequestTimeout(), TimeUnit.MILLISECONDS)); + } + Optional.ofNullable(requestConfigCustomizers).ifPresent( + requestConfigCustomizers -> + requestConfigCustomizers + .getIfAvailable(Collections::emptySet) + .forEach(customizer -> customizer.customize(requestConfigBuilder))); + return requestConfigBuilder.build(); } } diff --git a/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/http/EurekaClientHttpRequestFactorySupplier.java b/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/http/EurekaClientHttpRequestFactorySupplier.java index b5a104c3c..9ef5302f7 100644 --- a/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/http/EurekaClientHttpRequestFactorySupplier.java +++ b/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/http/EurekaClientHttpRequestFactorySupplier.java @@ -19,6 +19,8 @@ package org.springframework.cloud.netflix.eureka.http; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.SSLContext; +import org.apache.hc.client5.http.config.RequestConfig; + import org.springframework.http.client.ClientHttpRequestFactory; import org.springframework.lang.Nullable; @@ -38,4 +40,10 @@ public interface EurekaClientHttpRequestFactorySupplier { */ ClientHttpRequestFactory get(SSLContext sslContext, @Nullable HostnameVerifier hostnameVerifier); + interface RequestConfigCustomizer { + + void customize(RequestConfig.Builder builder); + + } + }