diff options
Diffstat (limited to 'eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/http/HttpClientFactory.java')
-rw-r--r-- | eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/http/HttpClientFactory.java | 204 |
1 files changed, 91 insertions, 113 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 f2955482..715b0c96 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 @@ -1,10 +1,10 @@ package at.gv.egiz.eaaf.core.impl.http; +import java.net.URI; import java.security.KeyStore; import java.security.Provider; import java.util.HashMap; import java.util.Map; -import java.util.Map.Entry; import java.util.concurrent.TimeUnit; import javax.annotation.Nonnull; @@ -13,35 +13,34 @@ import javax.net.ssl.HostnameVerifier; import javax.net.ssl.SSLContext; import org.apache.commons.lang3.StringUtils; -import org.apache.http.HttpRequest; -import org.apache.http.HttpResponse; -import org.apache.http.ProtocolException; -import org.apache.http.auth.AuthScope; -import org.apache.http.auth.UsernamePasswordCredentials; -import org.apache.http.client.CredentialsProvider; -import org.apache.http.client.RedirectStrategy; -import org.apache.http.client.config.RequestConfig; -import org.apache.http.client.methods.HttpUriRequest; -import org.apache.http.config.Registry; -import org.apache.http.config.RegistryBuilder; -import org.apache.http.config.SocketConfig; -import org.apache.http.conn.HttpClientConnectionManager; -import org.apache.http.conn.socket.ConnectionSocketFactory; -import org.apache.http.conn.socket.LayeredConnectionSocketFactory; -import org.apache.http.conn.socket.PlainConnectionSocketFactory; -import org.apache.http.conn.ssl.NoopHostnameVerifier; -import org.apache.http.conn.ssl.SSLConnectionSocketFactory; -import org.apache.http.impl.client.BasicCredentialsProvider; -import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.impl.client.DefaultRedirectStrategy; -import org.apache.http.impl.client.HttpClientBuilder; -import org.apache.http.impl.client.HttpClients; -import org.apache.http.impl.conn.BasicHttpClientConnectionManager; -import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; -import org.apache.http.protocol.HttpContext; -import org.apache.http.ssl.SSLContexts; +import org.apache.hc.client5.http.auth.AuthScope; +import org.apache.hc.client5.http.auth.UsernamePasswordCredentials; +import org.apache.hc.client5.http.config.ConnectionConfig; +import org.apache.hc.client5.http.config.RequestConfig; +import org.apache.hc.client5.http.impl.DefaultRedirectStrategy; +import org.apache.hc.client5.http.impl.auth.BasicCredentialsProvider; +import org.apache.hc.client5.http.impl.classic.CloseableHttpClient; +import org.apache.hc.client5.http.impl.classic.HttpClientBuilder; +import org.apache.hc.client5.http.impl.classic.HttpClients; +import org.apache.hc.client5.http.impl.io.BasicHttpClientConnectionManager; +import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager; +import org.apache.hc.client5.http.io.HttpClientConnectionManager; +import org.apache.hc.client5.http.protocol.RedirectStrategy; +import org.apache.hc.client5.http.socket.ConnectionSocketFactory; +import org.apache.hc.client5.http.socket.LayeredConnectionSocketFactory; +import org.apache.hc.client5.http.socket.PlainConnectionSocketFactory; +import org.apache.hc.client5.http.ssl.NoopHostnameVerifier; +import org.apache.hc.client5.http.ssl.SSLConnectionSocketFactory; +import org.apache.hc.core5.http.HttpException; +import org.apache.hc.core5.http.HttpRequest; +import org.apache.hc.core5.http.HttpResponse; +import org.apache.hc.core5.http.config.Registry; +import org.apache.hc.core5.http.config.RegistryBuilder; +import org.apache.hc.core5.http.io.SocketConfig; +import org.apache.hc.core5.http.protocol.HttpContext; +import org.apache.hc.core5.ssl.SSLContexts; +import org.apache.hc.core5.util.TimeValue; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.scheduling.annotation.Scheduled; import at.gv.egiz.eaaf.core.api.idp.IConfiguration; import at.gv.egiz.eaaf.core.exceptions.EaafConfigurationException; @@ -74,8 +73,6 @@ public class HttpClientFactory implements IHttpClientFactory { "client.http.connection.timeout.request"; public static final String PROP_CONFIG_CLIENT_HTTP_CONNECTION_RETRY_COUNT = "client.http.connection.retry.count"; - public static final String PROP_CONFIG_CLIENT_HTTP_CONNECTION_RETRY_POST = - "client.http.connection.retry.post"; public static final String PROP_CONFIG_CLIENT_HTTP_SSL_HOSTNAMEVERIFIER_TRUSTALL = "client.http.ssl.hostnameverifier.trustall"; @@ -102,15 +99,13 @@ public class HttpClientFactory implements IHttpClientFactory { 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 String DEFAUTL_CONFIG_CLIENT_HTTP_CONNECTION_RETRY_POST = String.valueOf(false); public static final int DEFAULT_CLEANUP_RUNNER_TIME = 30000; public static final int DEFAULT_CLEANUP_IDLE_TIME = 60; - - + private String defaultConfigurationId = null; - private final Map<String, Pair<HttpClientBuilder, HttpClientConnectionManager>> - availableBuilders = new HashMap<>(); + private final Map<String, Pair<HttpClientBuilder, HttpClientConnectionManager>> availableBuilders = + new HashMap<>(); /* * (non-Javadoc) @@ -156,17 +151,21 @@ public class HttpClientFactory implements IHttpClientFactory { final LayeredConnectionSocketFactory sslConnectionFactory = getSslContext(config); // set pool connection if required - HttpClientConnectionManager connectionManager - = injectConnectionManager(builder, sslConnectionFactory); + final HttpClientConnectionManager connectionManager = injectConnectionManager(builder, + sslConnectionFactory); + + // set evication for connection pool + builder.evictExpiredConnections(); + builder.evictIdleConnections(TimeValue.ofSeconds(DEFAULT_CLEANUP_IDLE_TIME)); - // set interceptor + // set interceptor if (config.getMessageInterceptors() != null) { for (int i = config.getMessageInterceptors().size() - 1; i >= 0; i--) { - builder.addInterceptorFirst(config.getMessageInterceptors().get(i)); - - } + builder.addRequestInterceptorFirst(config.getMessageInterceptors().get(i)); + + } } - + availableBuilders.put(config.getUuid(), Pair.newInstance(builder, connectionManager)); } @@ -176,38 +175,17 @@ public class HttpClientFactory implements IHttpClientFactory { } - /** - * Worker that closes expired connections or connections that in idle - * for more than DEFAULT_CLEANUP_IDLE_TIME seconds. - * - */ - @Scheduled(fixedDelay = DEFAULT_CLEANUP_RUNNER_TIME) - private void httpConnectionPoolCleaner() { - log.trace("Starting http connection-pool eviction policy ... "); - for (final Entry<String, Pair<HttpClientBuilder, HttpClientConnectionManager>> el - : availableBuilders.entrySet()) { - log.trace("Checking connections of http-client: {}", el.getKey()); - el.getValue().getSecond().closeExpiredConnections(); - el.getValue().getSecond().closeIdleConnections(DEFAULT_CLEANUP_IDLE_TIME, TimeUnit.SECONDS); - - } - - } - private void injectInternalRetryHandler(HttpClientBuilder builder, HttpClientConfiguration config) { - if (config.getHttpErrorRetryCount() > 0) { + if (config.getServiceUnavailStrategy() != null) { + log.debug("HttpClient configuration: {} set custom ServiceUnavailableRetryStrategy: {}", + config.getFriendlyName(), config.getServiceUnavailStrategy().getClass().getName()); + builder.setRetryStrategy(config.getServiceUnavailStrategy()); + + } else if (config.getHttpErrorRetryCount() > 0) { log.info("Set HTTP error-retry to {} for http-client: {}", config.getHttpErrorRetryCount(), config.getFriendlyName()); - builder.setRetryHandler(new EaafHttpRequestRetryHandler( - config.getHttpErrorRetryCount(), - config.isHttpErrorRetryPost())); - - if (config.getServiceUnavailStrategy() != null) { - log.debug("HttpClient configuration: {} set custom ServiceUnavailableRetryStrategy: {}", - config.getFriendlyName(), config.getServiceUnavailStrategy().getClass().getName()); - builder.setServiceUnavailableRetryStrategy(config.getServiceUnavailStrategy()); - - } + builder.setRetryStrategy(new EaafHttpRequestRetryHandler( + config.getHttpErrorRetryCount())); } else { log.info("Disable HTTP error-retry for http-client: {}", config.getFriendlyName()); @@ -237,12 +215,12 @@ public class HttpClientFactory implements IHttpClientFactory { getSslContext(defaultHttpClientConfig); // set pool connection if required - HttpClientConnectionManager connectionManager - = injectConnectionManager(defaultHttpClientBuilder, sslConnectionFactory); + final HttpClientConnectionManager connectionManager = injectConnectionManager(defaultHttpClientBuilder, + sslConnectionFactory); // set default http client builder defaultConfigurationId = defaultHttpClientConfig.getUuid(); - availableBuilders.put(defaultConfigurationId, + availableBuilders.put(defaultConfigurationId, Pair.newInstance(defaultHttpClientBuilder, connectionManager)); } @@ -281,9 +259,6 @@ public class HttpClientFactory implements IHttpClientFactory { config.setHttpErrorRetryCount(Integer.parseInt(basicConfig.getBasicConfiguration( PROP_CONFIG_CLIENT_HTTP_CONNECTION_RETRY_COUNT, DEFAULT_CONFIG_CLIENT_HTTP_CONNECTION_RETRY_COUNT))); - config.setHttpErrorRetryPost(Boolean.parseBoolean(basicConfig.getBasicConfiguration( - PROP_CONFIG_CLIENT_HTTP_CONNECTION_RETRY_POST, - DEFAUTL_CONFIG_CLIENT_HTTP_CONNECTION_RETRY_POST))); // validate configuration object config.validate(); @@ -294,25 +269,29 @@ public class HttpClientFactory implements IHttpClientFactory { private void injectBasicAuthenticationIfRequired(HttpClientBuilder builder, final HttpClientConfiguration httpClientConfig) { if (httpClientConfig.getAuthMode().equals(HttpClientConfiguration.ClientAuthMode.PASSWORD)) { - final CredentialsProvider provider = new BasicCredentialsProvider(); + final BasicCredentialsProvider provider = new BasicCredentialsProvider(); log.trace("Injecting basic authentication with username: {} and password: {}", httpClientConfig.getUsername(), httpClientConfig.getPassword()); + final UsernamePasswordCredentials credentials = new UsernamePasswordCredentials( - httpClientConfig.getUsername(), httpClientConfig.getPassword()); + httpClientConfig.getUsername(), + httpClientConfig.getPassword() != null + ? httpClientConfig.getPassword().toCharArray() + : "".toCharArray()); - final AuthScope scope = new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT, AuthScope.ANY_REALM); + final AuthScope scope = new AuthScope(null, null, -1, null, null); provider.setCredentials(scope, credentials); builder.setDefaultCredentialsProvider(provider); log.info("Basic http authentication was injected with username: {}", httpClientConfig.getUsername()); if (httpClientConfig.isEnablePreEmptiveHttpBasicAuth()) { - log.info("Inject pre-emptive HTTP Basic-Auth interceptor for client: {}", + log.info("Inject pre-emptive HTTP Basic-Auth interceptor for client: {}", httpClientConfig.getFriendlyName()); - builder.addInterceptorFirst(new PreemptiveAuthInterceptor()); - + builder.addRequestInterceptorFirst(new PreemptiveAuthInterceptor()); + } - + } else { log.trace("Injection of Http Basic authentication was skipped"); @@ -360,50 +339,49 @@ public class HttpClientFactory implements IHttpClientFactory { HttpClientBuilder builder, final LayeredConnectionSocketFactory sslConnectionFactory) { if (basicConfig.getBasicConfigurationBoolean(PROP_CONFIG_CLIENT_HTTP_CONNECTION_POOL_USE, true)) { - PoolingHttpClientConnectionManager connectionPool - = new PoolingHttpClientConnectionManager(getDefaultRegistry(sslConnectionFactory)); + final PoolingHttpClientConnectionManager connectionPool = new PoolingHttpClientConnectionManager( + getDefaultRegistry(sslConnectionFactory)); 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)) - * 1000).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( + PROP_CONFIG_CLIENT_HTTP_CONNECTION_TIMEOUT_CONNECTION, + DEFAULT_CONFIG_CLIENT_HTTP_CONNECTION_TIMEOUT_CONNECTION)), TimeUnit.SECONDS) + .build()); + builder.setConnectionManager(connectionPool); - log.debug("Initalize http-client pool with, maxTotal: {} maxPerRoute: {}", + log.debug("Initalize http-client pool with, maxTotal: {} maxPerRoute: {}", connectionPool.getMaxTotal(), connectionPool.getDefaultMaxPerRoute()); return connectionPool; - + } else { log.debug("Building http-client without Connection-Pool ... "); final BasicHttpClientConnectionManager basicPool = new BasicHttpClientConnectionManager( - getDefaultRegistry(sslConnectionFactory)); - builder.setConnectionManager(basicPool); + getDefaultRegistry(sslConnectionFactory)); + builder.setConnectionManager(basicPool); return basicPool; - + } - + } private RequestConfig buildDefaultRequestConfig(HttpClientConfiguration config) { final RequestConfig requestConfig = RequestConfig.custom() - .setConnectTimeout(selectTimeoutFromConfig(config.getConnectTimeout(), - Integer.parseInt(basicConfig.getBasicConfiguration( - PROP_CONFIG_CLIENT_HTTP_CONNECTION_TIMEOUT_CONNECTION, - DEFAULT_CONFIG_CLIENT_HTTP_CONNECTION_TIMEOUT_CONNECTION)) * 1000)) .setConnectionRequestTimeout(selectTimeoutFromConfig(config.getConnectionRequestTimeout(), Integer.parseInt(basicConfig.getBasicConfiguration( - PROP_CONFIG_CLIENT_HTTP_CONNECTION_TIMEOUT_REQUEST, - DEFAULT_CONFIG_CLIENT_HTTP_CONNECTION_TIMEOUT_REQUEST)) * 1000)) - .setSocketTimeout(selectTimeoutFromConfig(config.getSocketTimeout(), - Integer.parseInt(basicConfig.getBasicConfiguration( - PROP_CONFIG_CLIENT_HTTP_CONNECTION_TIMEOUT_SOCKET, - DEFAULT_CONFIG_CLIENT_HTTP_CONNECTION_TIMEOUT_SOCKET)) - * 1000)) + PROP_CONFIG_CLIENT_HTTP_CONNECTION_TIMEOUT_REQUEST, + DEFAULT_CONFIG_CLIENT_HTTP_CONNECTION_TIMEOUT_REQUEST))), TimeUnit.SECONDS) .build(); return requestConfig; @@ -420,14 +398,14 @@ public class HttpClientFactory implements IHttpClientFactory { redirectStrategy = new RedirectStrategy() { @Override - public boolean isRedirected(final HttpRequest request, final HttpResponse response, - final HttpContext context) throws ProtocolException { + public boolean isRedirected(HttpRequest request, HttpResponse response, HttpContext context) + throws HttpException { return false; } @Override - public HttpUriRequest getRedirect(final HttpRequest request, final HttpResponse response, - final HttpContext context) throws ProtocolException { + public URI getLocationURI(HttpRequest request, HttpResponse response, HttpContext context) + throws HttpException { return null; } }; @@ -435,7 +413,7 @@ public class HttpClientFactory implements IHttpClientFactory { return redirectStrategy; } - + private static Registry<ConnectionSocketFactory> getDefaultRegistry( final LayeredConnectionSocketFactory sslConnectionFactory) { final RegistryBuilder<ConnectionSocketFactory> builder = |