mirror of https://github.com/apache/jclouds.git
JCLOUDS-795: Retry with backoff upon receiving a 500 response from S3 with error code 'InternalError'
This commit is contained in:
parent
85637ccee2
commit
bf00298f74
|
@ -57,7 +57,7 @@ public abstract class AWSHttpApiModule<A> extends HttpApiModule<A> {
|
||||||
@ServerError
|
@ServerError
|
||||||
@Singleton
|
@Singleton
|
||||||
protected Set<String> provideRetryableServerCodes() {
|
protected Set<String> provideRetryableServerCodes() {
|
||||||
return ImmutableSet.of("RequestLimitExceeded");
|
return ImmutableSet.of("RequestLimitExceeded", "InternalError");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -49,6 +49,7 @@ public class AWSServerErrorRetryHandler extends BackoffLimitedRetryHandler {
|
||||||
@Override
|
@Override
|
||||||
public boolean shouldRetryRequest(HttpCommand command, HttpResponse response) {
|
public boolean shouldRetryRequest(HttpCommand command, HttpResponse response) {
|
||||||
switch (response.getStatusCode()) {
|
switch (response.getStatusCode()) {
|
||||||
|
case 500: // Internal Server Error
|
||||||
case 503: // Service Unavailable
|
case 503: // Service Unavailable
|
||||||
// Content can be null in the case of HEAD requests
|
// Content can be null in the case of HEAD requests
|
||||||
if (response.getPayload() != null) {
|
if (response.getPayload() != null) {
|
||||||
|
|
|
@ -46,7 +46,7 @@ import com.google.common.collect.ImmutableSet;
|
||||||
@Test(groups = "unit", testName = "AWSServerErrorRetryHandlerTest")
|
@Test(groups = "unit", testName = "AWSServerErrorRetryHandlerTest")
|
||||||
public class AWSServerErrorRetryHandlerTest {
|
public class AWSServerErrorRetryHandlerTest {
|
||||||
@Test
|
@Test
|
||||||
public void test500DoesNotRetry() {
|
public void testUnknown500DoesNotRetry() {
|
||||||
|
|
||||||
AWSUtils utils = createMock(AWSUtils.class);
|
AWSUtils utils = createMock(AWSUtils.class);
|
||||||
HttpCommand command = createMock(HttpCommand.class);
|
HttpCommand command = createMock(HttpCommand.class);
|
||||||
|
@ -64,11 +64,14 @@ public class AWSServerErrorRetryHandlerTest {
|
||||||
|
|
||||||
@DataProvider(name = "codes")
|
@DataProvider(name = "codes")
|
||||||
public Object[][] createData() {
|
public Object[][] createData() {
|
||||||
return new Object[][] { { "RequestLimitExceeded" } };
|
return new Object[][] {
|
||||||
|
{ SERVICE_UNAVAILABLE.getStatusCode(), "RequestLimitExceeded" },
|
||||||
|
{ INTERNAL_SERVER_ERROR.getStatusCode(), "InternalError" }
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(dataProvider = "codes")
|
@Test(dataProvider = "codes")
|
||||||
public void test503DoesBackoffAndRetryForCode(String code) {
|
public void testDoesBackoffAndRetryForHttpStatusCodeAndErrorCode(int httpStatusCode, String errorCode) {
|
||||||
|
|
||||||
AWSUtils utils = createMock(AWSUtils.class);
|
AWSUtils utils = createMock(AWSUtils.class);
|
||||||
HttpCommand command = createMock(HttpCommand.class);
|
HttpCommand command = createMock(HttpCommand.class);
|
||||||
|
@ -76,8 +79,8 @@ public class AWSServerErrorRetryHandlerTest {
|
||||||
HttpRequest putBucket = HttpRequest.builder().method(PUT)
|
HttpRequest putBucket = HttpRequest.builder().method(PUT)
|
||||||
.endpoint("https://adriancole-blobstore113.s3.amazonaws.com/").build();
|
.endpoint("https://adriancole-blobstore113.s3.amazonaws.com/").build();
|
||||||
|
|
||||||
HttpResponse limitExceeded = HttpResponse.builder().statusCode(SERVICE_UNAVAILABLE.getStatusCode())
|
HttpResponse response = HttpResponse.builder().statusCode(httpStatusCode)
|
||||||
.payload(Payloads.newStringPayload(String.format("<Error><Code>%s</Code></Error>", code))).build();
|
.payload(Payloads.newStringPayload(String.format("<Error><Code>%s</Code></Error>", errorCode))).build();
|
||||||
|
|
||||||
expect(command.getCurrentRequest()).andReturn(putBucket);
|
expect(command.getCurrentRequest()).andReturn(putBucket);
|
||||||
final AtomicInteger counter = new AtomicInteger();
|
final AtomicInteger counter = new AtomicInteger();
|
||||||
|
@ -96,16 +99,16 @@ public class AWSServerErrorRetryHandlerTest {
|
||||||
}).anyTimes();
|
}).anyTimes();
|
||||||
|
|
||||||
AWSError error = new AWSError();
|
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);
|
replay(utils, command);
|
||||||
|
|
||||||
AWSServerErrorRetryHandler retry = new AWSServerErrorRetryHandler(utils,
|
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);
|
verify(utils, command);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue