JCLOUDS-795: Retry with backoff upon receiving a 500 response from S3 with error code 'InternalError'

This commit is contained in:
Matt Hurne 2015-02-25 20:29:23 -05:00 committed by Andrew Gaul
parent 85637ccee2
commit bf00298f74
3 changed files with 14 additions and 10 deletions

View File

@ -57,7 +57,7 @@ public abstract class AWSHttpApiModule<A> extends HttpApiModule<A> {
@ServerError
@Singleton
protected Set<String> provideRetryableServerCodes() {
return ImmutableSet.of("RequestLimitExceeded");
return ImmutableSet.of("RequestLimitExceeded", "InternalError");
}
@Override

View File

@ -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) {

View File

@ -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("<Error><Code>%s</Code></Error>", code))).build();
HttpResponse response = HttpResponse.builder().statusCode(httpStatusCode)
.payload(Payloads.newStringPayload(String.format("<Error><Code>%s</Code></Error>", 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.<String> of("RequestLimitExceeded"));
ImmutableSet.of("RequestLimitExceeded", "InternalError"));
assert retry.shouldRetryRequest(command, limitExceeded);
assert retry.shouldRetryRequest(command, response);
verify(utils, command);