From b5aeeac822bfe1a734835e3aa0caa65b56b3643a Mon Sep 17 00:00:00 2001 From: Thomas Lenz Date: Mon, 11 May 2020 19:19:25 +0200 Subject: update HttpClientFactory to facilitate request retrying in case of an error --- .../impl/http/EaafHttpRequestRetryHandler.java | 33 ++++++++++++++++ .../core/impl/http/HttpClientConfiguration.java | 8 +++- .../eaaf/core/impl/http/HttpClientFactory.java | 44 +++++++++++++++++++--- .../eaaf/core/impl/http/IHttpClientFactory.java | 4 +- 4 files changed, 81 insertions(+), 8 deletions(-) create mode 100644 eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/http/EaafHttpRequestRetryHandler.java (limited to 'eaaf_core_utils/src/main/java/at/gv') diff --git a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/http/EaafHttpRequestRetryHandler.java b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/http/EaafHttpRequestRetryHandler.java new file mode 100644 index 00000000..3aa908e8 --- /dev/null +++ b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/http/EaafHttpRequestRetryHandler.java @@ -0,0 +1,33 @@ +package at.gv.egiz.eaaf.core.impl.http; + +import java.net.UnknownHostException; +import java.util.Arrays; + +import javax.net.ssl.SSLException; + +import org.apache.http.client.HttpRequestRetryHandler; +import org.apache.http.impl.client.DefaultHttpRequestRetryHandler; + +public class EaafHttpRequestRetryHandler extends DefaultHttpRequestRetryHandler implements + HttpRequestRetryHandler { + + /** + * Create the request retry handler using the following list of non-retriable. + * IOException classes:
+ * + * + * @param retryCount how many times to retry; 0 means no retries + * @param requestSentRetryEnabled true if it's OK to retry non-idempotent + * requests that have been sent + */ + public EaafHttpRequestRetryHandler(final int retryCount, final boolean requestSentRetryEnabled) { + super(retryCount, requestSentRetryEnabled, Arrays.asList( + UnknownHostException.class, + SSLException.class)); + + } + +} diff --git a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/http/HttpClientConfiguration.java b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/http/HttpClientConfiguration.java index 6a66dfff..ec7d115a 100644 --- a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/http/HttpClientConfiguration.java +++ b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/http/HttpClientConfiguration.java @@ -56,7 +56,13 @@ public class HttpClientConfiguration { @Setter private boolean followHttpRedirects = true; - + + @Setter + private int httpErrorRetryCount = 3; + + @Setter + private boolean httpErrorRetryPost = false; + /** * Get a new HTTP-client configuration object. * 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 4e811eaa..b53226ce 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 @@ -65,7 +65,11 @@ public class HttpClientFactory implements IHttpClientFactory { public static final String PROP_CONFIG_CLIENT_HTTP_CONNECTION_TIMEOUT_CONNECTION = "client.http.connection.timeout.connection"; public static final String PROP_CONFIG_CLIENT_HTTP_CONNECTION_TIMEOUT_REQUEST = - "client.http.connection.timeout.request"; + "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"; @@ -91,7 +95,9 @@ public class HttpClientFactory implements IHttpClientFactory { 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 String DEFAUTL_CONFIG_CLIENT_HTTP_CONNECTION_RETRY_POST = String.valueOf(false); + private String defaultConfigurationId = null; private final Map availableBuilders = new HashMap<>(); @@ -127,8 +133,11 @@ public class HttpClientFactory implements IHttpClientFactory { config.validate(); builder = HttpClients.custom(); + + //inject request configuration builder.setDefaultRequestConfig(buildDefaultRequestConfig()); - + injectInternalRetryHandler(builder, config); + //inject basic authentication infos injectBasicAuthenticationIfRequired(builder, config); @@ -147,6 +156,22 @@ public class HttpClientFactory implements IHttpClientFactory { } + private void injectInternalRetryHandler(HttpClientBuilder builder, HttpClientConfiguration config) { + 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())); + + } else { + log.info("Disable HTTP error-retry for http-client: {}", config.getFriendlyName()); + builder.disableAutomaticRetries(); + + } + + } + @PostConstruct private void initalize() throws EaafException { final HttpClientConfiguration defaultHttpClientConfig = buildDefaultHttpClientConfiguration(); @@ -157,7 +182,8 @@ public class HttpClientFactory implements IHttpClientFactory { // set default request configuration defaultHttpClientBuilder.setDefaultRequestConfig(buildDefaultRequestConfig()); - + injectInternalRetryHandler(defaultHttpClientBuilder, defaultHttpClientConfig); + //inject http basic authentication injectBasicAuthenticationIfRequired(defaultHttpClientBuilder, defaultHttpClientConfig); @@ -205,6 +231,14 @@ public class HttpClientFactory implements IHttpClientFactory { config.setDisableHostnameValidation(basicConfig.getBasicConfigurationBoolean( PROP_CONFIG_CLIENT_HTTP_SSL_HOSTNAMEVERIFIER_TRUSTALL, false)); + 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(); @@ -324,7 +358,7 @@ public class HttpClientFactory implements IHttpClientFactory { .setSocketTimeout(Integer.parseInt( basicConfig.getBasicConfiguration(PROP_CONFIG_CLIENT_HTTP_CONNECTION_TIMEOUT_SOCKET, DEFAULT_CONFIG_CLIENT_HTTP_CONNECTION_TIMEOUT_SOCKET)) - * 1000) + * 1000) .build(); return requestConfig; diff --git a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/http/IHttpClientFactory.java b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/http/IHttpClientFactory.java index 7ec58d46..4e8374e1 100644 --- a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/http/IHttpClientFactory.java +++ b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/http/IHttpClientFactory.java @@ -2,10 +2,10 @@ package at.gv.egiz.eaaf.core.impl.http; import javax.annotation.Nonnull; -import at.gv.egiz.eaaf.core.exceptions.EaafException; - import org.apache.http.impl.client.CloseableHttpClient; +import at.gv.egiz.eaaf.core.exceptions.EaafException; + public interface IHttpClientFactory { /** -- cgit v1.2.3