diff options
author | Thomas <> | 2024-03-28 18:46:16 +0100 |
---|---|---|
committer | Thomas <> | 2024-03-28 18:46:16 +0100 |
commit | 285dcb02c86ee06c7b86a4b56dc1a78b15c17ad2 (patch) | |
tree | 04bc75b8ef4a4bd4f64ba115a4257296f678acf2 | |
parent | d233142006490a667d0d5b83e768fd27172e5122 (diff) | |
download | EAAF-Components-285dcb02c86ee06c7b86a4b56dc1a78b15c17ad2.tar.gz EAAF-Components-285dcb02c86ee06c7b86a4b56dc1a78b15c17ad2.tar.bz2 EAAF-Components-285dcb02c86ee06c7b86a4b56dc1a78b15c17ad2.zip |
feat(http): add configuration parameter to set 'time-to-life' and 'validation-after-inactivity' for ConnectionPool
5 files changed, 70 insertions, 17 deletions
diff --git a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/http/HttpClientFactory.java b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/http/HttpClientFactory.java index f929c7eb..04dd36cb 100644 --- a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/http/HttpClientFactory.java +++ b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/http/HttpClientFactory.java @@ -47,6 +47,7 @@ import at.gv.egiz.eaaf.core.impl.credential.EaafKeyStoreFactory; import at.gv.egiz.eaaf.core.impl.credential.KeyStoreConfiguration.KeyStoreType; import at.gv.egiz.eaaf.core.impl.data.Pair; import at.gv.egiz.eaaf.core.impl.http.interceptor.PreemptiveAuthInterceptor; +import at.gv.egiz.eaaf.core.impl.utils.ConfigurationUtils; import jakarta.annotation.Nonnull; import jakarta.annotation.PostConstruct; import lombok.extern.slf4j.Slf4j; @@ -63,6 +64,10 @@ public class HttpClientFactory implements IHttpClientFactory { "client.http.connection.pool.use"; public static final String PROP_CONFIG_CLIENT_HTTP_CONNECTION_POOL_MAXTOTAL = "client.http.connection.pool.maxtotal"; + public static final String PROP_CONFIG_CLIENT_HTTP_CONNECTION_POOL_TIMETOLIFE = + "client.http.connection.pool.timetolife"; + public static final String PROP_CONFIG_CLIENT_HTTP_CONNECTION_POOL_VALIDATION_INACTIVITY = + "client.http.connection.pool.validationafterinactivity"; public static final String PROP_CONFIG_CLIENT_HTTP_CONNECTION_POOL_MAXPERROUTE = "client.http.connection.pool.maxperroute"; public static final String PROP_CONFIG_CLIENT_HTTP_CONNECTION_TIMEOUT_SOCKET = @@ -95,17 +100,14 @@ public class HttpClientFactory implements IHttpClientFactory { // default configuration values public static final String DEFAULT_CONFIG_CLIENT_HTTP_CONNECTION_TIMEOUT_SOCKET = "15"; public static final String DEFAULT_CONFIG_CLIENT_HTTP_CONNECTION_TIMEOUT_CONNECTION = "15"; + public static final String DEFAULT_CONFIG_CLIENT_HTTP_CONNECTION_POOL_VALIDATION_INACTIVITY = "2"; public static final String DEFAULT_CONFIG_CLIENT_HTTP_CONNECTION_TIMEOUT_REQUEST = "30"; public static final String DEFAULT_CONFIG_CLIENT_HTTP_CONNECTION_POOL_MAXTOTAL = "500"; public static final String DEFAULT_CONFIG_CLIENT_HTTP_CONNECTION_POOL_MAXPERROUTE = "100"; public static final String DEFAULT_CONFIG_CLIENT_HTTP_CONNECTION_RETRY_COUNT = "3"; - public static final int DEFAULT_CLEANUP_RUNNER_TIME = 30000; public static final int DEFAULT_CLEANUP_IDLE_TIME = 60; - public static final TimeValue CLEANUP_IDLE_TIME = - TimeValue.of(DEFAULT_CLEANUP_IDLE_TIME, TimeUnit.SECONDS); - private String defaultConfigurationId = null; private final Map<String, Pair<HttpClientBuilder, HttpClientConnectionManager>> availableBuilders = new HashMap<>(); @@ -340,28 +342,41 @@ public class HttpClientFactory implements IHttpClientFactory { @Nonnull private HttpClientConnectionManager injectConnectionManager( - HttpClientBuilder builder, final LayeredConnectionSocketFactory sslConnectionFactory) { + HttpClientBuilder builder, final LayeredConnectionSocketFactory sslConnectionFactory) + throws EaafConfigurationException { if (basicConfig.getBasicConfigurationBoolean(PROP_CONFIG_CLIENT_HTTP_CONNECTION_POOL_USE, true)) { + + final TimeValue timeToLife = TimeValue.of(ConfigurationUtils.parseInteger( + basicConfig, PROP_CONFIG_CLIENT_HTTP_CONNECTION_POOL_TIMETOLIFE, DEFAULT_CLEANUP_IDLE_TIME), + TimeUnit.SECONDS); + log.debug("Set {} seconds as time-to-life for pooled http connections"); + final PoolingHttpClientConnectionManager connectionPool = new PoolingHttpClientConnectionManager( getDefaultRegistry(sslConnectionFactory), - PoolConcurrencyPolicy.STRICT, CLEANUP_IDLE_TIME, null); + PoolConcurrencyPolicy.STRICT, timeToLife, null); connectionPool.setDefaultMaxPerRoute(Integer.parseInt( basicConfig.getBasicConfiguration(PROP_CONFIG_CLIENT_HTTP_CONNECTION_POOL_MAXPERROUTE, DEFAULT_CONFIG_CLIENT_HTTP_CONNECTION_POOL_MAXPERROUTE))); connectionPool.setMaxTotal(Integer.parseInt( basicConfig.getBasicConfiguration(PROP_CONFIG_CLIENT_HTTP_CONNECTION_POOL_MAXTOTAL, DEFAULT_CONFIG_CLIENT_HTTP_CONNECTION_POOL_MAXTOTAL))); - connectionPool.setDefaultSocketConfig(SocketConfig.custom().setSoTimeout( - Integer.parseInt( - basicConfig.getBasicConfiguration( - PROP_CONFIG_CLIENT_HTTP_CONNECTION_TIMEOUT_SOCKET, - DEFAULT_CONFIG_CLIENT_HTTP_CONNECTION_TIMEOUT_SOCKET)), TimeUnit.SECONDS).build()); + connectionPool.setDefaultSocketConfig(SocketConfig.custom() + .setSoTimeout( + Integer.parseInt( + basicConfig.getBasicConfiguration( + PROP_CONFIG_CLIENT_HTTP_CONNECTION_TIMEOUT_SOCKET, + DEFAULT_CONFIG_CLIENT_HTTP_CONNECTION_TIMEOUT_SOCKET)), TimeUnit.SECONDS) + .build()); connectionPool.setDefaultConnectionConfig(ConnectionConfig.custom() - .setConnectTimeout( - Long.parseLong(basicConfig.getBasicConfiguration( + .setConnectTimeout(Long.parseLong( + basicConfig.getBasicConfiguration( PROP_CONFIG_CLIENT_HTTP_CONNECTION_TIMEOUT_CONNECTION, DEFAULT_CONFIG_CLIENT_HTTP_CONNECTION_TIMEOUT_CONNECTION)), TimeUnit.SECONDS) + .setValidateAfterInactivity(Integer.parseInt( + basicConfig.getBasicConfiguration( + PROP_CONFIG_CLIENT_HTTP_CONNECTION_POOL_VALIDATION_INACTIVITY, + DEFAULT_CONFIG_CLIENT_HTTP_CONNECTION_POOL_VALIDATION_INACTIVITY)), TimeUnit.SECONDS) .build()); @@ -374,6 +389,23 @@ public class HttpClientFactory implements IHttpClientFactory { log.debug("Building http-client without Connection-Pool ... "); final BasicHttpClientConnectionManager basicPool = new BasicHttpClientConnectionManager( getDefaultRegistry(sslConnectionFactory)); + + basicPool.setSocketConfig(SocketConfig.custom() + .setSoTimeout( + Integer.parseInt( + basicConfig.getBasicConfiguration( + PROP_CONFIG_CLIENT_HTTP_CONNECTION_TIMEOUT_SOCKET, + DEFAULT_CONFIG_CLIENT_HTTP_CONNECTION_TIMEOUT_SOCKET)), TimeUnit.SECONDS) + .build()); + basicPool.setConnectionConfig(ConnectionConfig.custom() + .setConnectTimeout( + Long.parseLong(basicConfig.getBasicConfiguration( + PROP_CONFIG_CLIENT_HTTP_CONNECTION_TIMEOUT_CONNECTION, + DEFAULT_CONFIG_CLIENT_HTTP_CONNECTION_TIMEOUT_CONNECTION)), TimeUnit.SECONDS) + .build()); + + + builder.setConnectionManager(basicPool); return basicPool; diff --git a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/http/HttpUtils.java b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/http/HttpUtils.java index 491d641f..0faa94f4 100644 --- a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/http/HttpUtils.java +++ b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/http/HttpUtils.java @@ -258,7 +258,7 @@ public class HttpUtils { } /** - * Initialize a {@link SSLContext} + * Initialize a {@link SSLContext}. * * @param trustAllServerCertificates Deactivate SSL server-certificate * validation diff --git a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/ConfigurationUtils.java b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/ConfigurationUtils.java index 2e6d53c9..81de9762 100644 --- a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/ConfigurationUtils.java +++ b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/ConfigurationUtils.java @@ -36,6 +36,28 @@ public class ConfigurationUtils { } /** + * Parse Integer value from configuration. + * + * @param basicConfig Configuration object + * @param propertyKey Configuration key + * @param defaultValue Default value of configuration-key does not exist + * @return Configuration value + * @throws EaafConfigurationException If configuration value is not an Integer + */ + public static int parseInteger(IConfiguration basicConfig, String propertyKey, int defaultValue) + throws EaafConfigurationException { + try { + return Integer.parseInt(basicConfig.getBasicConfiguration(propertyKey, String.valueOf(defaultValue))); + + } catch (NumberFormatException e) { + log.error("Can not read Integer value from configuration: {}", propertyKey, e); + throw new EaafConfigurationException("internal.configuration.02", + new Object[] { propertyKey, Integer.class.getSimpleName() }, e); + + } + } + + /** * Parse Long value from configuration. * * @param basicConfig Configuration object diff --git a/eaaf_core_utils/src/test/java/at/gv/egiz/eaaf/core/test/http/HttpClientFactoryTest.java b/eaaf_core_utils/src/test/java/at/gv/egiz/eaaf/core/test/http/HttpClientFactoryTest.java index 493d966b..7f0240ef 100644 --- a/eaaf_core_utils/src/test/java/at/gv/egiz/eaaf/core/test/http/HttpClientFactoryTest.java +++ b/eaaf_core_utils/src/test/java/at/gv/egiz/eaaf/core/test/http/HttpClientFactoryTest.java @@ -18,8 +18,6 @@ import java.security.Provider; import java.security.UnrecoverableKeyException; import java.security.cert.X509Certificate; -import javax.net.ssl.SSLHandshakeException; - import org.apache.commons.lang3.RandomStringUtils; import org.apache.hc.client5.http.ClientProtocolException; import org.apache.hc.client5.http.classic.methods.HttpGet; @@ -278,7 +276,7 @@ public class HttpClientFactoryTest { // perform test request final HttpUriRequest httpGet2 = new HttpGet(mockServerUrl.url().toString()); - assertThrows(SSLHandshakeException.class, () -> client.execute(httpGet2)); + assertThrows(Exception.class, () -> client.execute(httpGet2)); } diff --git a/eaaf_core_utils/src/test/resources/data/config1.properties b/eaaf_core_utils/src/test/resources/data/config1.properties index 12209d21..1bcc1fb3 100644 --- a/eaaf_core_utils/src/test/resources/data/config1.properties +++ b/eaaf_core_utils/src/test/resources/data/config1.properties @@ -4,6 +4,7 @@ security.hsmfacade.trustedsslcert=src/test/resources/data/hsm_facade_trust_root. security.hsmfacade.username=authhandler-junit security.hsmfacade.password=supersecret123 +client.http.connection.pool.use=true client.http.connection.timeout.socket=2 client.http.connection.timeout.connection=2 client.http.connection.timeout.request=2 |