From bf00298f747a3599eeef6a4fe274682666ded4df Mon Sep 17 00:00:00 2001 From: Matt Hurne Date: Wed, 25 Feb 2015 20:29:23 -0500 Subject: [PATCH] JCLOUDS-795: Retry with backoff upon receiving a 500 response from S3 with error code 'InternalError' --- .../jclouds/aws/config/AWSHttpApiModule.java | 2 +- .../handlers/AWSServerErrorRetryHandler.java | 1 + .../AWSServerErrorRetryHandlerTest.java | 21 +++++++++++-------- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/apis/sts/src/main/java/org/jclouds/aws/config/AWSHttpApiModule.java b/apis/sts/src/main/java/org/jclouds/aws/config/AWSHttpApiModule.java index fb59dcf789..4992ab6b8d 100644 --- a/apis/sts/src/main/java/org/jclouds/aws/config/AWSHttpApiModule.java +++ b/apis/sts/src/main/java/org/jclouds/aws/config/AWSHttpApiModule.java @@ -57,7 +57,7 @@ public abstract class AWSHttpApiModule extends HttpApiModule { @ServerError @Singleton protected Set provideRetryableServerCodes() { - return ImmutableSet.of("RequestLimitExceeded"); + return ImmutableSet.of("RequestLimitExceeded", "InternalError"); } @Override diff --git a/apis/sts/src/main/java/org/jclouds/aws/handlers/AWSServerErrorRetryHandler.java b/apis/sts/src/main/java/org/jclouds/aws/handlers/AWSServerErrorRetryHandler.java index ffbed50215..dd01fd4629 100644 --- a/apis/sts/src/main/java/org/jclouds/aws/handlers/AWSServerErrorRetryHandler.java +++ b/apis/sts/src/main/java/org/jclouds/aws/handlers/AWSServerErrorRetryHandler.java @@ -49,6 +49,7 @@ public class AWSServerErrorRetryHandler extends BackoffLimitedRetryHandler { @Override public boolean shouldRetryRequest(HttpCommand command, HttpResponse response) { switch (response.getStatusCode()) { + case 500: // Internal Server Error case 503: // Service Unavailable // Content can be null in the case of HEAD requests if (response.getPayload() != null) { diff --git a/apis/sts/src/test/java/org/jclouds/aws/handlers/AWSServerErrorRetryHandlerTest.java b/apis/sts/src/test/java/org/jclouds/aws/handlers/AWSServerErrorRetryHandlerTest.java index 77e54acebc..ea5cb51bc0 100644 --- a/apis/sts/src/test/java/org/jclouds/aws/handlers/AWSServerErrorRetryHandlerTest.java +++ b/apis/sts/src/test/java/org/jclouds/aws/handlers/AWSServerErrorRetryHandlerTest.java @@ -46,7 +46,7 @@ import com.google.common.collect.ImmutableSet; @Test(groups = "unit", testName = "AWSServerErrorRetryHandlerTest") public class AWSServerErrorRetryHandlerTest { @Test - public void test500DoesNotRetry() { + public void testUnknown500DoesNotRetry() { AWSUtils utils = createMock(AWSUtils.class); HttpCommand command = createMock(HttpCommand.class); @@ -64,11 +64,14 @@ public class AWSServerErrorRetryHandlerTest { @DataProvider(name = "codes") public Object[][] createData() { - return new Object[][] { { "RequestLimitExceeded" } }; + return new Object[][] { + { SERVICE_UNAVAILABLE.getStatusCode(), "RequestLimitExceeded" }, + { INTERNAL_SERVER_ERROR.getStatusCode(), "InternalError" } + }; } @Test(dataProvider = "codes") - public void test503DoesBackoffAndRetryForCode(String code) { + public void testDoesBackoffAndRetryForHttpStatusCodeAndErrorCode(int httpStatusCode, String errorCode) { AWSUtils utils = createMock(AWSUtils.class); HttpCommand command = createMock(HttpCommand.class); @@ -76,8 +79,8 @@ public class AWSServerErrorRetryHandlerTest { HttpRequest putBucket = HttpRequest.builder().method(PUT) .endpoint("https://adriancole-blobstore113.s3.amazonaws.com/").build(); - HttpResponse limitExceeded = HttpResponse.builder().statusCode(SERVICE_UNAVAILABLE.getStatusCode()) - .payload(Payloads.newStringPayload(String.format("%s", code))).build(); + HttpResponse response = HttpResponse.builder().statusCode(httpStatusCode) + .payload(Payloads.newStringPayload(String.format("%s", errorCode))).build(); expect(command.getCurrentRequest()).andReturn(putBucket); final AtomicInteger counter = new AtomicInteger(); @@ -96,16 +99,16 @@ public class AWSServerErrorRetryHandlerTest { }).anyTimes(); AWSError error = new AWSError(); - error.setCode(code); + error.setCode(errorCode); - expect(utils.parseAWSErrorFromContent(putBucket, limitExceeded)).andReturn(error); + expect(utils.parseAWSErrorFromContent(putBucket, response)).andReturn(error); replay(utils, command); AWSServerErrorRetryHandler retry = new AWSServerErrorRetryHandler(utils, - ImmutableSet. of("RequestLimitExceeded")); + ImmutableSet.of("RequestLimitExceeded", "InternalError")); - assert retry.shouldRetryRequest(command, limitExceeded); + assert retry.shouldRetryRequest(command, response); verify(utils, command);