summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas <>2024-04-03 18:40:59 +0200
committerThomas <>2024-04-03 18:40:59 +0200
commitff340b3aec5193b066b3cf6ee6cbc9c542de48df (patch)
tree00186bd13aa86f6016383aa96837f1a2de76a239
parent487011328411309e0be774d5e9371346a788d9ba (diff)
downloadEAAF-Components-ff340b3aec5193b066b3cf6ee6cbc9c542de48df.tar.gz
EAAF-Components-ff340b3aec5193b066b3cf6ee6cbc9c542de48df.tar.bz2
EAAF-Components-ff340b3aec5193b066b3cf6ee6cbc9c542de48df.zip
fix(http): include retry on HTTP POST requests
Reason: that feature looks be removed during refactoring from Apache HTTP Client v4.x to 5.x
-rw-r--r--eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/http/EaafHttpRequestRetryHandler.java37
-rw-r--r--eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/http/HttpClientConfiguration.java3
-rw-r--r--eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/http/HttpClientFactory.java7
-rw-r--r--eaaf_core_utils/src/test/java/at/gv/egiz/eaaf/core/test/http/HttpClientFactoryTest.java94
4 files changed, 108 insertions, 33 deletions
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
index 026b76c4..6ea13905 100644
--- 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
@@ -7,11 +7,15 @@ import javax.net.ssl.SSLException;
import org.apache.hc.client5.http.HttpRequestRetryStrategy;
import org.apache.hc.client5.http.impl.DefaultHttpRequestRetryStrategy;
+import org.apache.hc.core5.http.HttpRequest;
+import org.apache.hc.core5.http.Method;
import org.apache.hc.core5.util.TimeValue;
public class EaafHttpRequestRetryHandler extends DefaultHttpRequestRetryStrategy implements
HttpRequestRetryStrategy {
+ private boolean allowHttpPostRetry;
+
/**
* Create the request retry handler using the following list of non-retriable.
* IOException classes: <br>
@@ -25,15 +29,48 @@ public class EaafHttpRequestRetryHandler extends DefaultHttpRequestRetryStrategy
* <li>502</li>
* </ul>
* After two seconds if no {@code Retry-After} header was set.
+ * <p>
+ * Do not allow retry of HTTP POST
+ * </p>
*
* @param retryCount how many times to retry; 0 means no retries
*/
public EaafHttpRequestRetryHandler(final int retryCount) {
+ this(retryCount, false);
+
+ }
+
+ /**
+ * Create the request retry handler using the following list of non-retriable.
+ * IOException classes: <br>
+ * <ul>
+ * <li>UnknownHostException</li>
+ * <li>SSLException</li>
+ * </ul>
+ * HTTP StatusCodes:
+ * <ul>
+ * <li>429</li>
+ * <li>502</li>
+ * </ul>
+ * After two seconds if no {@code Retry-After} header was set.
+ *
+ * @param retryCount how many times to retry; 0 means no retries
+ * @param retryHttpPost In case of <code>true</code> allow retry of HTTP POST
+ * too
+ */
+ public EaafHttpRequestRetryHandler(final int retryCount, final boolean retryHttpPost) {
super(retryCount, TimeValue.ofSeconds(2),
Arrays.asList(
UnknownHostException.class,
SSLException.class),
Arrays.asList(429, 502));
+ allowHttpPostRetry = retryHttpPost;
+
+ }
+
+ protected boolean handleAsIdempotent(final HttpRequest request) {
+ return allowHttpPostRetry && Method.POST.isSame(request.getMethod())
+ || Method.isIdempotent(request.getMethod());
}
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 2081bd24..f978fa4c 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
@@ -67,6 +67,9 @@ public class HttpClientConfiguration {
private boolean followHttpRedirects = true;
@Setter
+ private boolean httpPostRetryAllowed = false;
+
+ @Setter
private int httpErrorRetryCount = 3;
@Setter
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 62e781b9..7a71bfab 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
@@ -81,6 +81,8 @@ 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";
@@ -210,7 +212,8 @@ public class HttpClientFactory implements IHttpClientFactory {
log.info("Set HTTP error-retry to {} for http-client: {}",
config.getHttpErrorRetryCount(), config.getFriendlyName());
builder.setRetryStrategy(new EaafHttpRequestRetryHandler(
- config.getHttpErrorRetryCount()));
+ config.getHttpErrorRetryCount(),
+ config.isHttpPostRetryAllowed()));
} else {
log.info("Disable HTTP error-retry for http-client: {}", config.getFriendlyName());
@@ -309,6 +312,8 @@ 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.setHttpPostRetryAllowed(basicConfig.getBasicConfigurationBoolean(
+ PROP_CONFIG_CLIENT_HTTP_CONNECTION_RETRY_POST, false));
config.setEnableHttpProxyMode(basicConfig.getBasicConfigurationBoolean(
PROP_CONFIG_CLIENT_HTTP_PROXY_ENABLED, false));
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 243205c9..c566380e 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
@@ -394,38 +394,6 @@ public class HttpClientFactoryTest {
}
@Test
- public void httpPostRetryNotAllowed() throws EaafException, InterruptedException,
- ClientProtocolException, IOException {
- final HttpClientConfiguration config =
- new HttpClientConfiguration("jUnit_retry_" + RandomStringUtils.randomAlphabetic(3));
- config.setHttpErrorRetryCount(2);
-
- final CloseableHttpClient client = httpClientFactory.getHttpClient(config);
- Assert.assertNotNull("No httpClient", client);
-
-
- mockWebServer = new MockWebServer();
- mockServerUrl = mockWebServer.url("/sp/junit");
- mockWebServer.enqueue(new MockResponse()
- .setSocketPolicy(SocketPolicy.NO_RESPONSE)
- .setResponseCode(HttpURLConnection.HTTP_NO_CONTENT));
- mockWebServer.enqueue(new MockResponse().setResponseCode(200)
- .setBody("GetData"));
-
- //request webservice
- final HttpUriRequest httpGet1 = new HttpPost(mockServerUrl.url().toString());
- try {
- client.execute(httpGet1);
- Assert.fail("HTTP POST retry not allowed");
-
- } catch (final SocketTimeoutException e) {
- Assert.assertNotNull("No errorMsg", e.getMessage());
-
- }
-
- }
-
- @Test
public void testHttpClientRetryOneTime() throws EaafException, InterruptedException,
ClientProtocolException, IOException {
final HttpClientConfiguration config =
@@ -552,6 +520,68 @@ public class HttpClientFactoryTest {
}
@Test
+ public void testHttpClientRetryOneTimePost() throws EaafException, InterruptedException,
+ ClientProtocolException, IOException {
+ final HttpClientConfiguration config =
+ new HttpClientConfiguration("jUnit_retry_" + RandomStringUtils.randomAlphabetic(3));
+ config.setHttpErrorRetryCount(2);
+ config.setHttpPostRetryAllowed(true);
+
+ final CloseableHttpClient client = httpClientFactory.getHttpClient(config);
+ Assert.assertNotNull("No httpClient", client);
+
+ mockWebServer = new MockWebServer();
+ mockServerUrl = mockWebServer.url("/sp/junit");
+ mockWebServer.enqueue(new MockResponse()
+ .setSocketPolicy(SocketPolicy.NO_RESPONSE)
+ .setResponseCode(HttpURLConnection.HTTP_NO_CONTENT));
+
+ String bodyData = RandomStringUtils.randomAlphanumeric(10);
+ mockWebServer.enqueue(new MockResponse().setResponseCode(200)
+ .setBody(bodyData));
+
+ // request webservice
+ final HttpUriRequest httpGet1 = new HttpPost(mockServerUrl.url().toString());
+ final Triple<StatusLine, ByteArrayInputStream, ContentType> httpResp1 = client.execute(httpGet1,
+ HttpUtils.bodyStatusCodeResponseHandler());
+ Assert.assertEquals("http statusCode", 200, httpResp1.getFirst().getStatusCode());
+ Assert.assertEquals("http statusCode", bodyData, new String(StreamUtils.readStream(httpResp1
+ .getSecond())));
+
+ }
+
+ @Test
+ public void httpPostRetryNotAllowed() throws EaafException, InterruptedException,
+ ClientProtocolException, IOException {
+ final HttpClientConfiguration config =
+ new HttpClientConfiguration("jUnit_retry_" + RandomStringUtils.randomAlphabetic(3));
+ config.setHttpErrorRetryCount(2);
+ config.setHttpPostRetryAllowed(false);
+
+ final CloseableHttpClient client = httpClientFactory.getHttpClient(config);
+ Assert.assertNotNull("No httpClient", client);
+
+ mockWebServer = new MockWebServer();
+ mockServerUrl = mockWebServer.url("/sp/junit");
+ mockWebServer.enqueue(new MockResponse()
+ .setSocketPolicy(SocketPolicy.NO_RESPONSE)
+ .setResponseCode(HttpURLConnection.HTTP_NO_CONTENT));
+ mockWebServer.enqueue(new MockResponse().setResponseCode(200)
+ .setBody("GetData"));
+
+ // request webservices
+ final HttpUriRequest httpGet1 = new HttpPost(mockServerUrl.url().toString());
+ try {
+ client.execute(httpGet1);
+ Assert.fail("HTTP POST retry not allowed");
+
+ } catch (final SocketTimeoutException e) {
+ Assert.assertNotNull("No errorMsg", e.getMessage());
+
+ }
+ }
+
+ @Test
public void getCustomClientBasicAuthNoPassword() throws EaafException {
final HttpClientConfiguration config = new HttpClientConfiguration("jUnit");
config.setAuthMode("password");