JCLOUDS-40 unasync Fallback

This commit is contained in:
Adrian Cole 2014-10-05 22:55:07 -07:00 committed by Adrian Cole
parent 0a74e923d2
commit b42cda0a66
23 changed files with 56 additions and 253 deletions

View File

@ -18,7 +18,6 @@ package org.jclouds.atmos.fallbacks;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Throwables.propagate;
import static com.google.common.util.concurrent.Futures.immediateFuture;
import java.net.URI;
@ -29,17 +28,11 @@ import org.jclouds.javax.annotation.Nullable;
import org.jclouds.rest.InvocationContext;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.util.concurrent.ListenableFuture;
public class EndpointIfAlreadyExists implements Fallback<URI>, InvocationContext<EndpointIfAlreadyExists> {
private URI endpoint;
@Override
public ListenableFuture<URI> create(Throwable t) throws Exception {
return immediateFuture(createOrPropagate(t));
}
@Override
public URI createOrPropagate(Throwable t) throws Exception {
if (checkNotNull(t, "throwable") instanceof KeyAlreadyExistsException) {

View File

@ -17,7 +17,6 @@
package org.jclouds.atmos.fallbacks;
import static com.google.common.base.Throwables.propagate;
import static com.google.common.util.concurrent.Futures.immediateFuture;
import static org.jclouds.util.Throwables2.getFirstThrowableOfType;
import org.jclouds.Fallback;
@ -25,14 +24,7 @@ import org.jclouds.atmos.AtmosResponseException;
import org.jclouds.atmos.reference.AtmosErrorCode;
import org.jclouds.http.HttpUtils;
import com.google.common.util.concurrent.ListenableFuture;
public final class TrueOn404FalseOnPathNotEmpty implements Fallback<Boolean> {
@Override
public ListenableFuture<Boolean> create(Throwable t) throws Exception {
return immediateFuture(createOrPropagate(t));
}
@Override
public Boolean createOrPropagate(Throwable t) throws Exception {
if (HttpUtils.contains404(t)) {

View File

@ -16,7 +16,6 @@
*/
package org.jclouds.atmos.fallbacks;
import static com.google.common.util.concurrent.Futures.getUnchecked;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNull;
@ -30,23 +29,23 @@ public class EndpointIfAlreadyExistsTest {
@Test
public void testFoundIsNullWhenEndpointNotSet() throws Exception {
assertNull(getUnchecked(new EndpointIfAlreadyExists().create(new KeyAlreadyExistsException())));
assertNull(new EndpointIfAlreadyExists().createOrPropagate(new KeyAlreadyExistsException()));
}
@Test
public void testFoundIsEndpointWhenSet() throws Exception {
assertEquals(
getUnchecked(new EndpointIfAlreadyExists().setEndpoint(URI.create("foo")).create(
new KeyAlreadyExistsException())), URI.create("foo"));
new EndpointIfAlreadyExists().setEndpoint(URI.create("foo")).createOrPropagate(
new KeyAlreadyExistsException()), URI.create("foo"));
}
@Test(expectedExceptions = RuntimeException.class)
public void testNotFoundPropagates() throws Exception {
new EndpointIfAlreadyExists().create(new RuntimeException());
new EndpointIfAlreadyExists().createOrPropagate(new RuntimeException());
}
@Test(expectedExceptions = NullPointerException.class)
public void testNullIsBad() throws Exception {
new EndpointIfAlreadyExists().create(null);
new EndpointIfAlreadyExists().createOrPropagate(null);
}
}

View File

@ -17,14 +17,11 @@
package org.jclouds.cloudstack.functions;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.util.concurrent.Futures.immediateFuture;
import static org.jclouds.Fallbacks.valOnNotFoundOr404;
import static org.jclouds.util.Throwables2.getFirstThrowableOfType;
import org.jclouds.Fallback;
import com.google.common.util.concurrent.ListenableFuture;
public final class CloudStackFallbacks {
private CloudStackFallbacks() {
}
@ -34,11 +31,6 @@ public final class CloudStackFallbacks {
* have to ignore as there's no means for us to avoid the problem, or action to take.
*/
public static final class VoidOnNotFoundOr404OrUnableToFindAccountOwner implements Fallback<Void> {
@Override
public ListenableFuture<Void> create(Throwable t) throws Exception {
return immediateFuture(createOrPropagate(t));
}
@Override
public Void createOrPropagate(Throwable t) throws Exception {
IllegalStateException e = getFirstThrowableOfType(checkNotNull(t, "throwable"), IllegalStateException.class);

View File

@ -18,25 +18,18 @@ package org.jclouds.ec2;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Throwables.propagate;
import static com.google.common.util.concurrent.Futures.immediateFuture;
import org.jclouds.Fallback;
import org.jclouds.aws.AWSResponseException;
import com.google.common.base.Predicates;
import com.google.common.collect.ImmutableSet;
import com.google.common.util.concurrent.ListenableFuture;
public final class EC2Fallbacks {
private EC2Fallbacks() {
}
public static final class VoidOnVolumeAvailable implements Fallback<Void> {
@Override
public ListenableFuture<Void> create(Throwable t) throws Exception {
return immediateFuture(createOrPropagate(t));
}
@Override
public Void createOrPropagate(Throwable t) throws Exception {
if (checkNotNull(t, "throwable") instanceof AWSResponseException) {

View File

@ -16,15 +16,13 @@
*/
package org.jclouds.openstack.keystone.v2_0;
import static com.google.common.util.concurrent.Futures.immediateFuture;
import static org.jclouds.Fallbacks.valOnNotFoundOr404;
import org.jclouds.Fallback;
import org.jclouds.openstack.v2_0.domain.PaginatedCollection;
import org.jclouds.openstack.v2_0.domain.Link;
import org.jclouds.openstack.v2_0.domain.PaginatedCollection;
import com.google.common.collect.ImmutableSet;
import com.google.common.util.concurrent.ListenableFuture;
public final class KeystoneFallbacks {
private KeystoneFallbacks() {
@ -35,11 +33,6 @@ public final class KeystoneFallbacks {
ImmutableSet.<Object> of(), ImmutableSet.<Link> of()) {
};
@Override
public ListenableFuture<PaginatedCollection<Object>> create(Throwable t) throws Exception {
return immediateFuture(createOrPropagate(t));
}
@Override
public PaginatedCollection<Object> createOrPropagate(Throwable t) throws Exception {
return valOnNotFoundOr404(EMPTY, t);

View File

@ -19,25 +19,17 @@ package org.jclouds.s3;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Predicates.equalTo;
import static com.google.common.base.Throwables.propagate;
import static com.google.common.util.concurrent.Futures.immediateFuture;
import static org.jclouds.http.HttpUtils.returnValueOnCodeOrNull;
import static org.jclouds.util.Throwables2.getFirstThrowableOfType;
import org.jclouds.Fallback;
import org.jclouds.blobstore.ContainerNotFoundException;
import com.google.common.util.concurrent.ListenableFuture;
public final class S3Fallbacks {
private S3Fallbacks() {
}
public static final class TrueOn404OrNotFoundFalseOnIllegalState implements Fallback<Boolean> {
@Override
public ListenableFuture<Boolean> create(Throwable t) throws Exception {
return immediateFuture(createOrPropagate(t));
}
@Override
public Boolean createOrPropagate(Throwable t) throws Exception {
if (getFirstThrowableOfType(checkNotNull(t, "throwable"), IllegalStateException.class) != null)

View File

@ -18,7 +18,6 @@ package org.jclouds.s3.fallbacks;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Throwables.propagate;
import static com.google.common.util.concurrent.Futures.immediateFuture;
import static org.jclouds.s3.util.S3Utils.getBucketName;
import static org.jclouds.util.Throwables2.getFirstThrowableOfType;
@ -31,8 +30,6 @@ import org.jclouds.javax.annotation.Nullable;
import org.jclouds.rest.InvocationContext;
import org.jclouds.s3.S3Client;
import com.google.common.util.concurrent.ListenableFuture;
public class FalseIfBucketAlreadyOwnedByYouOrOperationAbortedWhenBucketExists implements Fallback<Boolean>,
InvocationContext<FalseIfBucketAlreadyOwnedByYouOrOperationAbortedWhenBucketExists> {
@ -44,11 +41,6 @@ public class FalseIfBucketAlreadyOwnedByYouOrOperationAbortedWhenBucketExists im
this.client = client;
}
@Override
public ListenableFuture<Boolean> create(Throwable t) throws Exception {
return immediateFuture(createOrPropagate(t));
}
@Override
public Boolean createOrPropagate(Throwable t) throws Exception {
AWSResponseException exception = getFirstThrowableOfType(checkNotNull(t, "throwable"), AWSResponseException.class);

View File

@ -21,7 +21,6 @@ import static com.google.common.net.HttpHeaders.ETAG;
import static com.google.common.net.HttpHeaders.EXPECT;
import static com.google.common.util.concurrent.MoreExecutors.sameThreadExecutor;
import static org.jclouds.Constants.PROPERTY_MAX_RETRIES;
import static org.jclouds.Constants.PROPERTY_SO_TIMEOUT;
import static org.testng.Assert.assertEquals;
import java.io.IOException;

View File

@ -15,7 +15,7 @@
* limitations under the License.
*/
package org.jclouds.s3.fallbacks;
import static com.google.common.util.concurrent.Futures.getUnchecked;
import static org.easymock.EasyMock.createMock;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.replay;
@ -55,8 +55,8 @@ public class FalseIfBucketAlreadyOwnedByYouOrOperationAbortedWhenBucketExistsTes
replay(client);
Exception e = getErrorWithCode("BucketAlreadyOwnedByYou");
assertFalse(getUnchecked(new FalseIfBucketAlreadyOwnedByYouOrOperationAbortedWhenBucketExists(client).setContext(
putBucket).create(e)));
assertFalse(new FalseIfBucketAlreadyOwnedByYouOrOperationAbortedWhenBucketExists(client).setContext(
putBucket).createOrPropagate(e));
verify(client);
}
@ -66,8 +66,8 @@ public class FalseIfBucketAlreadyOwnedByYouOrOperationAbortedWhenBucketExistsTes
expect(client.bucketExists("bucket")).andReturn(true);
replay(client);
Exception e = getErrorWithCode("OperationAborted");
assertFalse(getUnchecked(new FalseIfBucketAlreadyOwnedByYouOrOperationAbortedWhenBucketExists(client).setContext(
putBucket).create(e)));
assertFalse(new FalseIfBucketAlreadyOwnedByYouOrOperationAbortedWhenBucketExists(client).setContext(
putBucket).createOrPropagate(e));
verify(client);
}
@ -77,7 +77,8 @@ public class FalseIfBucketAlreadyOwnedByYouOrOperationAbortedWhenBucketExistsTes
expect(client.bucketExists("bucket")).andReturn(false);
replay(client);
Exception e = getErrorWithCode("OperationAborted");
new FalseIfBucketAlreadyOwnedByYouOrOperationAbortedWhenBucketExists(client).setContext(putBucket).create(e);
new FalseIfBucketAlreadyOwnedByYouOrOperationAbortedWhenBucketExists(client).setContext(putBucket)
.createOrPropagate(e);
}
@Test(expectedExceptions = IllegalStateException.class)
@ -86,7 +87,7 @@ public class FalseIfBucketAlreadyOwnedByYouOrOperationAbortedWhenBucketExistsTes
replay(client);
Exception e = new IllegalStateException();
new FalseIfBucketAlreadyOwnedByYouOrOperationAbortedWhenBucketExists(client).create(e);
new FalseIfBucketAlreadyOwnedByYouOrOperationAbortedWhenBucketExists(client).createOrPropagate(e);
}
@Test(expectedExceptions = AWSResponseException.class)
@ -94,7 +95,7 @@ public class FalseIfBucketAlreadyOwnedByYouOrOperationAbortedWhenBucketExistsTes
S3Client client = createMock(S3Client.class);
replay(client);
Exception e = getErrorWithCode("blah");
new FalseIfBucketAlreadyOwnedByYouOrOperationAbortedWhenBucketExists(client).create(e);
new FalseIfBucketAlreadyOwnedByYouOrOperationAbortedWhenBucketExists(client).createOrPropagate(e);
}
private Exception getErrorWithCode(String code) {

View File

@ -19,24 +19,16 @@ package org.jclouds.openstack.swift;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Predicates.equalTo;
import static com.google.common.base.Throwables.propagate;
import static com.google.common.util.concurrent.Futures.immediateFuture;
import static org.jclouds.http.HttpUtils.contains404;
import static org.jclouds.http.HttpUtils.returnValueOnCodeOrNull;
import org.jclouds.Fallback;
import com.google.common.util.concurrent.ListenableFuture;
public final class SwiftFallbacks {
private SwiftFallbacks() {
}
public static final class TrueOn404FalseOn409 implements Fallback<Boolean> {
@Override
public ListenableFuture<Boolean> create(Throwable t) throws Exception {
return immediateFuture(createOrPropagate(t));
}
@Override
public Boolean createOrPropagate(Throwable t) throws Exception {
if (contains404(checkNotNull(t, "throwable")))

View File

@ -18,48 +18,31 @@ package org.jclouds.blobstore;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Throwables.propagate;
import static com.google.common.util.concurrent.Futures.immediateFuture;
import static org.jclouds.http.HttpUtils.contains404;
import org.jclouds.Fallback;
import com.google.common.util.concurrent.ListenableFuture;
public final class BlobStoreFallbacks {
private BlobStoreFallbacks() {
}
public static final class ThrowContainerNotFoundOn404 implements Fallback<Object> {
public ListenableFuture<Object> create(Throwable t) throws Exception {
return immediateFuture(createOrPropagate(t));
}
public Object createOrPropagate(Throwable t) throws Exception {
if (contains404(checkNotNull(t, "throwable")))
throw new ContainerNotFoundException(t);
throw propagate(t);
}
}
public static final class ThrowKeyNotFoundOn404 implements Fallback<Object> {
public ListenableFuture<Object> create(Throwable t) throws Exception {
return immediateFuture(createOrPropagate(t));
}
public Object createOrPropagate(Throwable t) throws Exception {
if (contains404(checkNotNull(t, "throwable")))
throw new KeyNotFoundException(t);
throw propagate(t);
}
}
public static final class FalseOnContainerNotFound implements Fallback<Boolean> {
public ListenableFuture<Boolean> create(Throwable t) throws Exception {
return immediateFuture(createOrPropagate(t));
}
public Boolean createOrPropagate(Throwable t) throws Exception {
if (checkNotNull(t, "throwable") instanceof ContainerNotFoundException) {
return false;
@ -69,10 +52,6 @@ public final class BlobStoreFallbacks {
}
public static final class FalseOnKeyNotFound implements Fallback<Boolean> {
public ListenableFuture<Boolean> create(Throwable t) throws Exception {
return immediateFuture(createOrPropagate(t));
}
public Boolean createOrPropagate(Throwable t) throws Exception {
if (checkNotNull(t, "throwable") instanceof KeyNotFoundException) {
return false;
@ -82,10 +61,6 @@ public final class BlobStoreFallbacks {
}
public static final class NullOnContainerNotFound implements Fallback<Object> {
public ListenableFuture<Object> create(Throwable t) throws Exception {
return immediateFuture(createOrPropagate(t));
}
public Object createOrPropagate(Throwable t) throws Exception {
if (checkNotNull(t, "throwable") instanceof ContainerNotFoundException) {
return null;
@ -95,10 +70,6 @@ public final class BlobStoreFallbacks {
}
public static final class NullOnKeyNotFound implements Fallback<Object> {
public ListenableFuture<Object> create(Throwable t) throws Exception {
return immediateFuture(createOrPropagate(t));
}
public Object createOrPropagate(Throwable t) throws Exception {
if (checkNotNull(t, "throwable") instanceof KeyNotFoundException) {
return null;
@ -108,10 +79,6 @@ public final class BlobStoreFallbacks {
}
public static final class NullOnKeyAlreadyExists implements Fallback<Object> {
public ListenableFuture<Object> create(Throwable t) throws Exception {
return immediateFuture(createOrPropagate(t));
}
public Object createOrPropagate(Throwable t) throws Exception {
if (checkNotNull(t, "throwable") instanceof KeyAlreadyExistsException) {
return null;

View File

@ -17,7 +17,6 @@
package org.jclouds;
import com.google.common.annotations.Beta;
import com.google.common.util.concurrent.FutureFallback;
/**
* Provides a backup value to replace an earlier exception.
@ -25,11 +24,10 @@ import com.google.common.util.concurrent.FutureFallback;
* @param <V>
* the result type of the backup value
*
* @see FutureFallback
* @since 1.6
*/
@Beta
public interface Fallback<V> extends FutureFallback<V> {
public interface Fallback<V> {
/**
* The exception is provided so that the {@code Fallback} implementation can
* conditionally determine whether to propagate the exception or to attempt

View File

@ -21,7 +21,6 @@ import static com.google.common.base.Predicates.equalTo;
import static com.google.common.base.Predicates.in;
import static com.google.common.base.Throwables.propagate;
import static com.google.common.primitives.Ints.asList;
import static com.google.common.util.concurrent.Futures.immediateFuture;
import static org.jclouds.http.HttpUtils.contains404;
import static org.jclouds.http.HttpUtils.returnValueOnCodeOrNull;
import static org.jclouds.util.Throwables2.getFirstThrowableOfType;
@ -38,57 +37,36 @@ import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.ImmutableSet;
import com.google.common.util.concurrent.ListenableFuture;
public final class Fallbacks {
private Fallbacks() {
}
public static final class NullOnNotFoundOr404 implements Fallback<Object> {
public ListenableFuture<Object> create(Throwable t) throws Exception {
return immediateFuture(createOrPropagate(t));
}
public Object createOrPropagate(Throwable t) throws Exception {
return valOnNotFoundOr404(null, checkNotNull(t, "throwable"));
}
}
public static final class VoidOnNotFoundOr404 implements Fallback<Void> {
public ListenableFuture<Void> create(Throwable t) throws Exception {
return immediateFuture(createOrPropagate(t));
}
public Void createOrPropagate(Throwable t) throws Exception {
return valOnNotFoundOr404(null, checkNotNull(t, "throwable"));
}
}
public static final class TrueOnNotFoundOr404 implements Fallback<Boolean> {
public ListenableFuture<Boolean> create(Throwable t) throws Exception {
return immediateFuture(createOrPropagate(t));
}
public Boolean createOrPropagate(Throwable t) throws Exception {
return valOnNotFoundOr404(true, checkNotNull(t, "throwable"));
}
}
public static final class FalseOnNotFoundOr404 implements Fallback<Boolean> {
public ListenableFuture<Boolean> create(Throwable t) throws Exception {
return immediateFuture(createOrPropagate(t));
}
public Boolean createOrPropagate(Throwable t) throws Exception {
return valOnNotFoundOr404(false, checkNotNull(t, "throwable"));
}
}
public static final class FalseOnNotFoundOr422 implements Fallback<Boolean> {
public ListenableFuture<Boolean> create(Throwable t) throws Exception {
return immediateFuture(createOrPropagate(t));
}
public Boolean createOrPropagate(Throwable t) throws Exception {
if (containsResourceNotFoundException(checkNotNull(t, "throwable"))
|| returnValueOnCodeOrNull(t, true, equalTo(422)) != null)
@ -100,10 +78,6 @@ public final class Fallbacks {
/**
*/
public static final class AbsentOn403Or404Or500 implements Fallback<Optional<Object>> {
public ListenableFuture<Optional<Object>> create(Throwable t) throws Exception {
return immediateFuture(createOrPropagate(t));
}
public Optional<Object> createOrPropagate(Throwable t) throws Exception {
Boolean returnVal = returnValueOnCodeOrNull(checkNotNull(t, "throwable"), true, in(asList(403, 404, 500)));
if (returnVal != null)
@ -113,30 +87,18 @@ public final class Fallbacks {
}
public static final class EmptyFluentIterableOnNotFoundOr404 implements Fallback<FluentIterable<Object>> {
public ListenableFuture<FluentIterable<Object>> create(Throwable t) throws Exception {
return immediateFuture(createOrPropagate(t));
}
public FluentIterable<Object> createOrPropagate(Throwable t) throws Exception {
return valOnNotFoundOr404(FluentIterable.from(ImmutableSet.of()), checkNotNull(t, "throwable"));
}
}
public static final class EmptyIterableWithMarkerOnNotFoundOr404 implements Fallback<IterableWithMarker<Object>> {
public ListenableFuture<IterableWithMarker<Object>> create(Throwable t) throws Exception {
return immediateFuture(createOrPropagate(t));
}
public IterableWithMarker<Object> createOrPropagate(Throwable t) throws Exception {
return valOnNotFoundOr404(IterableWithMarkers.from(ImmutableSet.of()), checkNotNull(t, "throwable"));
}
}
public static final class EmptyPagedIterableOnNotFoundOr404 implements Fallback<PagedIterable<Object>> {
public ListenableFuture<PagedIterable<Object>> create(Throwable t) throws Exception {
return immediateFuture(createOrPropagate(t));
}
public PagedIterable<Object> createOrPropagate(Throwable t) throws Exception {
return valOnNotFoundOr404(PagedIterables.of(IterableWithMarkers.from(ImmutableSet.of())),
checkNotNull(t, "throwable"));
@ -144,44 +106,24 @@ public final class Fallbacks {
}
public static final class EmptyListOnNotFoundOr404 implements Fallback<ImmutableList<Object>> { // NO_UCD
// (unused
// code)
public ListenableFuture<ImmutableList<Object>> create(Throwable t) throws Exception {
return immediateFuture(createOrPropagate(t));
}
public ImmutableList<Object> createOrPropagate(Throwable t) throws Exception {
return valOnNotFoundOr404(ImmutableList.of(), checkNotNull(t, "throwable"));
}
}
public static final class EmptySetOnNotFoundOr404 implements Fallback<ImmutableSet<Object>> {
public ListenableFuture<ImmutableSet<Object>> create(Throwable t) throws Exception {
return immediateFuture(createOrPropagate(t));
}
public ImmutableSet<Object> createOrPropagate(Throwable t) throws Exception {
return valOnNotFoundOr404(ImmutableSet.of(), checkNotNull(t, "throwable"));
}
}
public static final class EmptyMapOnNotFoundOr404 implements Fallback<ImmutableMap<Object, Object>> {
public ListenableFuture<ImmutableMap<Object, Object>> create(Throwable t) throws Exception {
return immediateFuture(createOrPropagate(t));
}
public ImmutableMap<Object, Object> createOrPropagate(Throwable t) throws Exception {
return valOnNotFoundOr404(ImmutableMap.of(), checkNotNull(t, "throwable"));
}
}
public static final class EmptyMultimapOnNotFoundOr404 implements Fallback<ImmutableMultimap<Object, Object>> { // NO_UCD
// (unused
// code)
public ListenableFuture<ImmutableMultimap<Object, Object>> create(Throwable t) throws Exception {
return immediateFuture(createOrPropagate(t));
}
public ImmutableMultimap<Object, Object> createOrPropagate(Throwable t) throws Exception {
return valOnNotFoundOr404(ImmutableMultimap.of(), checkNotNull(t, "throwable"));
}

View File

@ -18,7 +18,6 @@ package org.jclouds.fallbacks;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Throwables.propagate;
import static com.google.common.util.concurrent.Futures.immediateFuture;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static java.util.concurrent.TimeUnit.NANOSECONDS;
@ -34,7 +33,6 @@ import com.google.common.annotations.Beta;
import com.google.common.base.Optional;
import com.google.common.base.Ticker;
import com.google.common.net.HttpHeaders;
import com.google.common.util.concurrent.ListenableFuture;
/**
* propagates as {@link RetryAfterException} if a Throwable is an
@ -54,7 +52,7 @@ public final class HeaderToRetryAfterException implements PropagateIfRetryAfter
*
* @param ticker
* how to read current time
* @param dateParser
* @param dateCodec
* how to parse the {@link HttpHeaders#RETRY_AFTER} header, if it
* is a Date.
* @return
@ -76,13 +74,13 @@ public final class HeaderToRetryAfterException implements PropagateIfRetryAfter
this.dateCodec = checkNotNull(dateCodec, "dateCodec");
}
@Override
public ListenableFuture<Object> create(Throwable t) {
@Override public Object createOrPropagate(Throwable t) throws Exception {
if (!(t instanceof HttpResponseException))
throw propagate(t);
HttpResponse response = HttpResponseException.class.cast(t).getResponse();
if (response == null)
return immediateFuture(null);
if (response == null) {
return null;
}
// https://tools.ietf.org/html/rfc2616#section-14.37
String retryAfter = response.getFirstHeaderOrNull(HttpHeaders.RETRY_AFTER);
@ -92,7 +90,7 @@ public final class HeaderToRetryAfterException implements PropagateIfRetryAfter
throw retryException.get();
}
return immediateFuture(null);
return null;
}
/**

View File

@ -18,7 +18,6 @@ package org.jclouds.fallbacks;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Throwables.propagate;
import static com.google.common.util.concurrent.Futures.immediateFuture;
import javax.inject.Inject;
import javax.inject.Singleton;
@ -28,8 +27,6 @@ import org.jclouds.http.HttpResponseException;
import org.jclouds.rest.AuthorizationException;
import org.jclouds.rest.ResourceNotFoundException;
import com.google.common.util.concurrent.ListenableFuture;
@Singleton
public final class MapHttp4xxCodesToExceptions implements Fallback<Object> {
@ -39,15 +36,9 @@ public final class MapHttp4xxCodesToExceptions implements Fallback<Object> {
MapHttp4xxCodesToExceptions(PropagateIfRetryAfter propagateIfRetryAfter) { // NO_UCD
this.propagateIfRetryAfter = checkNotNull(propagateIfRetryAfter, "propagateIfRetryAfter");
}
@Override
public ListenableFuture<Object> create(Throwable t) throws Exception { // NO_UCD
return immediateFuture(createOrPropagate(t));
}
@Override
public Object createOrPropagate(Throwable t) throws Exception {
propagateIfRetryAfter.create(t); // if we pass here, we aren't a retry-after exception
propagateIfRetryAfter.createOrPropagate(t); // if we pass here, we aren't a retry-after exception
if (t instanceof HttpResponseException) {
HttpResponseException responseException = HttpResponseException.class.cast(t);
if (responseException.getResponse() != null)

View File

@ -16,8 +16,8 @@
*/
package org.jclouds.fallbacks;
import com.google.common.util.concurrent.FutureFallback;
import com.google.common.util.concurrent.ListenableFuture;
import org.jclouds.Fallback;
import com.google.inject.ImplementedBy;
/**
@ -25,12 +25,10 @@ import com.google.inject.ImplementedBy;
* offset.
*/
@ImplementedBy(HeaderToRetryAfterException.class)
public interface PropagateIfRetryAfter extends FutureFallback<Object> {
public interface PropagateIfRetryAfter extends Fallback<Object> {
/**
* if input is not of type {@link org.jclouds.http.HttpResponseException}, this method propagates. Otherwise, immediate future of
* if input is not of type {@link org.jclouds.http.HttpResponseException}, this method propagates. Otherwise,
* {@code null}, if didn't coerce to {@link org.jclouds.rest.RetryAfterException}
*/
@Override
ListenableFuture<Object> create(Throwable t);
@Override Object createOrPropagate(Throwable t) throws Exception;
}

View File

@ -34,47 +34,42 @@ import com.google.common.net.HttpHeaders;
public class HeaderToRetryAfterExceptionTest {
@Test(expectedExceptions = RuntimeException.class)
public void testArbitraryExceptionDoesntConvert() {
fn.create(new RuntimeException());
public void testArbitraryExceptionDoesntConvert() throws Exception {
fn.createOrPropagate(new RuntimeException());
}
public void testHttpResponseExceptionWithoutResponseDoesntPropagate() {
fn.create(new HttpResponseException("message", command, null));
public void testHttpResponseExceptionWithoutResponseDoesntPropagate() throws Exception {
fn.createOrPropagate(new HttpResponseException("message", command, null));
}
public void testHttpResponseExceptionWithoutRetryAfterHeaderDoesntPropagate() {
fn.create(new HttpResponseException(command, HttpResponse.builder().statusCode(500).build()));
public void testHttpResponseExceptionWithoutRetryAfterHeaderDoesntPropagate() throws Exception {
fn.createOrPropagate(new HttpResponseException(command, HttpResponse.builder().statusCode(500).build()));
}
public void testHttpResponseExceptionWithMalformedRetryAfterHeaderDoesntConvert() {
fn.create(new HttpResponseException(command,
HttpResponse.builder()
.statusCode(503)
.addHeader(HttpHeaders.RETRY_AFTER, "Fri, 31 Dec 1999 23:59:59 ZBW").build()));
public void testHttpResponseExceptionWithMalformedRetryAfterHeaderDoesntConvert() throws Exception {
fn.createOrPropagate(new HttpResponseException(command,
HttpResponse.builder().statusCode(503).addHeader(HttpHeaders.RETRY_AFTER, "Fri, 31 Dec 1999 23:59:59 ZBW")
.build()));
}
@Test(expectedExceptions = RetryAfterException.class, expectedExceptionsMessageRegExp = "retry now")
public void testHttpResponseExceptionWithRetryAfterDate() {
fn.create(new HttpResponseException(command,
HttpResponse.builder()
.statusCode(503)
.addHeader(HttpHeaders.RETRY_AFTER, "Fri, 31 Dec 1999 23:59:59 GMT").build()));
public void testHttpResponseExceptionWithRetryAfterDate() throws Exception {
fn.createOrPropagate(new HttpResponseException(command,
HttpResponse.builder().statusCode(503).addHeader(HttpHeaders.RETRY_AFTER, "Fri, 31 Dec 1999 23:59:59 GMT")
.build()));
}
@Test(expectedExceptions = RetryAfterException.class, expectedExceptionsMessageRegExp = "retry in 700 seconds")
public void testHttpResponseExceptionWithRetryAfterOffset() {
fn.create(new HttpResponseException(command,
HttpResponse.builder()
.statusCode(503)
.addHeader(HttpHeaders.RETRY_AFTER, "700").build()));
public void testHttpResponseExceptionWithRetryAfterOffset() throws Exception {
fn.createOrPropagate(new HttpResponseException(command,
HttpResponse.builder().statusCode(503).addHeader(HttpHeaders.RETRY_AFTER, "700").build()));
}
@Test(expectedExceptions = RetryAfterException.class, expectedExceptionsMessageRegExp = "retry in 86400 seconds")
public void testHttpResponseExceptionWithRetryAfterPastIsZero() {
fn.create(new HttpResponseException(command,
HttpResponse.builder()
.statusCode(503)
.addHeader(HttpHeaders.RETRY_AFTER, "Sun, 2 Jan 2000 00:00:00 GMT").build()));
public void testHttpResponseExceptionWithRetryAfterPastIsZero() throws Exception {
fn.createOrPropagate(new HttpResponseException(command,
HttpResponse.builder().statusCode(503).addHeader(HttpHeaders.RETRY_AFTER, "Sun, 2 Jan 2000 00:00:00 GMT")
.build()));
}
public static HttpCommand command = new HttpCommand(HttpRequest.builder().method("GET").endpoint("http://stub").build());

View File

@ -31,27 +31,27 @@ public class MapHttp4xxCodesToExceptionsTest {
@Test(expectedExceptions = AuthorizationException.class)
public void test401ToAuthorizationException() throws Exception {
fn.create(new HttpResponseException(command, HttpResponse.builder().statusCode(401).build()));
fn.createOrPropagate(new HttpResponseException(command, HttpResponse.builder().statusCode(401).build()));
}
@Test(expectedExceptions = AuthorizationException.class)
public void test403ToAuthorizationException() throws Exception {
fn.create(new HttpResponseException(command, HttpResponse.builder().statusCode(403).build()));
fn.createOrPropagate(new HttpResponseException(command, HttpResponse.builder().statusCode(403).build()));
}
@Test(expectedExceptions = ResourceNotFoundException.class)
public void test404ToResourceNotFoundException() throws Exception {
fn.create(new HttpResponseException(command, HttpResponse.builder().statusCode(404).build()));
fn.createOrPropagate(new HttpResponseException(command, HttpResponse.builder().statusCode(404).build()));
}
@Test(expectedExceptions = IllegalStateException.class)
public void test409ToIllegalStateException() throws Exception {
fn.create(new HttpResponseException(command, HttpResponse.builder().statusCode(409).build()));
fn.createOrPropagate(new HttpResponseException(command, HttpResponse.builder().statusCode(409).build()));
}
@Test(expectedExceptions = RetryAfterException.class, expectedExceptionsMessageRegExp = "retry now")
public void testHttpResponseExceptionWithRetryAfterDate() throws Exception {
fn.create(new HttpResponseException(command,
fn.createOrPropagate(new HttpResponseException(command,
HttpResponse.builder()
.statusCode(503)
.addHeader(HttpHeaders.RETRY_AFTER, "Fri, 31 Dec 1999 23:59:59 GMT").build()));
@ -59,7 +59,7 @@ public class MapHttp4xxCodesToExceptionsTest {
@Test(expectedExceptions = RetryAfterException.class, expectedExceptionsMessageRegExp = "retry in 700 seconds")
public void testHttpResponseExceptionWithRetryAfterOffset() throws Exception {
fn.create(new HttpResponseException(command,
fn.createOrPropagate(new HttpResponseException(command,
HttpResponse.builder()
.statusCode(503)
.addHeader(HttpHeaders.RETRY_AFTER, "700").build()));
@ -67,7 +67,7 @@ public class MapHttp4xxCodesToExceptionsTest {
@Test(expectedExceptions = RetryAfterException.class, expectedExceptionsMessageRegExp = "retry in 86400 seconds")
public void testHttpResponseExceptionWithRetryAfterPastIsZero() throws Exception {
fn.create(new HttpResponseException(command,
fn.createOrPropagate(new HttpResponseException(command,
HttpResponse.builder()
.statusCode(503)
.addHeader(HttpHeaders.RETRY_AFTER, "Sun, 2 Jan 2000 00:00:00 GMT").build()));

View File

@ -16,8 +16,6 @@
*/
package org.jclouds.http;
import static com.google.common.util.concurrent.Futures.immediateFuture;
import java.io.Closeable;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
@ -51,7 +49,6 @@ import org.jclouds.util.Strings2;
import com.google.common.base.Function;
import com.google.common.collect.Multimap;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.inject.Provides;
/**
@ -89,10 +86,6 @@ public interface IntegrationTestClient extends Closeable {
String downloadException(@PathParam("id") String id, HttpRequestOptions options);
static class FooOnException implements org.jclouds.Fallback<String> {
public ListenableFuture<String> create(Throwable t) throws Exception {
return immediateFuture("foo");
}
public String createOrPropagate(Throwable t) throws Exception {
return "foo";
}

View File

@ -146,7 +146,6 @@ import com.google.common.io.ByteSource;
import com.google.common.io.Files;
import com.google.common.net.HttpHeaders;
import com.google.common.reflect.Invokable;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.inject.AbstractModule;
import com.google.inject.ConfigurationException;
import com.google.inject.Injector;

View File

@ -18,23 +18,15 @@ package org.jclouds.azureblob;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Throwables.propagate;
import static com.google.common.util.concurrent.Futures.immediateFuture;
import org.jclouds.Fallback;
import org.jclouds.azure.storage.AzureStorageResponseException;
import com.google.common.util.concurrent.ListenableFuture;
public final class AzureBlobFallbacks {
private AzureBlobFallbacks() {
}
public static final class FalseIfContainerAlreadyExists implements Fallback<Boolean> {
@Override
public ListenableFuture<Boolean> create(Throwable t) throws Exception {
return immediateFuture(createOrPropagate(t));
}
@Override
public Boolean createOrPropagate(Throwable t) throws Exception {
if (checkNotNull(t, "throwable") instanceof AzureStorageResponseException) {

View File

@ -18,23 +18,15 @@ package org.jclouds.dynect.v3;
import static com.google.common.base.Predicates.equalTo;
import static com.google.common.base.Throwables.propagate;
import static com.google.common.util.concurrent.Futures.immediateFuture;
import static org.jclouds.http.HttpUtils.returnValueOnCodeOrNull;
import org.jclouds.Fallback;
import com.google.common.util.concurrent.ListenableFuture;
public final class DynECTFallbacks {
private DynECTFallbacks() {
}
public static class FalseOn400 implements Fallback<Boolean> {
@Override
public ListenableFuture<Boolean> create(Throwable t) throws Exception {
return immediateFuture(createOrPropagate(t));
}
@Override
public Boolean createOrPropagate(Throwable t) throws Exception {
if (returnValueOnCodeOrNull(t, false, equalTo(400)) != null)