mirror of https://github.com/apache/jclouds.git
changes that facilitate synchronous fallbacks and http invocation
This commit is contained in:
parent
878313582a
commit
40d9f8bfe7
|
@ -35,8 +35,9 @@ import org.jclouds.blobstore.functions.BlobToHttpGetOptions;
|
||||||
import org.jclouds.http.HttpRequest;
|
import org.jclouds.http.HttpRequest;
|
||||||
import org.jclouds.http.options.GetOptions;
|
import org.jclouds.http.options.GetOptions;
|
||||||
import org.jclouds.reflect.Invocation;
|
import org.jclouds.reflect.Invocation;
|
||||||
import org.jclouds.rest.internal.RestAnnotationProcessor;
|
import org.jclouds.rest.internal.GeneratedHttpRequest;
|
||||||
|
|
||||||
|
import com.google.common.base.Function;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.google.common.reflect.Invokable;
|
import com.google.common.reflect.Invokable;
|
||||||
|
|
||||||
|
@ -46,7 +47,7 @@ import com.google.common.reflect.Invokable;
|
||||||
*/
|
*/
|
||||||
@Singleton
|
@Singleton
|
||||||
public class AtmosBlobRequestSigner implements BlobRequestSigner {
|
public class AtmosBlobRequestSigner implements BlobRequestSigner {
|
||||||
private final RestAnnotationProcessor processor;
|
private final Function<Invocation, HttpRequest> processor;
|
||||||
private final BlobToObject blobToObject;
|
private final BlobToObject blobToObject;
|
||||||
private final BlobToHttpGetOptions blob2ObjectGetOptions;
|
private final BlobToHttpGetOptions blob2ObjectGetOptions;
|
||||||
|
|
||||||
|
@ -55,7 +56,7 @@ public class AtmosBlobRequestSigner implements BlobRequestSigner {
|
||||||
private final Invokable<?, ?> createMethod;
|
private final Invokable<?, ?> createMethod;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public AtmosBlobRequestSigner(RestAnnotationProcessor processor, BlobToObject blobToObject,
|
public AtmosBlobRequestSigner(Function<Invocation, HttpRequest> processor, BlobToObject blobToObject,
|
||||||
BlobToHttpGetOptions blob2ObjectGetOptions) throws SecurityException, NoSuchMethodException {
|
BlobToHttpGetOptions blob2ObjectGetOptions) throws SecurityException, NoSuchMethodException {
|
||||||
this.processor = checkNotNull(processor, "processor");
|
this.processor = checkNotNull(processor, "processor");
|
||||||
this.blobToObject = checkNotNull(blobToObject, "blobToObject");
|
this.blobToObject = checkNotNull(blobToObject, "blobToObject");
|
||||||
|
|
|
@ -24,27 +24,32 @@ import static com.google.common.util.concurrent.Futures.immediateFuture;
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
|
||||||
|
import org.jclouds.Fallback;
|
||||||
import org.jclouds.blobstore.KeyAlreadyExistsException;
|
import org.jclouds.blobstore.KeyAlreadyExistsException;
|
||||||
import org.jclouds.http.HttpRequest;
|
import org.jclouds.http.HttpRequest;
|
||||||
import org.jclouds.javax.annotation.Nullable;
|
import org.jclouds.javax.annotation.Nullable;
|
||||||
import org.jclouds.rest.InvocationContext;
|
import org.jclouds.rest.InvocationContext;
|
||||||
|
|
||||||
import com.google.common.annotations.VisibleForTesting;
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
import com.google.common.util.concurrent.FutureFallback;
|
|
||||||
import com.google.common.util.concurrent.ListenableFuture;
|
import com.google.common.util.concurrent.ListenableFuture;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
public class EndpointIfAlreadyExists implements FutureFallback<URI>, InvocationContext<EndpointIfAlreadyExists> {
|
public class EndpointIfAlreadyExists implements Fallback<URI>, InvocationContext<EndpointIfAlreadyExists> {
|
||||||
|
|
||||||
private URI endpoint;
|
private URI endpoint;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ListenableFuture<URI> create(Throwable t) {
|
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) {
|
if (checkNotNull(t, "throwable") instanceof KeyAlreadyExistsException) {
|
||||||
return immediateFuture(endpoint);
|
return endpoint;
|
||||||
}
|
}
|
||||||
throw propagate(t);
|
throw propagate(t);
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,24 +35,24 @@ import org.testng.annotations.Test;
|
||||||
public class EndpointIfAlreadyExistsTest {
|
public class EndpointIfAlreadyExistsTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testFoundIsNullWhenEndpointNotSet() {
|
public void testFoundIsNullWhenEndpointNotSet() throws Exception {
|
||||||
assertNull(getUnchecked(new EndpointIfAlreadyExists().create(new KeyAlreadyExistsException())));
|
assertNull(getUnchecked(new EndpointIfAlreadyExists().create(new KeyAlreadyExistsException())));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testFoundIsEndpointWhenSet() {
|
public void testFoundIsEndpointWhenSet() throws Exception {
|
||||||
assertEquals(
|
assertEquals(
|
||||||
getUnchecked(new EndpointIfAlreadyExists().setEndpoint(URI.create("foo")).create(
|
getUnchecked(new EndpointIfAlreadyExists().setEndpoint(URI.create("foo")).create(
|
||||||
new KeyAlreadyExistsException())), URI.create("foo"));
|
new KeyAlreadyExistsException())), URI.create("foo"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expectedExceptions = RuntimeException.class)
|
@Test(expectedExceptions = RuntimeException.class)
|
||||||
public void testNotFoundPropagates() {
|
public void testNotFoundPropagates() throws Exception {
|
||||||
new EndpointIfAlreadyExists().create(new RuntimeException());
|
new EndpointIfAlreadyExists().create(new RuntimeException());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expectedExceptions = NullPointerException.class)
|
@Test(expectedExceptions = NullPointerException.class)
|
||||||
public void testNullIsBad() {
|
public void testNullIsBad() throws Exception {
|
||||||
new EndpointIfAlreadyExists().create(null);
|
new EndpointIfAlreadyExists().create(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,11 +20,11 @@ package org.jclouds.cloudstack.functions;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
import static com.google.common.util.concurrent.Futures.immediateFuture;
|
import static com.google.common.util.concurrent.Futures.immediateFuture;
|
||||||
|
import static org.jclouds.Fallbacks.valOnNotFoundOr404;
|
||||||
import static org.jclouds.util.Throwables2.getFirstThrowableOfType;
|
import static org.jclouds.util.Throwables2.getFirstThrowableOfType;
|
||||||
|
|
||||||
import org.jclouds.Fallbacks;
|
import org.jclouds.Fallback;
|
||||||
|
|
||||||
import com.google.common.util.concurrent.FutureFallback;
|
|
||||||
import com.google.common.util.concurrent.ListenableFuture;
|
import com.google.common.util.concurrent.ListenableFuture;
|
||||||
|
|
||||||
public final class CloudStackFallbacks {
|
public final class CloudStackFallbacks {
|
||||||
|
@ -35,14 +35,19 @@ public final class CloudStackFallbacks {
|
||||||
* CloudStack is currently sending 431 errors with the text "Unable to find account owner for ip ". In this case, we
|
* CloudStack is currently sending 431 errors with the text "Unable to find account owner for ip ". In this case, we
|
||||||
* have to ignore as there's no means for us to avoid the problem, or action to take.
|
* have to ignore as there's no means for us to avoid the problem, or action to take.
|
||||||
*/
|
*/
|
||||||
public static final class VoidOnNotFoundOr404OrUnableToFindAccountOwner implements FutureFallback<Void> {
|
public static final class VoidOnNotFoundOr404OrUnableToFindAccountOwner implements Fallback<Void> {
|
||||||
@Override
|
@Override
|
||||||
public ListenableFuture<Void> create(final Throwable t) {
|
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);
|
IllegalStateException e = getFirstThrowableOfType(checkNotNull(t, "throwable"), IllegalStateException.class);
|
||||||
if (e != null && e.getMessage().indexOf("Unable to find account owner for") != -1) {
|
if (e != null && e.getMessage().indexOf("Unable to find account owner for") != -1) {
|
||||||
return immediateFuture(null);
|
return null;
|
||||||
} else {
|
} else {
|
||||||
return Fallbacks.valOnNotFoundOr404(null, t);
|
return valOnNotFoundOr404(null, t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,24 +23,29 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
import static com.google.common.base.Throwables.propagate;
|
import static com.google.common.base.Throwables.propagate;
|
||||||
import static com.google.common.util.concurrent.Futures.immediateFuture;
|
import static com.google.common.util.concurrent.Futures.immediateFuture;
|
||||||
|
|
||||||
|
import org.jclouds.Fallback;
|
||||||
import org.jclouds.aws.AWSResponseException;
|
import org.jclouds.aws.AWSResponseException;
|
||||||
|
|
||||||
import com.google.common.base.Predicates;
|
import com.google.common.base.Predicates;
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
import com.google.common.util.concurrent.FutureFallback;
|
|
||||||
import com.google.common.util.concurrent.ListenableFuture;
|
import com.google.common.util.concurrent.ListenableFuture;
|
||||||
|
|
||||||
public final class EC2Fallbacks {
|
public final class EC2Fallbacks {
|
||||||
private EC2Fallbacks() {
|
private EC2Fallbacks() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final class VoidOnVolumeAvailable implements FutureFallback<Object> {
|
public static final class VoidOnVolumeAvailable implements Fallback<Void> {
|
||||||
@Override
|
@Override
|
||||||
public ListenableFuture<Object> create(final Throwable t) {
|
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) {
|
if (checkNotNull(t, "throwable") instanceof AWSResponseException) {
|
||||||
AWSResponseException e = AWSResponseException.class.cast(t);
|
AWSResponseException e = AWSResponseException.class.cast(t);
|
||||||
if (Predicates.in(ImmutableSet.of("IncorrectState", "available")).apply(e.getError().getCode()))
|
if (Predicates.in(ImmutableSet.of("IncorrectState", "available")).apply(e.getError().getCode()))
|
||||||
return immediateFuture(null);
|
return null;
|
||||||
}
|
}
|
||||||
throw propagate(t);
|
throw propagate(t);
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,27 +18,33 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.openstack.keystone.v2_0;
|
package org.jclouds.openstack.keystone.v2_0;
|
||||||
|
|
||||||
import org.jclouds.Fallbacks;
|
import static com.google.common.util.concurrent.Futures.immediateFuture;
|
||||||
|
import static org.jclouds.Fallbacks.valOnNotFoundOr404;
|
||||||
|
|
||||||
|
import org.jclouds.Fallback;
|
||||||
import org.jclouds.openstack.keystone.v2_0.domain.PaginatedCollection;
|
import org.jclouds.openstack.keystone.v2_0.domain.PaginatedCollection;
|
||||||
import org.jclouds.openstack.v2_0.domain.Link;
|
import org.jclouds.openstack.v2_0.domain.Link;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
import com.google.common.util.concurrent.FutureFallback;
|
|
||||||
import com.google.common.util.concurrent.ListenableFuture;
|
import com.google.common.util.concurrent.ListenableFuture;
|
||||||
|
|
||||||
public final class KeystoneFallbacks {
|
public final class KeystoneFallbacks {
|
||||||
private KeystoneFallbacks() {
|
private KeystoneFallbacks() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final class EmptyPaginatedCollectionOnNotFoundOr404 implements
|
public static final class EmptyPaginatedCollectionOnNotFoundOr404 implements Fallback<PaginatedCollection<Object>> {
|
||||||
FutureFallback<PaginatedCollection<Object>> {
|
|
||||||
private static final PaginatedCollection<Object> EMPTY = new PaginatedCollection<Object>(
|
private static final PaginatedCollection<Object> EMPTY = new PaginatedCollection<Object>(
|
||||||
ImmutableSet.<Object> of(), ImmutableSet.<Link> of()) {
|
ImmutableSet.<Object> of(), ImmutableSet.<Link> of()) {
|
||||||
};
|
};
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ListenableFuture<PaginatedCollection<Object>> create(Throwable t) {
|
public ListenableFuture<PaginatedCollection<Object>> create(Throwable t) throws Exception {
|
||||||
return Fallbacks.valOnNotFoundOr404(EMPTY, t);
|
return immediateFuture(createOrPropagate(t));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PaginatedCollection<Object> createOrPropagate(Throwable t) throws Exception {
|
||||||
|
return valOnNotFoundOr404(EMPTY, t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,24 +25,29 @@ import static com.google.common.util.concurrent.Futures.immediateFuture;
|
||||||
import static org.jclouds.http.HttpUtils.returnValueOnCodeOrNull;
|
import static org.jclouds.http.HttpUtils.returnValueOnCodeOrNull;
|
||||||
import static org.jclouds.util.Throwables2.getFirstThrowableOfType;
|
import static org.jclouds.util.Throwables2.getFirstThrowableOfType;
|
||||||
|
|
||||||
|
import org.jclouds.Fallback;
|
||||||
import org.jclouds.blobstore.ContainerNotFoundException;
|
import org.jclouds.blobstore.ContainerNotFoundException;
|
||||||
|
|
||||||
import com.google.common.util.concurrent.FutureFallback;
|
|
||||||
import com.google.common.util.concurrent.ListenableFuture;
|
import com.google.common.util.concurrent.ListenableFuture;
|
||||||
|
|
||||||
public final class S3Fallbacks {
|
public final class S3Fallbacks {
|
||||||
private S3Fallbacks() {
|
private S3Fallbacks() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final class TrueOn404OrNotFoundFalseOnIllegalState implements FutureFallback<Boolean> {
|
public static final class TrueOn404OrNotFoundFalseOnIllegalState implements Fallback<Boolean> {
|
||||||
@Override
|
@Override
|
||||||
public ListenableFuture<Boolean> create(final Throwable t) {
|
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)
|
if (getFirstThrowableOfType(checkNotNull(t, "throwable"), IllegalStateException.class) != null)
|
||||||
return immediateFuture(false);
|
return false;
|
||||||
if (getFirstThrowableOfType(t, ContainerNotFoundException.class) != null)
|
if (getFirstThrowableOfType(t, ContainerNotFoundException.class) != null)
|
||||||
return immediateFuture(true);
|
return true;
|
||||||
if (returnValueOnCodeOrNull(t, true, equalTo(404)) != null)
|
if (returnValueOnCodeOrNull(t, true, equalTo(404)) != null)
|
||||||
return immediateFuture(true);
|
return true;
|
||||||
throw propagate(t);
|
throw propagate(t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,20 +26,20 @@ import static org.jclouds.util.Throwables2.getFirstThrowableOfType;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import org.jclouds.Fallback;
|
||||||
import org.jclouds.aws.AWSResponseException;
|
import org.jclouds.aws.AWSResponseException;
|
||||||
import org.jclouds.http.HttpRequest;
|
import org.jclouds.http.HttpRequest;
|
||||||
import org.jclouds.javax.annotation.Nullable;
|
import org.jclouds.javax.annotation.Nullable;
|
||||||
import org.jclouds.rest.InvocationContext;
|
import org.jclouds.rest.InvocationContext;
|
||||||
import org.jclouds.s3.S3Client;
|
import org.jclouds.s3.S3Client;
|
||||||
|
|
||||||
import com.google.common.util.concurrent.FutureFallback;
|
|
||||||
import com.google.common.util.concurrent.ListenableFuture;
|
import com.google.common.util.concurrent.ListenableFuture;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
public class FalseIfBucketAlreadyOwnedByYouOrOperationAbortedWhenBucketExists implements FutureFallback<Boolean>,
|
public class FalseIfBucketAlreadyOwnedByYouOrOperationAbortedWhenBucketExists implements Fallback<Boolean>,
|
||||||
InvocationContext<FalseIfBucketAlreadyOwnedByYouOrOperationAbortedWhenBucketExists> {
|
InvocationContext<FalseIfBucketAlreadyOwnedByYouOrOperationAbortedWhenBucketExists> {
|
||||||
|
|
||||||
private final S3Client client;
|
private final S3Client client;
|
||||||
|
@ -51,14 +51,19 @@ public class FalseIfBucketAlreadyOwnedByYouOrOperationAbortedWhenBucketExists im
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ListenableFuture<Boolean> create(final Throwable t) {
|
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);
|
AWSResponseException exception = getFirstThrowableOfType(checkNotNull(t, "throwable"), AWSResponseException.class);
|
||||||
if (exception != null && exception.getError() != null && exception.getError().getCode() != null) {
|
if (exception != null && exception.getError() != null && exception.getError().getCode() != null) {
|
||||||
String code = exception.getError().getCode();
|
String code = exception.getError().getCode();
|
||||||
if (code.equals("BucketAlreadyOwnedByYou"))
|
if (code.equals("BucketAlreadyOwnedByYou"))
|
||||||
return immediateFuture(false);
|
return false;
|
||||||
else if (code.equals("OperationAborted") && bucket != null && client.bucketExists(bucket))
|
else if (code.equals("OperationAborted") && bucket != null && client.bucketExists(bucket))
|
||||||
return immediateFuture(false);
|
return false;
|
||||||
}
|
}
|
||||||
throw propagate(t);
|
throw propagate(t);
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,20 +25,26 @@ import static com.google.common.util.concurrent.Futures.immediateFuture;
|
||||||
import static org.jclouds.http.HttpUtils.contains404;
|
import static org.jclouds.http.HttpUtils.contains404;
|
||||||
import static org.jclouds.http.HttpUtils.returnValueOnCodeOrNull;
|
import static org.jclouds.http.HttpUtils.returnValueOnCodeOrNull;
|
||||||
|
|
||||||
import com.google.common.util.concurrent.FutureFallback;
|
import org.jclouds.Fallback;
|
||||||
|
|
||||||
import com.google.common.util.concurrent.ListenableFuture;
|
import com.google.common.util.concurrent.ListenableFuture;
|
||||||
|
|
||||||
public final class SwiftFallbacks {
|
public final class SwiftFallbacks {
|
||||||
private SwiftFallbacks() {
|
private SwiftFallbacks() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final class TrueOn404FalseOn409 implements FutureFallback<Boolean> {
|
public static final class TrueOn404FalseOn409 implements Fallback<Boolean> {
|
||||||
@Override
|
@Override
|
||||||
public ListenableFuture<Boolean> create(final Throwable t) {
|
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")))
|
if (contains404(checkNotNull(t, "throwable")))
|
||||||
return immediateFuture(true);
|
return true;
|
||||||
if (returnValueOnCodeOrNull(t, false, equalTo(409)) != null)
|
if (returnValueOnCodeOrNull(t, false, equalTo(409)) != null)
|
||||||
return immediateFuture(false);
|
return false;
|
||||||
throw propagate(t);
|
throw propagate(t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,9 +47,8 @@ import org.jclouds.openstack.swift.TemporaryUrlKey;
|
||||||
import org.jclouds.openstack.swift.blobstore.functions.BlobToObject;
|
import org.jclouds.openstack.swift.blobstore.functions.BlobToObject;
|
||||||
import org.jclouds.openstack.swift.domain.SwiftObject;
|
import org.jclouds.openstack.swift.domain.SwiftObject;
|
||||||
import org.jclouds.reflect.Invocation;
|
import org.jclouds.reflect.Invocation;
|
||||||
import org.jclouds.rest.internal.GeneratedHttpRequest;
|
|
||||||
import org.jclouds.rest.internal.RestAnnotationProcessor;
|
|
||||||
|
|
||||||
|
import com.google.common.base.Function;
|
||||||
import com.google.common.base.Supplier;
|
import com.google.common.base.Supplier;
|
||||||
import com.google.common.base.Throwables;
|
import com.google.common.base.Throwables;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
|
@ -64,7 +63,7 @@ import com.google.inject.Provider;
|
||||||
@Singleton
|
@Singleton
|
||||||
public class SwiftBlobSigner<T extends CommonSwiftAsyncClient> implements BlobRequestSigner {
|
public class SwiftBlobSigner<T extends CommonSwiftAsyncClient> implements BlobRequestSigner {
|
||||||
|
|
||||||
private final RestAnnotationProcessor processor;
|
private final Function<Invocation, HttpRequest> processor;
|
||||||
private final Crypto crypto;
|
private final Crypto crypto;
|
||||||
|
|
||||||
private final Provider<Long> unixEpochTimestampProvider;
|
private final Provider<Long> unixEpochTimestampProvider;
|
||||||
|
@ -86,8 +85,9 @@ public class SwiftBlobSigner<T extends CommonSwiftAsyncClient> implements BlobRe
|
||||||
@Inject
|
@Inject
|
||||||
protected SwiftBlobSigner(BlobToObject blobToObject, BlobToHttpGetOptions blob2HttpGetOptions, Crypto crypto,
|
protected SwiftBlobSigner(BlobToObject blobToObject, BlobToHttpGetOptions blob2HttpGetOptions, Crypto crypto,
|
||||||
@TimeStamp Provider<Long> unixEpochTimestampProvider,
|
@TimeStamp Provider<Long> unixEpochTimestampProvider,
|
||||||
@TemporaryUrlKey Supplier<String> temporaryUrlKeySupplier, RestAnnotationProcessor processor,
|
@TemporaryUrlKey Supplier<String> temporaryUrlKeySupplier,
|
||||||
Class<T> ownerType) throws SecurityException, NoSuchMethodException {
|
Function<Invocation, HttpRequest> processor, Class<T> ownerType) throws SecurityException,
|
||||||
|
NoSuchMethodException {
|
||||||
this.processor = checkNotNull(processor, "processor");
|
this.processor = checkNotNull(processor, "processor");
|
||||||
this.crypto = checkNotNull(crypto, "crypto");
|
this.crypto = checkNotNull(crypto, "crypto");
|
||||||
|
|
||||||
|
@ -112,8 +112,7 @@ public class SwiftBlobSigner<T extends CommonSwiftAsyncClient> implements BlobRe
|
||||||
public HttpRequest signGetBlob(String container, String name, long timeInSeconds) {
|
public HttpRequest signGetBlob(String container, String name, long timeInSeconds) {
|
||||||
checkNotNull(container, "container");
|
checkNotNull(container, "container");
|
||||||
checkNotNull(name, "name");
|
checkNotNull(name, "name");
|
||||||
GeneratedHttpRequest request = processor.apply(Invocation.create(getMethod,
|
HttpRequest request = processor.apply(Invocation.create(getMethod, ImmutableList.<Object> of(container, name)));
|
||||||
ImmutableList.<Object> of(container, name)));
|
|
||||||
return cleanRequest(signForTemporaryAccess(request, timeInSeconds));
|
return cleanRequest(signForTemporaryAccess(request, timeInSeconds));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -137,7 +136,7 @@ public class SwiftBlobSigner<T extends CommonSwiftAsyncClient> implements BlobRe
|
||||||
public HttpRequest signPutBlob(String container, Blob blob, long timeInSeconds) {
|
public HttpRequest signPutBlob(String container, Blob blob, long timeInSeconds) {
|
||||||
checkNotNull(container, "container");
|
checkNotNull(container, "container");
|
||||||
checkNotNull(blob, "blob");
|
checkNotNull(blob, "blob");
|
||||||
GeneratedHttpRequest request = processor.apply(Invocation.create(createMethod,
|
HttpRequest request = processor.apply(Invocation.create(createMethod,
|
||||||
ImmutableList.<Object> of(container, blobToObject.apply(blob))));
|
ImmutableList.<Object> of(container, blobToObject.apply(blob))));
|
||||||
return cleanRequest(signForTemporaryAccess(request, timeInSeconds));
|
return cleanRequest(signForTemporaryAccess(request, timeInSeconds));
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,20 +23,20 @@ import static com.google.common.base.Throwables.propagate;
|
||||||
import static com.google.common.util.concurrent.Futures.immediateFuture;
|
import static com.google.common.util.concurrent.Futures.immediateFuture;
|
||||||
import static org.jclouds.http.HttpUtils.contains404;
|
import static org.jclouds.http.HttpUtils.contains404;
|
||||||
|
|
||||||
import org.jclouds.blobstore.ContainerNotFoundException;
|
import org.jclouds.Fallback;
|
||||||
import org.jclouds.blobstore.KeyNotFoundException;
|
|
||||||
|
|
||||||
import com.google.common.util.concurrent.FutureFallback;
|
|
||||||
import com.google.common.util.concurrent.ListenableFuture;
|
import com.google.common.util.concurrent.ListenableFuture;
|
||||||
|
|
||||||
public final class BlobStoreFallbacks {
|
public final class BlobStoreFallbacks {
|
||||||
private BlobStoreFallbacks() {
|
private BlobStoreFallbacks() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final class ThrowContainerNotFoundOn404 implements FutureFallback<Object> {
|
public static final class ThrowContainerNotFoundOn404 implements Fallback<Object> {
|
||||||
|
public ListenableFuture<Object> create(Throwable t) throws Exception {
|
||||||
|
return immediateFuture(createOrPropagate(t));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
public Object createOrPropagate(Throwable t) throws Exception {
|
||||||
public ListenableFuture<Object> create(Throwable t) {
|
|
||||||
if (contains404(checkNotNull(t, "throwable")))
|
if (contains404(checkNotNull(t, "throwable")))
|
||||||
throw new ContainerNotFoundException(t);
|
throw new ContainerNotFoundException(t);
|
||||||
throw propagate(t);
|
throw propagate(t);
|
||||||
|
@ -44,10 +44,12 @@ public final class BlobStoreFallbacks {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final class ThrowKeyNotFoundOn404 implements FutureFallback<Object> {
|
public static final class ThrowKeyNotFoundOn404 implements Fallback<Object> {
|
||||||
|
public ListenableFuture<Object> create(Throwable t) throws Exception {
|
||||||
|
return immediateFuture(createOrPropagate(t));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
public Object createOrPropagate(Throwable t) throws Exception {
|
||||||
public ListenableFuture<Object> create(Throwable t) {
|
|
||||||
if (contains404(checkNotNull(t, "throwable")))
|
if (contains404(checkNotNull(t, "throwable")))
|
||||||
throw new KeyNotFoundException(t);
|
throw new KeyNotFoundException(t);
|
||||||
throw propagate(t);
|
throw propagate(t);
|
||||||
|
@ -55,45 +57,53 @@ public final class BlobStoreFallbacks {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final class FalseOnContainerNotFound implements FutureFallback<Boolean> {
|
public static final class FalseOnContainerNotFound implements Fallback<Boolean> {
|
||||||
|
public ListenableFuture<Boolean> create(Throwable t) throws Exception {
|
||||||
|
return immediateFuture(createOrPropagate(t));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
public Boolean createOrPropagate(Throwable t) throws Exception {
|
||||||
public ListenableFuture<Boolean> create(Throwable t) {
|
|
||||||
if (checkNotNull(t, "throwable") instanceof ContainerNotFoundException) {
|
if (checkNotNull(t, "throwable") instanceof ContainerNotFoundException) {
|
||||||
return immediateFuture(false);
|
return false;
|
||||||
}
|
}
|
||||||
throw propagate(t);
|
throw propagate(t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final class FalseOnKeyNotFound implements FutureFallback<Boolean> {
|
public static final class FalseOnKeyNotFound implements Fallback<Boolean> {
|
||||||
|
public ListenableFuture<Boolean> create(Throwable t) throws Exception {
|
||||||
|
return immediateFuture(createOrPropagate(t));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
public Boolean createOrPropagate(Throwable t) throws Exception {
|
||||||
public ListenableFuture<Boolean> create(Throwable t) {
|
|
||||||
if (checkNotNull(t, "throwable") instanceof KeyNotFoundException) {
|
if (checkNotNull(t, "throwable") instanceof KeyNotFoundException) {
|
||||||
return immediateFuture(false);
|
return false;
|
||||||
}
|
}
|
||||||
throw propagate(t);
|
throw propagate(t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final class NullOnContainerNotFound implements FutureFallback<Object> {
|
public static final class NullOnContainerNotFound implements Fallback<Object> {
|
||||||
|
public ListenableFuture<Object> create(Throwable t) throws Exception {
|
||||||
|
return immediateFuture(createOrPropagate(t));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
public Object createOrPropagate(Throwable t) throws Exception {
|
||||||
public ListenableFuture<Object> create(Throwable t) {
|
|
||||||
if (checkNotNull(t, "throwable") instanceof ContainerNotFoundException) {
|
if (checkNotNull(t, "throwable") instanceof ContainerNotFoundException) {
|
||||||
return immediateFuture(null);
|
return null;
|
||||||
}
|
}
|
||||||
throw propagate(t);
|
throw propagate(t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final class NullOnKeyNotFound implements FutureFallback<Object> {
|
public static final class NullOnKeyNotFound implements Fallback<Object> {
|
||||||
|
public ListenableFuture<Object> create(Throwable t) throws Exception {
|
||||||
|
return immediateFuture(createOrPropagate(t));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
public Object createOrPropagate(Throwable t) throws Exception {
|
||||||
public ListenableFuture<Object> create(Throwable t) {
|
|
||||||
if (checkNotNull(t, "throwable") instanceof KeyNotFoundException) {
|
if (checkNotNull(t, "throwable") instanceof KeyNotFoundException) {
|
||||||
return immediateFuture(null);
|
return null;
|
||||||
}
|
}
|
||||||
throw propagate(t);
|
throw propagate(t);
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,10 +24,10 @@ import static com.google.common.util.concurrent.Futures.immediateFuture;
|
||||||
|
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import org.jclouds.Fallback;
|
||||||
import org.jclouds.http.HttpResponseException;
|
import org.jclouds.http.HttpResponseException;
|
||||||
import org.jclouds.rest.AuthorizationException;
|
import org.jclouds.rest.AuthorizationException;
|
||||||
|
|
||||||
import com.google.common.util.concurrent.FutureFallback;
|
|
||||||
import com.google.common.util.concurrent.ListenableFuture;
|
import com.google.common.util.concurrent.ListenableFuture;
|
||||||
|
|
||||||
public final class TerremarkVCloudFallbacks {
|
public final class TerremarkVCloudFallbacks {
|
||||||
|
@ -40,19 +40,24 @@ public final class TerremarkVCloudFallbacks {
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
public static final class VoidOnDeleteDefaultIp implements FutureFallback<Void> {
|
public static final class VoidOnDeleteDefaultIp implements Fallback<Void> {
|
||||||
public static final Pattern MESSAGE_PATTERN = Pattern
|
public static final Pattern MESSAGE_PATTERN = Pattern
|
||||||
.compile(".*Cannot release this Public IP as it is default oubound IP.*");
|
.compile(".*Cannot release this Public IP as it is default oubound IP.*");
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ListenableFuture<Void> create(final Throwable t) {
|
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 HttpResponseException) {
|
if (checkNotNull(t, "throwable") instanceof HttpResponseException) {
|
||||||
HttpResponseException hre = HttpResponseException.class.cast(t);
|
HttpResponseException hre = HttpResponseException.class.cast(t);
|
||||||
if (hre.getResponse().getStatusCode() == 503 || hre.getResponse().getStatusCode() == 401
|
if (hre.getResponse().getStatusCode() == 503 || hre.getResponse().getStatusCode() == 401
|
||||||
|| MESSAGE_PATTERN.matcher(hre.getMessage()).matches())
|
|| MESSAGE_PATTERN.matcher(hre.getMessage()).matches())
|
||||||
return immediateFuture(null);
|
return null;
|
||||||
} else if (t instanceof AuthorizationException) {
|
} else if (t instanceof AuthorizationException) {
|
||||||
return immediateFuture(null);
|
return null;
|
||||||
}
|
}
|
||||||
throw propagate(t);
|
throw propagate(t);
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,12 +26,12 @@ import static org.jclouds.http.HttpUtils.wirePayloadIfEnabled;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Named;
|
import javax.inject.Named;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
import org.jclouds.Constants;
|
import org.jclouds.Constants;
|
||||||
|
import org.jclouds.JcloudsVersion;
|
||||||
import org.jclouds.http.HttpCommand;
|
import org.jclouds.http.HttpCommand;
|
||||||
import org.jclouds.http.HttpCommandExecutorService;
|
import org.jclouds.http.HttpCommandExecutorService;
|
||||||
import org.jclouds.http.HttpRequest;
|
import org.jclouds.http.HttpRequest;
|
||||||
|
@ -42,58 +42,72 @@ import org.jclouds.http.HttpUtils;
|
||||||
import org.jclouds.http.IOExceptionRetryHandler;
|
import org.jclouds.http.IOExceptionRetryHandler;
|
||||||
import org.jclouds.http.handlers.DelegatingErrorHandler;
|
import org.jclouds.http.handlers.DelegatingErrorHandler;
|
||||||
import org.jclouds.http.handlers.DelegatingRetryHandler;
|
import org.jclouds.http.handlers.DelegatingRetryHandler;
|
||||||
|
import org.jclouds.http.internal.BaseHttpCommandExecutorService;
|
||||||
import org.jclouds.http.internal.HttpWire;
|
import org.jclouds.http.internal.HttpWire;
|
||||||
import org.jclouds.logging.Logger;
|
import org.jclouds.io.ContentMetadataCodec;
|
||||||
import org.jclouds.util.Throwables2;
|
import org.jclouds.util.Throwables2;
|
||||||
|
|
||||||
import com.google.appengine.api.urlfetch.HTTPRequest;
|
import com.google.appengine.api.urlfetch.HTTPRequest;
|
||||||
|
import com.google.appengine.api.urlfetch.HTTPResponse;
|
||||||
import com.google.appengine.api.urlfetch.URLFetchService;
|
import com.google.appengine.api.urlfetch.URLFetchService;
|
||||||
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
import com.google.common.util.concurrent.ListenableFuture;
|
import com.google.common.util.concurrent.ListenableFuture;
|
||||||
import com.google.common.util.concurrent.ListeningExecutorService;
|
import com.google.common.util.concurrent.ListeningExecutorService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Google App Engine version of {@link HttpCommandExecutorService} using their fetchAsync call
|
* Google App Engine version of {@link HttpCommandExecutorService} using their
|
||||||
|
* fetchAsync call
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
@Singleton
|
@Singleton
|
||||||
public class AsyncGaeHttpCommandExecutorService implements HttpCommandExecutorService {
|
public class AsyncGaeHttpCommandExecutorService extends BaseHttpCommandExecutorService<HTTPRequest> {
|
||||||
private final ListeningExecutorService ioExecutor;
|
// TODO: look up gae version
|
||||||
|
public static final String USER_AGENT = String.format("jclouds/%s urlfetch/%s", JcloudsVersion.get(), "1.6.5");
|
||||||
|
|
||||||
private final URLFetchService urlFetchService;
|
private final URLFetchService urlFetchService;
|
||||||
private final ConvertToGaeRequest convertToGaeRequest;
|
private final ConvertToGaeRequest convertToGaeRequest;
|
||||||
private final ConvertToJcloudsResponse convertToJcloudsResponse;
|
private final ConvertToJcloudsResponse convertToJcloudsResponse;
|
||||||
private final DelegatingRetryHandler retryHandler;
|
private final ListeningExecutorService ioExecutor;
|
||||||
private final IOExceptionRetryHandler ioRetryHandler;
|
|
||||||
private final DelegatingErrorHandler errorHandler;
|
|
||||||
|
|
||||||
@Resource
|
|
||||||
protected Logger logger = Logger.NULL;
|
|
||||||
@Resource
|
|
||||||
@Named(Constants.LOGGER_HTTP_HEADERS)
|
|
||||||
protected Logger headerLog = Logger.NULL;
|
|
||||||
protected final HttpWire wire;
|
|
||||||
protected final HttpUtils utils;
|
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public AsyncGaeHttpCommandExecutorService(
|
public AsyncGaeHttpCommandExecutorService(URLFetchService urlFetchService, HttpUtils utils,
|
||||||
|
ContentMetadataCodec contentMetadataCodec,
|
||||||
@Named(Constants.PROPERTY_IO_WORKER_THREADS) ListeningExecutorService ioExecutor,
|
@Named(Constants.PROPERTY_IO_WORKER_THREADS) ListeningExecutorService ioExecutor,
|
||||||
URLFetchService urlFetchService, ConvertToGaeRequest convertToGaeRequest,
|
IOExceptionRetryHandler ioRetryHandler, DelegatingRetryHandler retryHandler,
|
||||||
ConvertToJcloudsResponse convertToJcloudsResponse, DelegatingRetryHandler retryHandler,
|
DelegatingErrorHandler errorHandler, HttpWire wire, ConvertToGaeRequest convertToGaeRequest,
|
||||||
IOExceptionRetryHandler ioRetryHandler, DelegatingErrorHandler errorHandler, HttpUtils utils, HttpWire wire) {
|
ConvertToJcloudsResponse convertToJcloudsResponse) {
|
||||||
|
super(utils, contentMetadataCodec, ioExecutor, retryHandler, ioRetryHandler, errorHandler, wire);
|
||||||
this.ioExecutor = ioExecutor;
|
this.ioExecutor = ioExecutor;
|
||||||
this.urlFetchService = urlFetchService;
|
this.urlFetchService = urlFetchService;
|
||||||
this.convertToGaeRequest = convertToGaeRequest;
|
this.convertToGaeRequest = convertToGaeRequest;
|
||||||
this.convertToJcloudsResponse = convertToJcloudsResponse;
|
this.convertToJcloudsResponse = convertToJcloudsResponse;
|
||||||
this.retryHandler = retryHandler;
|
}
|
||||||
this.ioRetryHandler = ioRetryHandler;
|
|
||||||
this.errorHandler = errorHandler;
|
@VisibleForTesting
|
||||||
this.utils = utils;
|
protected HttpResponse convert(HTTPResponse gaeResponse) {
|
||||||
this.wire = wire;
|
return convertToJcloudsResponse.apply(gaeResponse);
|
||||||
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
protected HTTPRequest convert(HttpRequest request) throws IOException {
|
||||||
|
return convertToGaeRequest.apply(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* nothing to clean up.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected void cleanup(HTTPRequest nativeRequest) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected HttpResponse invoke(HTTPRequest request) throws IOException {
|
||||||
|
return convert(urlFetchService.fetch(request));
|
||||||
}
|
}
|
||||||
|
|
||||||
public HTTPRequest filterLogAndConvertRe(HttpRequest request) {
|
public HTTPRequest filterLogAndConvertRe(HttpRequest request) {
|
||||||
|
|
||||||
for (HttpRequestFilter filter : request.getFilters()) {
|
for (HttpRequestFilter filter : request.getFilters()) {
|
||||||
request = filter.filter(request);
|
request = filter.filter(request);
|
||||||
}
|
}
|
||||||
|
@ -108,61 +122,59 @@ public class AsyncGaeHttpCommandExecutorService implements HttpCommandExecutorSe
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ListenableFuture<HttpResponse> submit(final HttpCommand command) {
|
public ListenableFuture<HttpResponse> submit(final HttpCommand command) {
|
||||||
|
|
||||||
HTTPRequest nativeRequest = filterLogAndConvertRe(command.getCurrentRequest());
|
HTTPRequest nativeRequest = filterLogAndConvertRe(command.getCurrentRequest());
|
||||||
|
|
||||||
ListenableFuture<HttpResponse> response = transform(
|
ListenableFuture<HttpResponse> response = transform(
|
||||||
listenInPoolThread(urlFetchService.fetchAsync(nativeRequest)), convertToJcloudsResponse);
|
listenInPoolThread(urlFetchService.fetchAsync(nativeRequest)), convertToJcloudsResponse);
|
||||||
|
|
||||||
return transform(response, new Function<HttpResponse, HttpResponse>() {
|
return transform(response, new Function<HttpResponse, HttpResponse>() {
|
||||||
|
|
||||||
@Override
|
|
||||||
public HttpResponse apply(HttpResponse response) {
|
public HttpResponse apply(HttpResponse response) {
|
||||||
try {
|
return receiveResponse(command, response);
|
||||||
logger.debug("Receiving response %s: %s", command.getCurrentRequest().hashCode(),
|
|
||||||
response.getStatusLine());
|
|
||||||
utils.logResponse(headerLog, response, "<<");
|
|
||||||
if (response.getPayload() != null && wire.enabled())
|
|
||||||
wire.input(response);
|
|
||||||
int statusCode = response.getStatusCode();
|
|
||||||
if (statusCode >= 300) {
|
|
||||||
if (shouldContinue(response))
|
|
||||||
return submit(command).get();
|
|
||||||
else
|
|
||||||
return response;
|
|
||||||
}
|
|
||||||
return response;
|
|
||||||
} catch (Exception e) {
|
|
||||||
IOException ioe = Throwables2.getFirstThrowableOfType(e, IOException.class);
|
|
||||||
if (ioe != null && ioRetryHandler.shouldRetryRequest(command, ioe)) {
|
|
||||||
try {
|
|
||||||
return submit(command).get();
|
|
||||||
} catch (Exception e1) {
|
|
||||||
command.setException(e1);
|
|
||||||
return response;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
command.setException(new HttpResponseException(e.getMessage() + " connecting to "
|
|
||||||
+ command.getCurrentRequest().getRequestLine(), command, null, e));
|
|
||||||
return response;
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
if (command.getException() != null)
|
|
||||||
propagate(command.getException());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean shouldContinue(HttpResponse response) {
|
|
||||||
boolean shouldContinue = false;
|
|
||||||
if (retryHandler.shouldRetryRequest(command, response)) {
|
|
||||||
shouldContinue = true;
|
|
||||||
} else {
|
|
||||||
errorHandler.handleError(command, response);
|
|
||||||
}
|
|
||||||
return shouldContinue;
|
|
||||||
}
|
|
||||||
}, ioExecutor);
|
}, ioExecutor);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private HttpResponse receiveResponse(HttpCommand command, HttpResponse response) {
|
||||||
|
try {
|
||||||
|
logger.debug("Receiving response %s: %s", command.getCurrentRequest().hashCode(), response.getStatusLine());
|
||||||
|
utils.logResponse(headerLog, response, "<<");
|
||||||
|
if (response.getPayload() != null && wire.enabled())
|
||||||
|
wire.input(response);
|
||||||
|
int statusCode = response.getStatusCode();
|
||||||
|
if (statusCode >= 300) {
|
||||||
|
if (shouldContinue(command, response))
|
||||||
|
return submit(command).get();
|
||||||
|
else
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
return response;
|
||||||
|
} catch (Exception e) {
|
||||||
|
IOException ioe = Throwables2.getFirstThrowableOfType(e, IOException.class);
|
||||||
|
if (ioe != null && ioRetryHandler.shouldRetryRequest(command, ioe)) {
|
||||||
|
try {
|
||||||
|
return submit(command).get();
|
||||||
|
} catch (Exception e1) {
|
||||||
|
command.setException(e1);
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
command.setException(new HttpResponseException(e.getMessage() + " connecting to "
|
||||||
|
+ command.getCurrentRequest().getRequestLine(), command, null, e));
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
if (command.getException() != null)
|
||||||
|
propagate(command.getException());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean shouldContinue(HttpCommand command, HttpResponse response) {
|
||||||
|
boolean shouldContinue = false;
|
||||||
|
if (retryHandler.shouldRetryRequest(command, response)) {
|
||||||
|
shouldContinue = true;
|
||||||
|
} else {
|
||||||
|
errorHandler.handleError(command, response);
|
||||||
|
}
|
||||||
|
return shouldContinue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,6 @@ import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.net.MalformedURLException;
|
import java.net.MalformedURLException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
|
|
@ -53,7 +53,7 @@ import com.google.common.util.concurrent.ListeningExecutorService;
|
||||||
@Singleton
|
@Singleton
|
||||||
public class GaeHttpCommandExecutorService extends BaseHttpCommandExecutorService<HTTPRequest> {
|
public class GaeHttpCommandExecutorService extends BaseHttpCommandExecutorService<HTTPRequest> {
|
||||||
//TODO: look up gae version
|
//TODO: look up gae version
|
||||||
public static final String USER_AGENT = String.format("jclouds/%s urlfetch/%s", JcloudsVersion.get(), "1.4.3");
|
public static final String USER_AGENT = String.format("jclouds/%s urlfetch/%s", JcloudsVersion.get(), "1.6.5");
|
||||||
|
|
||||||
private final URLFetchService urlFetchService;
|
private final URLFetchService urlFetchService;
|
||||||
private final ConvertToGaeRequest convertToGaeRequest;
|
private final ConvertToGaeRequest convertToGaeRequest;
|
||||||
|
|
|
@ -26,13 +26,13 @@ import static com.google.common.util.concurrent.Futures.immediateFuture;
|
||||||
|
|
||||||
import javax.ws.rs.core.Response.Status;
|
import javax.ws.rs.core.Response.Status;
|
||||||
|
|
||||||
|
import org.jclouds.Fallback;
|
||||||
import org.jclouds.abiquo.domain.exception.AbiquoException;
|
import org.jclouds.abiquo.domain.exception.AbiquoException;
|
||||||
import org.jclouds.http.HttpResponse;
|
import org.jclouds.http.HttpResponse;
|
||||||
import org.jclouds.http.HttpResponseException;
|
import org.jclouds.http.HttpResponseException;
|
||||||
import org.jclouds.rest.ResourceNotFoundException;
|
import org.jclouds.rest.ResourceNotFoundException;
|
||||||
|
|
||||||
import com.google.common.base.Predicate;
|
import com.google.common.base.Predicate;
|
||||||
import com.google.common.util.concurrent.FutureFallback;
|
|
||||||
import com.google.common.util.concurrent.ListenableFuture;
|
import com.google.common.util.concurrent.ListenableFuture;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -47,22 +47,30 @@ public final class AbiquoFallbacks {
|
||||||
/**
|
/**
|
||||||
* Return an Abiquo Exception on not found errors.
|
* Return an Abiquo Exception on not found errors.
|
||||||
*/
|
*/
|
||||||
public static final class PropagateAbiquoExceptionOnNotFoundOr4xx implements FutureFallback<Object> {
|
public static final class PropagateAbiquoExceptionOnNotFoundOr4xx implements Fallback<Object> {
|
||||||
@Override
|
@Override
|
||||||
public ListenableFuture<Object> create(final Throwable from) {
|
public ListenableFuture<Object> create(Throwable from) throws Exception {
|
||||||
Throwable exception = find(getCausalChain(from), isNotFoundAndHasAbiquoException(from), null);
|
return immediateFuture(createOrPropagate(from));
|
||||||
|
|
||||||
throw propagate(exception == null ? from : exception.getCause());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object createOrPropagate(Throwable from) throws Exception {
|
||||||
|
Throwable exception = find(getCausalChain(from), isNotFoundAndHasAbiquoException(from), null);
|
||||||
|
throw propagate(exception == null ? from : exception.getCause());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return <code>null</code> on 303 response codes when requesting a task.
|
* Return <code>null</code> on 303 response codes when requesting a task.
|
||||||
*/
|
*/
|
||||||
public static final class NullOn303 implements FutureFallback<Object> {
|
public static final class NullOn303 implements Fallback<Object> {
|
||||||
@Override
|
@Override
|
||||||
public ListenableFuture<Object> create(final Throwable from) {
|
public ListenableFuture<Object> create(Throwable from) throws Exception {
|
||||||
|
return immediateFuture(createOrPropagate(from));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object createOrPropagate(Throwable from) throws Exception {
|
||||||
Throwable exception = find(getCausalChain(from), hasResponse(from), null);
|
Throwable exception = find(getCausalChain(from), hasResponse(from), null);
|
||||||
|
|
||||||
if (exception != null) {
|
if (exception != null) {
|
||||||
|
@ -70,7 +78,7 @@ public final class AbiquoFallbacks {
|
||||||
HttpResponse response = responseException.getResponse();
|
HttpResponse response = responseException.getResponse();
|
||||||
|
|
||||||
if (response != null && response.getStatusCode() == Status.SEE_OTHER.getStatusCode()) {
|
if (response != null && response.getStatusCode() == Status.SEE_OTHER.getStatusCode()) {
|
||||||
return immediateFuture(null);
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,9 +90,14 @@ public final class AbiquoFallbacks {
|
||||||
/**
|
/**
|
||||||
* Return false on service error exceptions.
|
* Return false on service error exceptions.
|
||||||
*/
|
*/
|
||||||
public static final class FalseOn5xx implements FutureFallback<Boolean> {
|
public static final class FalseOn5xx implements Fallback<Boolean> {
|
||||||
@Override
|
@Override
|
||||||
public ListenableFuture<Boolean> create(final Throwable from) {
|
public ListenableFuture<Boolean> create(Throwable from) throws Exception {
|
||||||
|
return immediateFuture(createOrPropagate(from));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Boolean createOrPropagate(Throwable from) throws Exception {
|
||||||
Throwable exception = find(getCausalChain(from), hasResponse(from), null);
|
Throwable exception = find(getCausalChain(from), hasResponse(from), null);
|
||||||
|
|
||||||
if (exception != null) {
|
if (exception != null) {
|
||||||
|
@ -92,7 +105,7 @@ public final class AbiquoFallbacks {
|
||||||
HttpResponse response = responseException.getResponse();
|
HttpResponse response = responseException.getResponse();
|
||||||
|
|
||||||
if (response != null && response.getStatusCode() >= 500 && response.getStatusCode() < 600) {
|
if (response != null && response.getStatusCode() >= 500 && response.getStatusCode() < 600) {
|
||||||
return immediateFuture(false);
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,9 +117,14 @@ public final class AbiquoFallbacks {
|
||||||
/**
|
/**
|
||||||
* Return false on service error exceptions.
|
* Return false on service error exceptions.
|
||||||
*/
|
*/
|
||||||
public static final class FalseIfNotAvailable implements FutureFallback<Boolean> {
|
public static final class FalseIfNotAvailable implements Fallback<Boolean> {
|
||||||
@Override
|
@Override
|
||||||
public ListenableFuture<Boolean> create(final Throwable from) {
|
public ListenableFuture<Boolean> create(Throwable from) throws Exception {
|
||||||
|
return immediateFuture(createOrPropagate(from));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Boolean createOrPropagate(Throwable from) throws Exception {
|
||||||
Throwable exception = find(getCausalChain(from), isNotAvailableException(from), null);
|
Throwable exception = find(getCausalChain(from), isNotAvailableException(from), null);
|
||||||
|
|
||||||
if (exception != null) {
|
if (exception != null) {
|
||||||
|
@ -115,11 +133,11 @@ public final class AbiquoFallbacks {
|
||||||
HttpResponse response = responseException.getResponse();
|
HttpResponse response = responseException.getResponse();
|
||||||
|
|
||||||
if (response != null && response.getStatusCode() >= 500 && response.getStatusCode() < 600) {
|
if (response != null && response.getStatusCode() >= 500 && response.getStatusCode() < 600) {
|
||||||
return immediateFuture(false);
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Will enter here when exception is a ResourceNotFoundException
|
// Will enter here when exception is a ResourceNotFoundException
|
||||||
return immediateFuture(false);
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,7 @@ import javax.inject.Inject;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
import javax.ws.rs.core.Response.Status;
|
import javax.ws.rs.core.Response.Status;
|
||||||
|
|
||||||
|
import org.jclouds.Fallback;
|
||||||
import org.jclouds.http.HttpResponse;
|
import org.jclouds.http.HttpResponse;
|
||||||
import org.jclouds.http.HttpResponseException;
|
import org.jclouds.http.HttpResponseException;
|
||||||
import org.jclouds.http.functions.ParseXMLWithJAXB;
|
import org.jclouds.http.functions.ParseXMLWithJAXB;
|
||||||
|
@ -37,7 +38,6 @@ import com.abiquo.server.core.infrastructure.storage.MovedVolumeDto;
|
||||||
import com.abiquo.server.core.infrastructure.storage.VolumeManagementDto;
|
import com.abiquo.server.core.infrastructure.storage.VolumeManagementDto;
|
||||||
import com.google.common.annotations.VisibleForTesting;
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
import com.google.common.base.Predicate;
|
import com.google.common.base.Predicate;
|
||||||
import com.google.common.util.concurrent.FutureFallback;
|
|
||||||
import com.google.common.util.concurrent.ListenableFuture;
|
import com.google.common.util.concurrent.ListenableFuture;
|
||||||
import com.google.inject.TypeLiteral;
|
import com.google.inject.TypeLiteral;
|
||||||
|
|
||||||
|
@ -47,7 +47,7 @@ import com.google.inject.TypeLiteral;
|
||||||
* @author Ignasi Barrera
|
* @author Ignasi Barrera
|
||||||
*/
|
*/
|
||||||
@Singleton
|
@Singleton
|
||||||
public class MovedVolume implements FutureFallback<VolumeManagementDto> {
|
public class MovedVolume implements Fallback<VolumeManagementDto> {
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
|
@ -67,14 +67,19 @@ public class MovedVolume implements FutureFallback<VolumeManagementDto> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ListenableFuture<VolumeManagementDto> create(final Throwable from) {
|
public ListenableFuture<VolumeManagementDto> create(Throwable from) throws Exception {
|
||||||
|
return immediateFuture(createOrPropagate(from));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public VolumeManagementDto createOrPropagate(Throwable from) throws Exception {
|
||||||
Throwable exception = find(getCausalChain(from), isMovedException(from), null);
|
Throwable exception = find(getCausalChain(from), isMovedException(from), null);
|
||||||
|
|
||||||
if (exception != null) {
|
if (exception != null) {
|
||||||
HttpResponseException responseException = (HttpResponseException) exception;
|
HttpResponseException responseException = (HttpResponseException) exception;
|
||||||
HttpResponse response = responseException.getResponse();
|
HttpResponse response = responseException.getResponse();
|
||||||
|
|
||||||
return immediateFuture(parser.apply(response).getVolume());
|
return parser.apply(response).getVolume();
|
||||||
}
|
}
|
||||||
|
|
||||||
throw propagate(from);
|
throw propagate(from);
|
||||||
|
|
|
@ -19,7 +19,6 @@
|
||||||
|
|
||||||
package org.jclouds.abiquo.fallbacks;
|
package org.jclouds.abiquo.fallbacks;
|
||||||
|
|
||||||
import static com.google.common.util.concurrent.Futures.getUnchecked;
|
|
||||||
import static org.easymock.EasyMock.expect;
|
import static org.easymock.EasyMock.expect;
|
||||||
import static org.easymock.EasyMock.replay;
|
import static org.easymock.EasyMock.replay;
|
||||||
import static org.easymock.EasyMock.verify;
|
import static org.easymock.EasyMock.verify;
|
||||||
|
@ -45,13 +44,13 @@ public class FalseIfNotAvailableTest {
|
||||||
RuntimeException exception = new RuntimeException();
|
RuntimeException exception = new RuntimeException();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
function.create(exception);
|
function.createOrPropagate(exception);
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
assertEquals(ex, exception);
|
assertEquals(ex, exception);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testFalseIf5xx() {
|
public void testFalseIf5xx() throws Exception {
|
||||||
FalseIfNotAvailable function = new FalseIfNotAvailable();
|
FalseIfNotAvailable function = new FalseIfNotAvailable();
|
||||||
HttpResponse response = EasyMock.createMock(HttpResponse.class);
|
HttpResponse response = EasyMock.createMock(HttpResponse.class);
|
||||||
HttpResponseException exception = EasyMock.createMock(HttpResponseException.class);
|
HttpResponseException exception = EasyMock.createMock(HttpResponseException.class);
|
||||||
|
@ -68,7 +67,7 @@ public class FalseIfNotAvailableTest {
|
||||||
replay(response);
|
replay(response);
|
||||||
replay(exception);
|
replay(exception);
|
||||||
|
|
||||||
assertFalse(getUnchecked(function.create(exception)));
|
assertFalse(function.createOrPropagate(exception));
|
||||||
|
|
||||||
verify(response);
|
verify(response);
|
||||||
verify(exception);
|
verify(exception);
|
||||||
|
@ -92,7 +91,7 @@ public class FalseIfNotAvailableTest {
|
||||||
replay(exception);
|
replay(exception);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
function.create(exception);
|
function.createOrPropagate(exception);
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
assertEquals(ex, exception);
|
assertEquals(ex, exception);
|
||||||
}
|
}
|
||||||
|
@ -101,11 +100,11 @@ public class FalseIfNotAvailableTest {
|
||||||
verify(exception);
|
verify(exception);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testFalseIfResourceNotFound() {
|
public void testFalseIfResourceNotFound() throws Exception {
|
||||||
FalseIfNotAvailable function = new FalseIfNotAvailable();
|
FalseIfNotAvailable function = new FalseIfNotAvailable();
|
||||||
ResourceNotFoundException exception = new ResourceNotFoundException();
|
ResourceNotFoundException exception = new ResourceNotFoundException();
|
||||||
|
|
||||||
assertFalse(getUnchecked(function.create(exception)));
|
assertFalse(function.createOrPropagate(exception));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,6 @@
|
||||||
|
|
||||||
package org.jclouds.abiquo.fallbacks;
|
package org.jclouds.abiquo.fallbacks;
|
||||||
|
|
||||||
import static com.google.common.util.concurrent.Futures.getUnchecked;
|
|
||||||
import static org.easymock.EasyMock.expect;
|
import static org.easymock.EasyMock.expect;
|
||||||
import static org.easymock.EasyMock.replay;
|
import static org.easymock.EasyMock.replay;
|
||||||
import static org.easymock.EasyMock.verify;
|
import static org.easymock.EasyMock.verify;
|
||||||
|
@ -44,13 +43,13 @@ public class FalseOn5xxTest {
|
||||||
RuntimeException exception = new RuntimeException();
|
RuntimeException exception = new RuntimeException();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
function.create(exception);
|
function.createOrPropagate(exception);
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
assertEquals(ex, exception);
|
assertEquals(ex, exception);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testFalseIf5xx() {
|
public void testFalseIf5xx() throws Exception {
|
||||||
FalseOn5xx function = new FalseOn5xx();
|
FalseOn5xx function = new FalseOn5xx();
|
||||||
HttpResponse response = EasyMock.createMock(HttpResponse.class);
|
HttpResponse response = EasyMock.createMock(HttpResponse.class);
|
||||||
HttpResponseException exception = EasyMock.createMock(HttpResponseException.class);
|
HttpResponseException exception = EasyMock.createMock(HttpResponseException.class);
|
||||||
|
@ -67,7 +66,7 @@ public class FalseOn5xxTest {
|
||||||
replay(response);
|
replay(response);
|
||||||
replay(exception);
|
replay(exception);
|
||||||
|
|
||||||
assertFalse(getUnchecked(function.create(exception)));
|
assertFalse(function.createOrPropagate(exception));
|
||||||
|
|
||||||
verify(response);
|
verify(response);
|
||||||
verify(exception);
|
verify(exception);
|
||||||
|
@ -91,7 +90,7 @@ public class FalseOn5xxTest {
|
||||||
replay(exception);
|
replay(exception);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
function.create(exception);
|
function.createOrPropagate(exception);
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
assertEquals(ex, exception);
|
assertEquals(ex, exception);
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,8 +24,6 @@ import static org.easymock.EasyMock.replay;
|
||||||
import static org.easymock.EasyMock.verify;
|
import static org.easymock.EasyMock.verify;
|
||||||
import static org.testng.Assert.assertEquals;
|
import static org.testng.Assert.assertEquals;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
import javax.ws.rs.core.Response.Status;
|
import javax.ws.rs.core.Response.Status;
|
||||||
|
|
||||||
import org.easymock.EasyMock;
|
import org.easymock.EasyMock;
|
||||||
|
@ -61,7 +59,7 @@ public class MovedVolumeTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testReturnVolume() throws IOException {
|
public void testReturnVolume() throws Exception {
|
||||||
JAXBParser xmlParser = new JAXBParser("false");
|
JAXBParser xmlParser = new JAXBParser("false");
|
||||||
MovedVolume function = new MovedVolume(new ReturnMoveVolumeReference(
|
MovedVolume function = new MovedVolume(new ReturnMoveVolumeReference(
|
||||||
new JAXBParser("false"), TypeLiteral.get(MovedVolumeDto.class)));
|
new JAXBParser("false"), TypeLiteral.get(MovedVolumeDto.class)));
|
||||||
|
|
|
@ -19,7 +19,6 @@
|
||||||
|
|
||||||
package org.jclouds.abiquo.fallbacks;
|
package org.jclouds.abiquo.fallbacks;
|
||||||
|
|
||||||
import static com.google.common.util.concurrent.Futures.getUnchecked;
|
|
||||||
import static org.easymock.EasyMock.expect;
|
import static org.easymock.EasyMock.expect;
|
||||||
import static org.easymock.EasyMock.replay;
|
import static org.easymock.EasyMock.replay;
|
||||||
import static org.easymock.EasyMock.verify;
|
import static org.easymock.EasyMock.verify;
|
||||||
|
@ -44,13 +43,13 @@ public class NullOn303Test {
|
||||||
RuntimeException exception = new RuntimeException();
|
RuntimeException exception = new RuntimeException();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
function.create(exception);
|
function.createOrPropagate(exception);
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
assertEquals(ex, exception);
|
assertEquals(ex, exception);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testNullIf303() {
|
public void testNullIf303() throws Exception {
|
||||||
NullOn303 function = new NullOn303();
|
NullOn303 function = new NullOn303();
|
||||||
HttpResponse response = EasyMock.createMock(HttpResponse.class);
|
HttpResponse response = EasyMock.createMock(HttpResponse.class);
|
||||||
HttpResponseException exception = EasyMock.createMock(HttpResponseException.class);
|
HttpResponseException exception = EasyMock.createMock(HttpResponseException.class);
|
||||||
|
@ -66,7 +65,7 @@ public class NullOn303Test {
|
||||||
replay(response);
|
replay(response);
|
||||||
replay(exception);
|
replay(exception);
|
||||||
|
|
||||||
assertNull(getUnchecked(function.create(exception)));
|
assertNull(function.createOrPropagate(exception));
|
||||||
|
|
||||||
verify(response);
|
verify(response);
|
||||||
verify(exception);
|
verify(exception);
|
||||||
|
@ -89,7 +88,7 @@ public class NullOn303Test {
|
||||||
replay(exception);
|
replay(exception);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
function.create(exception);
|
function.createOrPropagate(exception);
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
assertEquals(ex, exception);
|
assertEquals(ex, exception);
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,8 @@ import static com.google.common.base.Throwables.propagate;
|
||||||
import static com.google.common.util.concurrent.Futures.immediateFuture;
|
import static com.google.common.util.concurrent.Futures.immediateFuture;
|
||||||
import static org.jclouds.http.HttpUtils.returnValueOnCodeOrNull;
|
import static org.jclouds.http.HttpUtils.returnValueOnCodeOrNull;
|
||||||
|
|
||||||
import com.google.common.util.concurrent.FutureFallback;
|
import org.jclouds.Fallback;
|
||||||
|
|
||||||
import com.google.common.util.concurrent.ListenableFuture;
|
import com.google.common.util.concurrent.ListenableFuture;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -34,10 +35,16 @@ public final class DynECTFallbacks {
|
||||||
private DynECTFallbacks() {
|
private DynECTFallbacks() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class FalseOn400 implements FutureFallback<Boolean> {
|
public static class FalseOn400 implements Fallback<Boolean> {
|
||||||
public ListenableFuture<Boolean> create(Throwable t) {
|
@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)
|
if (returnValueOnCodeOrNull(t, false, equalTo(400)) != null)
|
||||||
return immediateFuture(false);
|
return false;
|
||||||
throw propagate(t);
|
throw propagate(t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,8 +24,9 @@ import static com.google.common.base.Throwables.propagate;
|
||||||
import static com.google.common.util.concurrent.Futures.immediateFuture;
|
import static com.google.common.util.concurrent.Futures.immediateFuture;
|
||||||
import static org.jclouds.http.HttpUtils.returnValueOnCodeOrNull;
|
import static org.jclouds.http.HttpUtils.returnValueOnCodeOrNull;
|
||||||
|
|
||||||
|
import org.jclouds.Fallback;
|
||||||
|
|
||||||
import com.google.common.base.Predicates;
|
import com.google.common.base.Predicates;
|
||||||
import com.google.common.util.concurrent.FutureFallback;
|
|
||||||
import com.google.common.util.concurrent.ListenableFuture;
|
import com.google.common.util.concurrent.ListenableFuture;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -36,13 +37,18 @@ public final class JenkinsFallbacks {
|
||||||
private JenkinsFallbacks() {
|
private JenkinsFallbacks() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final class VoidOn302Or404 implements FutureFallback<Void> {
|
public static final class VoidOn302Or404 implements Fallback<Void> {
|
||||||
@Override
|
@Override
|
||||||
public ListenableFuture<Void> create(final Throwable t) {
|
public ListenableFuture<Void> create(Throwable t) throws Exception {
|
||||||
|
return immediateFuture(createOrPropagate(t));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Void createOrPropagate(Throwable t) throws Exception {
|
||||||
Boolean returnVal = returnValueOnCodeOrNull(checkNotNull(t, "throwable"), true,
|
Boolean returnVal = returnValueOnCodeOrNull(checkNotNull(t, "throwable"), true,
|
||||||
Predicates.<Integer> or(equalTo(302), equalTo(404)));
|
Predicates.<Integer> or(equalTo(302), equalTo(404)));
|
||||||
if (returnVal != null && returnVal)
|
if (returnVal != null && returnVal)
|
||||||
return immediateFuture(null);
|
return null;
|
||||||
throw propagate(t);
|
throw propagate(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,23 +22,28 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
import static com.google.common.util.concurrent.Futures.immediateFuture;
|
import static com.google.common.util.concurrent.Futures.immediateFuture;
|
||||||
import static org.jclouds.Fallbacks.valOnNotFoundOr404;
|
import static org.jclouds.Fallbacks.valOnNotFoundOr404;
|
||||||
|
|
||||||
|
import org.jclouds.Fallback;
|
||||||
import org.jclouds.aws.AWSResponseException;
|
import org.jclouds.aws.AWSResponseException;
|
||||||
|
|
||||||
import com.google.common.util.concurrent.FutureFallback;
|
|
||||||
import com.google.common.util.concurrent.ListenableFuture;
|
import com.google.common.util.concurrent.ListenableFuture;
|
||||||
|
|
||||||
public final class RDSFallbacks {
|
public final class RDSFallbacks {
|
||||||
private RDSFallbacks() {
|
private RDSFallbacks() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final class NullOnStateDeletingNotFoundOr404 implements FutureFallback<Object> {
|
public static final class NullOnStateDeletingNotFoundOr404 implements Fallback<Object> {
|
||||||
@Override
|
@Override
|
||||||
public ListenableFuture<Object> create(final Throwable t) {
|
public ListenableFuture<Object> create(Throwable t) throws Exception {
|
||||||
|
return immediateFuture(createOrPropagate(t));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object createOrPropagate(Throwable t) throws Exception {
|
||||||
if (checkNotNull(t, "throwable") instanceof AWSResponseException) {
|
if (checkNotNull(t, "throwable") instanceof AWSResponseException) {
|
||||||
AWSResponseException e = AWSResponseException.class.cast(t);
|
AWSResponseException e = AWSResponseException.class.cast(t);
|
||||||
if ("InvalidDBInstanceState".equals(e.getError().getCode())
|
if ("InvalidDBInstanceState".equals(e.getError().getCode())
|
||||||
&& e.getError().getMessage().contains("has state: deleting"))
|
&& e.getError().getMessage().contains("has state: deleting"))
|
||||||
return immediateFuture(null);
|
return null;
|
||||||
}
|
}
|
||||||
return valOnNotFoundOr404(null, t);
|
return valOnNotFoundOr404(null, t);
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,9 +22,9 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
import static com.google.common.base.Throwables.propagate;
|
import static com.google.common.base.Throwables.propagate;
|
||||||
import static com.google.common.util.concurrent.Futures.immediateFuture;
|
import static com.google.common.util.concurrent.Futures.immediateFuture;
|
||||||
|
|
||||||
|
import org.jclouds.Fallback;
|
||||||
import org.jclouds.azure.storage.AzureStorageResponseException;
|
import org.jclouds.azure.storage.AzureStorageResponseException;
|
||||||
|
|
||||||
import com.google.common.util.concurrent.FutureFallback;
|
|
||||||
import com.google.common.util.concurrent.ListenableFuture;
|
import com.google.common.util.concurrent.ListenableFuture;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -35,14 +35,18 @@ public final class AzureBlobFallbacks {
|
||||||
private AzureBlobFallbacks() {
|
private AzureBlobFallbacks() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final class FalseIfContainerAlreadyExists implements FutureFallback<Boolean> {
|
public static final class FalseIfContainerAlreadyExists implements Fallback<Boolean> {
|
||||||
|
@Override
|
||||||
|
public ListenableFuture<Boolean> create(Throwable t) throws Exception {
|
||||||
|
return immediateFuture(createOrPropagate(t));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ListenableFuture<Boolean> create(Throwable t) {
|
public Boolean createOrPropagate(Throwable t) throws Exception {
|
||||||
if (checkNotNull(t, "throwable") instanceof AzureStorageResponseException) {
|
if (checkNotNull(t, "throwable") instanceof AzureStorageResponseException) {
|
||||||
AzureStorageResponseException responseException = AzureStorageResponseException.class.cast(t);
|
AzureStorageResponseException responseException = AzureStorageResponseException.class.cast(t);
|
||||||
if ("ContainerAlreadyExists".equals(responseException.getError().getCode())) {
|
if ("ContainerAlreadyExists".equals(responseException.getError().getCode())) {
|
||||||
return immediateFuture(false);
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
throw propagate(t);
|
throw propagate(t);
|
||||||
|
|
|
@ -34,8 +34,9 @@ import org.jclouds.blobstore.functions.BlobToHttpGetOptions;
|
||||||
import org.jclouds.http.HttpRequest;
|
import org.jclouds.http.HttpRequest;
|
||||||
import org.jclouds.http.options.GetOptions;
|
import org.jclouds.http.options.GetOptions;
|
||||||
import org.jclouds.reflect.Invocation;
|
import org.jclouds.reflect.Invocation;
|
||||||
import org.jclouds.rest.internal.RestAnnotationProcessor;
|
import org.jclouds.rest.internal.GeneratedHttpRequest;
|
||||||
|
|
||||||
|
import com.google.common.base.Function;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.google.common.reflect.Invokable;
|
import com.google.common.reflect.Invokable;
|
||||||
|
|
||||||
|
@ -45,7 +46,7 @@ import com.google.common.reflect.Invokable;
|
||||||
*/
|
*/
|
||||||
@Singleton
|
@Singleton
|
||||||
public class AzureBlobRequestSigner implements BlobRequestSigner {
|
public class AzureBlobRequestSigner implements BlobRequestSigner {
|
||||||
private final RestAnnotationProcessor processor;
|
private final Function<Invocation, HttpRequest> processor;
|
||||||
private final BlobToAzureBlob blobToBlob;
|
private final BlobToAzureBlob blobToBlob;
|
||||||
private final BlobToHttpGetOptions blob2HttpGetOptions;
|
private final BlobToHttpGetOptions blob2HttpGetOptions;
|
||||||
|
|
||||||
|
@ -54,7 +55,7 @@ public class AzureBlobRequestSigner implements BlobRequestSigner {
|
||||||
private final Invokable<?, ?> createMethod;
|
private final Invokable<?, ?> createMethod;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public AzureBlobRequestSigner(RestAnnotationProcessor processor, BlobToAzureBlob blobToBlob,
|
public AzureBlobRequestSigner(Function<Invocation, HttpRequest> processor, BlobToAzureBlob blobToBlob,
|
||||||
BlobToHttpGetOptions blob2HttpGetOptions) throws SecurityException, NoSuchMethodException {
|
BlobToHttpGetOptions blob2HttpGetOptions) throws SecurityException, NoSuchMethodException {
|
||||||
this.processor = checkNotNull(processor, "processor");
|
this.processor = checkNotNull(processor, "processor");
|
||||||
this.blobToBlob = checkNotNull(blobToBlob, "blobToBlob");
|
this.blobToBlob = checkNotNull(blobToBlob, "blobToBlob");
|
||||||
|
|
|
@ -51,9 +51,8 @@ import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
|
||||||
import org.jclouds.openstack.swift.blobstore.functions.BlobToObject;
|
import org.jclouds.openstack.swift.blobstore.functions.BlobToObject;
|
||||||
import org.jclouds.openstack.swift.domain.SwiftObject;
|
import org.jclouds.openstack.swift.domain.SwiftObject;
|
||||||
import org.jclouds.reflect.Invocation;
|
import org.jclouds.reflect.Invocation;
|
||||||
import org.jclouds.rest.internal.GeneratedHttpRequest;
|
|
||||||
import org.jclouds.rest.internal.RestAnnotationProcessor;
|
|
||||||
|
|
||||||
|
import com.google.common.base.Function;
|
||||||
import com.google.common.base.Supplier;
|
import com.google.common.base.Supplier;
|
||||||
import com.google.common.base.Throwables;
|
import com.google.common.base.Throwables;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
|
@ -69,7 +68,7 @@ import com.google.inject.Provider;
|
||||||
@Singleton
|
@Singleton
|
||||||
public class HPCloudObjectStorageBlobRequestSigner implements BlobRequestSigner {
|
public class HPCloudObjectStorageBlobRequestSigner implements BlobRequestSigner {
|
||||||
|
|
||||||
private final RestAnnotationProcessor processor;
|
private final Function<Invocation, HttpRequest> processor;
|
||||||
private final Crypto crypto;
|
private final Crypto crypto;
|
||||||
|
|
||||||
private final Provider<Long> unixEpochTimestampProvider;
|
private final Provider<Long> unixEpochTimestampProvider;
|
||||||
|
@ -84,7 +83,7 @@ public class HPCloudObjectStorageBlobRequestSigner implements BlobRequestSigner
|
||||||
private final Invokable<?, ?> createMethod;
|
private final Invokable<?, ?> createMethod;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public HPCloudObjectStorageBlobRequestSigner(RestAnnotationProcessor processor,
|
public HPCloudObjectStorageBlobRequestSigner(Function<Invocation, HttpRequest> processor,
|
||||||
BlobToObject blobToObject, BlobToHttpGetOptions blob2HttpGetOptions, Crypto crypto,
|
BlobToObject blobToObject, BlobToHttpGetOptions blob2HttpGetOptions, Crypto crypto,
|
||||||
@TimeStamp Provider<Long> unixEpochTimestampProvider, Supplier<Access> access,
|
@TimeStamp Provider<Long> unixEpochTimestampProvider, Supplier<Access> access,
|
||||||
@org.jclouds.location.Provider final Supplier<Credentials> creds) throws SecurityException,
|
@org.jclouds.location.Provider final Supplier<Credentials> creds) throws SecurityException,
|
||||||
|
@ -115,8 +114,7 @@ public class HPCloudObjectStorageBlobRequestSigner implements BlobRequestSigner
|
||||||
public HttpRequest signGetBlob(String container, String name, long timeInSeconds) {
|
public HttpRequest signGetBlob(String container, String name, long timeInSeconds) {
|
||||||
checkNotNull(container, "container");
|
checkNotNull(container, "container");
|
||||||
checkNotNull(name, "name");
|
checkNotNull(name, "name");
|
||||||
GeneratedHttpRequest request = processor.apply(Invocation.create(getMethod,
|
HttpRequest request = processor.apply(Invocation.create(getMethod, ImmutableList.<Object> of(container, name)));
|
||||||
ImmutableList.<Object> of(container, name)));
|
|
||||||
return cleanRequest(signForTemporaryAccess(request, timeInSeconds));
|
return cleanRequest(signForTemporaryAccess(request, timeInSeconds));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -140,7 +138,7 @@ public class HPCloudObjectStorageBlobRequestSigner implements BlobRequestSigner
|
||||||
public HttpRequest signPutBlob(String container, Blob blob, long timeInSeconds) {
|
public HttpRequest signPutBlob(String container, Blob blob, long timeInSeconds) {
|
||||||
checkNotNull(container, "container");
|
checkNotNull(container, "container");
|
||||||
checkNotNull(blob, "blob");
|
checkNotNull(blob, "blob");
|
||||||
GeneratedHttpRequest request = processor.apply(Invocation.create(createMethod,
|
HttpRequest request = processor.apply(Invocation.create(createMethod,
|
||||||
ImmutableList.<Object> of(container, blobToObject.apply(blob))));
|
ImmutableList.<Object> of(container, blobToObject.apply(blob))));
|
||||||
return cleanRequest(signForTemporaryAccess(request, timeInSeconds));
|
return cleanRequest(signForTemporaryAccess(request, timeInSeconds));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue