mirror of https://github.com/apache/jclouds.git
externalized retry codes
This commit is contained in:
parent
80f6101e1f
commit
a0b1ffb625
|
@ -20,6 +20,9 @@ package org.jclouds.aws.config;
|
|||
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.aws.handlers.AWSClientErrorRetryHandler;
|
||||
import org.jclouds.aws.handlers.ParseAWSErrorFromXmlContent;
|
||||
|
@ -31,7 +34,9 @@ import org.jclouds.http.annotation.ServerError;
|
|||
import org.jclouds.rest.ConfiguresRestClient;
|
||||
import org.jclouds.rest.config.RestClientModule;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.reflect.TypeToken;
|
||||
import com.google.inject.Provides;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -57,6 +62,13 @@ public abstract class AWSRestClientModule<S, A> extends RestClientModule<S, A> {
|
|||
super(syncClientType, asyncClientType, sync2Async);
|
||||
}
|
||||
|
||||
@Provides
|
||||
@ClientError
|
||||
@Singleton
|
||||
protected Set<String> provideRetryableCodes(){
|
||||
return ImmutableSet.of("RequestTimeout", "OperationAborted", "SignatureDoesNotMatch");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void bindErrorHandlers() {
|
||||
bind(HttpErrorHandler.class).annotatedWith(Redirection.class).to(ParseAWSErrorFromXmlContent.class);
|
||||
|
|
|
@ -20,14 +20,16 @@ package org.jclouds.aws.handlers;
|
|||
|
||||
import static org.jclouds.http.HttpUtils.closeClientButKeepContentStream;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import org.jclouds.aws.domain.AWSError;
|
||||
import org.jclouds.aws.util.AWSUtils;
|
||||
import org.jclouds.http.HttpCommand;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.jclouds.http.HttpRetryHandler;
|
||||
import org.jclouds.http.annotation.ClientError;
|
||||
import org.jclouds.http.handlers.BackoffLimitedRetryHandler;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.inject.Inject;
|
||||
|
||||
/**
|
||||
|
@ -39,27 +41,35 @@ public class AWSClientErrorRetryHandler implements HttpRetryHandler {
|
|||
|
||||
private final AWSUtils utils;
|
||||
private final BackoffLimitedRetryHandler backoffLimitedRetryHandler;
|
||||
private final Set<String> retryableCodes;
|
||||
|
||||
@Inject
|
||||
public AWSClientErrorRetryHandler(AWSUtils utils, BackoffLimitedRetryHandler backoffLimitedRetryHandler) {
|
||||
public AWSClientErrorRetryHandler(AWSUtils utils, BackoffLimitedRetryHandler backoffLimitedRetryHandler,
|
||||
@ClientError Set<String> retryableCodes) {
|
||||
this.utils = utils;
|
||||
this.backoffLimitedRetryHandler = backoffLimitedRetryHandler;
|
||||
this.retryableCodes = retryableCodes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldRetryRequest(HttpCommand command, HttpResponse response) {
|
||||
if (response.getStatusCode() == 400 || response.getStatusCode() == 403 || response.getStatusCode() == 409) {
|
||||
// Content can be null in the case of HEAD requests
|
||||
if (response.getPayload() != null) {
|
||||
closeClientButKeepContentStream(response);
|
||||
AWSError error = utils.parseAWSErrorFromContent(command.getCurrentRequest(), response);
|
||||
if (error != null
|
||||
&& ImmutableSet.of("RequestTimeout", "OperationAborted", "SignatureDoesNotMatch").contains(
|
||||
error.getCode())) {
|
||||
return backoffLimitedRetryHandler.shouldRetryRequest(command, response);
|
||||
if (error != null) {
|
||||
return shouldRetryRequestOnError(command, response, error);
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected boolean shouldRetryRequestOnError(HttpCommand command, HttpResponse response, AWSError error) {
|
||||
if (retryableCodes.contains(error.getCode()))
|
||||
return backoffLimitedRetryHandler.shouldRetryRequest(command, response);
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -33,6 +33,8 @@ import org.jclouds.io.Payloads;
|
|||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
/**
|
||||
* Tests behavior of {@code AWSClientErrorRetryHandler}
|
||||
*
|
||||
|
@ -49,7 +51,8 @@ public class AWSClientErrorRetryHandlerTest {
|
|||
|
||||
replay(utils, backoffLimitedRetryHandler, command);
|
||||
|
||||
AWSClientErrorRetryHandler retry = new AWSClientErrorRetryHandler(utils, backoffLimitedRetryHandler);
|
||||
AWSClientErrorRetryHandler retry = new AWSClientErrorRetryHandler(utils, backoffLimitedRetryHandler,
|
||||
ImmutableSet.<String> of());
|
||||
|
||||
assert !retry.shouldRetryRequest(command, HttpResponse.builder().statusCode(401).build());
|
||||
|
||||
|
@ -70,10 +73,10 @@ public class AWSClientErrorRetryHandlerTest {
|
|||
HttpCommand command = createMock(HttpCommand.class);
|
||||
|
||||
HttpRequest putBucket = HttpRequest.builder().method("PUT")
|
||||
.endpoint("https://adriancole-blobstore113.s3.amazonaws.com/").build();
|
||||
.endpoint("https://adriancole-blobstore113.s3.amazonaws.com/").build();
|
||||
|
||||
HttpResponse operationAborted = HttpResponse.builder().statusCode(409)
|
||||
.payload(Payloads.newStringPayload(String.format("<Error><Code>%s</Code></Error>", code))).build();
|
||||
.payload(Payloads.newStringPayload(String.format("<Error><Code>%s</Code></Error>", code))).build();
|
||||
|
||||
expect(command.getCurrentRequest()).andReturn(putBucket);
|
||||
|
||||
|
@ -86,7 +89,8 @@ public class AWSClientErrorRetryHandlerTest {
|
|||
|
||||
replay(utils, backoffLimitedRetryHandler, command);
|
||||
|
||||
AWSClientErrorRetryHandler retry = new AWSClientErrorRetryHandler(utils, backoffLimitedRetryHandler);
|
||||
AWSClientErrorRetryHandler retry = new AWSClientErrorRetryHandler(utils, backoffLimitedRetryHandler,
|
||||
ImmutableSet.<String> of("RequestTimeout", "OperationAborted", "SignatureDoesNotMatch"));
|
||||
|
||||
assert retry.shouldRetryRequest(command, operationAborted);
|
||||
|
||||
|
|
Loading…
Reference in New Issue