From 00b01c71177f5fd5f3d6aa6efb15ec1e0045187e Mon Sep 17 00:00:00 2001 From: deagrawa Date: Wed, 23 Jan 2019 12:54:45 +0530 Subject: [PATCH 1/2] Add middleware options classes to enable middleware custom configurations --- .../graph/httpcore/RetryHandler.java | 26 ++++++++++----- .../middlewareoption/HttpContextBuilder.java | 33 +++++++++++++++++++ .../middlewareoption/IMiddlewareControl.java | 5 +++ .../middlewareoption/IShouldRetry.java | 8 +++++ .../middlewareoption/MiddlewareType.java | 16 +++++++++ .../middlewareoption/RetryOptions.java | 24 ++++++++++++++ 6 files changed, 104 insertions(+), 8 deletions(-) create mode 100644 src/main/java/com/microsoft/graph/httpcore/middlewareoption/HttpContextBuilder.java create mode 100644 src/main/java/com/microsoft/graph/httpcore/middlewareoption/IMiddlewareControl.java create mode 100644 src/main/java/com/microsoft/graph/httpcore/middlewareoption/IShouldRetry.java create mode 100644 src/main/java/com/microsoft/graph/httpcore/middlewareoption/MiddlewareType.java create mode 100644 src/main/java/com/microsoft/graph/httpcore/middlewareoption/RetryOptions.java diff --git a/src/main/java/com/microsoft/graph/httpcore/RetryHandler.java b/src/main/java/com/microsoft/graph/httpcore/RetryHandler.java index d0a7f6901..77de83f11 100644 --- a/src/main/java/com/microsoft/graph/httpcore/RetryHandler.java +++ b/src/main/java/com/microsoft/graph/httpcore/RetryHandler.java @@ -13,19 +13,22 @@ import org.apache.http.protocol.HttpCoreContext; import org.apache.http.util.Args; +import com.microsoft.graph.httpcore.middlewareoption.MiddlewareType; +import com.microsoft.graph.httpcore.middlewareoption.RetryOptions; + public class RetryHandler implements ServiceUnavailableRetryStrategy{ /** * Maximum number of allowed retries if the server responds with a HTTP code * in our retry code list. Default value is 1. */ - private final int maxRetries; + private final int maxRetries = 2; /** * Retry interval between subsequent requests, in milliseconds. Default * value is 1 second. */ - private long retryInterval; + private long retryInterval = 1000; private final int DELAY_MILLISECONDS = 1000; private final String RETRY_AFTER = "Retry-After"; private final String TRANSFER_ENCODING = "Transfer-Encoding"; @@ -33,21 +36,28 @@ public class RetryHandler implements ServiceUnavailableRetryStrategy{ private final int MSClientErrorCodeTooManyRequests = 429; private final int MSClientErrorCodeServiceUnavailable = 503; private final int MSClientErrorCodeGatewayTimeout = 504; + private final RetryOptions mRetryOption; - public RetryHandler(final int maxRetries, final int retryInterval) { + public RetryHandler(RetryOptions option) { super(); - Args.positive(maxRetries, "Max retries"); - Args.positive(retryInterval, "Retry interval"); - this.maxRetries = maxRetries; - this.retryInterval = retryInterval; + this.mRetryOption = option; } public RetryHandler() { - this(2, 1000); + this(null); } @Override public boolean retryRequest(HttpResponse response, int executionCount, HttpContext context) { + + RetryOptions retryOption = (RetryOptions)context.getAttribute(MiddlewareType.RETRY.toString()); + if(retryOption != null) { + return retryOption.shouldRetry().shouldRetry(response, executionCount, context); + } + if(mRetryOption != null) { + return mRetryOption.shouldRetry().shouldRetry(response, executionCount, context); + } + boolean shouldRetry = false; int statusCode = response.getStatusLine().getStatusCode(); shouldRetry = (executionCount < maxRetries) && checkStatus(statusCode) && isBuffered(response, context); diff --git a/src/main/java/com/microsoft/graph/httpcore/middlewareoption/HttpContextBuilder.java b/src/main/java/com/microsoft/graph/httpcore/middlewareoption/HttpContextBuilder.java new file mode 100644 index 000000000..a068df89c --- /dev/null +++ b/src/main/java/com/microsoft/graph/httpcore/middlewareoption/HttpContextBuilder.java @@ -0,0 +1,33 @@ +package com.microsoft.graph.httpcore.middlewareoption; + +import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.protocol.HttpClientContext; + +public class HttpContextBuilder { + + private RetryOptions retryoptions; + private int maxRedirect = -1; + + public static HttpContextBuilder create() { + return new HttpContextBuilder(); + } + + public void setRetryOption(IShouldRetry shouldRetry) { + retryoptions = new RetryOptions(shouldRetry); + } + + public void setRedirectOption(int maxRedirect) { + this.maxRedirect = maxRedirect; + } + + public HttpClientContext build() { + HttpClientContext context = HttpClientContext.create(); + if(retryoptions != null) + context.setAttribute(MiddlewareType.RETRY.toString(), retryoptions); + if(maxRedirect != -1) { + RequestConfig config = RequestConfig.custom().setMaxRedirects(maxRedirect).build(); + context.setRequestConfig(config); + } + return context; + } +} diff --git a/src/main/java/com/microsoft/graph/httpcore/middlewareoption/IMiddlewareControl.java b/src/main/java/com/microsoft/graph/httpcore/middlewareoption/IMiddlewareControl.java new file mode 100644 index 000000000..699c8d152 --- /dev/null +++ b/src/main/java/com/microsoft/graph/httpcore/middlewareoption/IMiddlewareControl.java @@ -0,0 +1,5 @@ +package com.microsoft.graph.httpcore.middlewareoption; + +public interface IMiddlewareControl { + +} diff --git a/src/main/java/com/microsoft/graph/httpcore/middlewareoption/IShouldRetry.java b/src/main/java/com/microsoft/graph/httpcore/middlewareoption/IShouldRetry.java new file mode 100644 index 000000000..cd208e0ca --- /dev/null +++ b/src/main/java/com/microsoft/graph/httpcore/middlewareoption/IShouldRetry.java @@ -0,0 +1,8 @@ +package com.microsoft.graph.httpcore.middlewareoption; + +import org.apache.http.HttpResponse; +import org.apache.http.protocol.HttpContext; + +public interface IShouldRetry { + boolean shouldRetry(HttpResponse response, int executionCount, HttpContext context); +} diff --git a/src/main/java/com/microsoft/graph/httpcore/middlewareoption/MiddlewareType.java b/src/main/java/com/microsoft/graph/httpcore/middlewareoption/MiddlewareType.java new file mode 100644 index 000000000..193ab9d1b --- /dev/null +++ b/src/main/java/com/microsoft/graph/httpcore/middlewareoption/MiddlewareType.java @@ -0,0 +1,16 @@ +package com.microsoft.graph.httpcore.middlewareoption; + +public enum MiddlewareType { + + //Authentication Middleware + AUTHENTICATION, + + //Redirect Middleware + REDIRECT, + + //Retry Middleware + RETRY, + + //Not supported + NOT_SUPPORTED +} diff --git a/src/main/java/com/microsoft/graph/httpcore/middlewareoption/RetryOptions.java b/src/main/java/com/microsoft/graph/httpcore/middlewareoption/RetryOptions.java new file mode 100644 index 000000000..867108389 --- /dev/null +++ b/src/main/java/com/microsoft/graph/httpcore/middlewareoption/RetryOptions.java @@ -0,0 +1,24 @@ +package com.microsoft.graph.httpcore.middlewareoption; + +import org.apache.http.HttpResponse; +import org.apache.http.protocol.HttpContext; + +public class RetryOptions implements IMiddlewareControl { + private IShouldRetry shouldretry; + + public RetryOptions(){ + this(new IShouldRetry() { + public boolean shouldRetry(HttpResponse response, int executionCount, HttpContext context) { + return true; + } + }); + } + + public RetryOptions(IShouldRetry shouldretry){ + this.shouldretry = shouldretry; + } + + public IShouldRetry shouldRetry() { + return shouldretry; + } +} From ae5dfebc7beb17ca05a8096887070c338373d029 Mon Sep 17 00:00:00 2001 From: deagrawa Date: Wed, 23 Jan 2019 13:02:17 +0530 Subject: [PATCH 2/2] Add retry handler test with retry options --- .../graph/httpcore/RetryHandlerTest.java | 40 +++++++++++++++---- 1 file changed, 33 insertions(+), 7 deletions(-) diff --git a/src/test/java/com/microsoft/graph/httpcore/RetryHandlerTest.java b/src/test/java/com/microsoft/graph/httpcore/RetryHandlerTest.java index 63240e40d..36082894e 100644 --- a/src/test/java/com/microsoft/graph/httpcore/RetryHandlerTest.java +++ b/src/test/java/com/microsoft/graph/httpcore/RetryHandlerTest.java @@ -14,24 +14,50 @@ import org.apache.http.client.protocol.HttpClientContext; import org.apache.http.entity.StringEntity; import org.apache.http.message.BasicHttpResponse; +import org.apache.http.protocol.HttpContext; import org.apache.http.protocol.HttpCoreContext; import org.junit.Test; +import com.microsoft.graph.httpcore.middlewareoption.IShouldRetry; +import com.microsoft.graph.httpcore.middlewareoption.RetryOptions; + public class RetryHandlerTest { int maxRetries = 2; - int retryInterval = 2000; + int retryInterval = 1000; String testurl = "https://graph.microsoft.com/v1.0/"; @Test public void testRetryHandlerCreation() { - RetryHandler retryhandler = new RetryHandler(maxRetries, retryInterval); + RetryHandler retryhandler = new RetryHandler(); assertTrue(retryhandler.getRetryInterval() == retryInterval); } + @Test + public void testRetryHandlerWithRetryOptions() { + RetryOptions option = new RetryOptions(); + RetryHandler retryhandler = new RetryHandler(option); + HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_GATEWAY_TIMEOUT, "Gateway Timeout"); + HttpClientContext localContext = HttpClientContext.create(); + assertTrue(retryhandler.retryRequest(response, 1, localContext)); + } + + @Test + public void testRetryHandlerWithCustomRetryOptions() { + RetryOptions option = new RetryOptions(new IShouldRetry() { + public boolean shouldRetry(HttpResponse response, int executionCount, HttpContext context) { + return false; + } + }); + RetryHandler retryhandler = new RetryHandler(option); + HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_GATEWAY_TIMEOUT, "Gateway Timeout"); + HttpClientContext localContext = HttpClientContext.create(); + assertTrue(!retryhandler.retryRequest(response, 1, localContext)); + } + @Test public void testRetryRequestWithMaxRetryAttempts() { - RetryHandler retryhandler = new RetryHandler(maxRetries, retryInterval); + RetryHandler retryhandler = new RetryHandler(); HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_GATEWAY_TIMEOUT, "Gateway Timeout"); HttpClientContext localContext = HttpClientContext.create(); assertFalse(retryhandler.retryRequest(response, 3, localContext)); @@ -39,7 +65,7 @@ public void testRetryRequestWithMaxRetryAttempts() { @Test public void testRetryRequestForStatusCode() { - RetryHandler retryhandler = new RetryHandler(maxRetries, retryInterval); + RetryHandler retryhandler = new RetryHandler(); HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_INTERNAL_SERVER_ERROR, "Internal Server Error"); HttpClientContext localContext = HttpClientContext.create(); assertFalse(retryhandler.retryRequest(response, 1, localContext)); @@ -47,7 +73,7 @@ public void testRetryRequestForStatusCode() { @Test public void testRetryRequestWithTransferEncoding() { - RetryHandler retryhandler = new RetryHandler(maxRetries, retryInterval); + RetryHandler retryhandler = new RetryHandler(); HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_GATEWAY_TIMEOUT, "Internal Server Error"); response.setHeader("Transfer-Encoding", "chunked"); HttpPost httppost = new HttpPost(testurl); @@ -67,7 +93,7 @@ public void testRetryRequestWithTransferEncoding() { @Test public void testRetryRequestWithExponentialBackOff() { - RetryHandler retryhandler = new RetryHandler(maxRetries, retryInterval); + RetryHandler retryhandler = new RetryHandler(); HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_GATEWAY_TIMEOUT, "Internal Server Error"); HttpPost httppost = new HttpPost(testurl); @@ -87,7 +113,7 @@ public void testRetryRequestWithExponentialBackOff() { @Test public void testRetryHandlerRetryRequestWithRetryAfterHeader() { - RetryHandler retryhandler = new RetryHandler(maxRetries, retryInterval); + RetryHandler retryhandler = new RetryHandler(); HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_GATEWAY_TIMEOUT, "Internal Server Error"); response.setHeader("Retry-After", "100"); HttpPost httppost = new HttpPost(testurl);