mirror of https://github.com/apache/jclouds.git
removed use of static fields to share type mapping info
This commit is contained in:
parent
29a7eb2b6d
commit
2523ab54ac
|
@ -131,7 +131,6 @@ import org.jclouds.location.suppliers.ImplicitLocationSupplier;
|
|||
import org.jclouds.location.suppliers.implicit.OnlyLocationOrFirstZone;
|
||||
import org.jclouds.rest.ConfiguresRestClient;
|
||||
import org.jclouds.rest.RestContext;
|
||||
import org.jclouds.rest.config.BinderUtils;
|
||||
import org.jclouds.rest.config.RestClientModule;
|
||||
import org.jclouds.rest.internal.RestContextImpl;
|
||||
|
||||
|
@ -199,26 +198,6 @@ public class CloudStackRestClientModule extends RestClientModule<CloudStackClien
|
|||
.put(SessionClient.class, SessionAsyncClient.class)//
|
||||
.build();
|
||||
|
||||
@Override
|
||||
protected void bindAsyncClient() {
|
||||
// bind the user client (default)
|
||||
super.bindAsyncClient();
|
||||
// bind the domain admin client
|
||||
BinderUtils.bindAsyncClient(binder(), CloudStackDomainAsyncClient.class);
|
||||
// bind the global admin client
|
||||
BinderUtils.bindAsyncClient(binder(), CloudStackGlobalAsyncClient.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void bindClient() {
|
||||
// bind the user client (default)
|
||||
super.bindClient();
|
||||
// bind the domain admin client
|
||||
BinderUtils.bindClient(binder(), CloudStackDomainClient.class, CloudStackDomainAsyncClient.class, DELEGATE_MAP);
|
||||
// bind the domain admin client
|
||||
BinderUtils.bindClient(binder(), CloudStackGlobalClient.class, CloudStackGlobalAsyncClient.class, DELEGATE_MAP);
|
||||
}
|
||||
|
||||
public CloudStackRestClientModule() {
|
||||
super(DELEGATE_MAP);
|
||||
}
|
||||
|
@ -232,9 +211,10 @@ public class CloudStackRestClientModule extends RestClientModule<CloudStackClien
|
|||
}).to(new TypeLiteral<RestContextImpl<CloudStackGlobalClient, CloudStackGlobalAsyncClient>>() {
|
||||
});
|
||||
bind(CredentialType.class).toProvider(CredentialTypeFromPropertyOrDefault.class);
|
||||
|
||||
// session client is used directly for filters and retry handlers, so let's bind it explicitly
|
||||
bindClientAndAsyncClient(binder(), SessionClient.class, SessionAsyncClient.class);
|
||||
bindClientAndAsyncClient(binder(), CloudStackDomainClient.class, CloudStackDomainAsyncClient.class);
|
||||
bindClientAndAsyncClient(binder(), CloudStackGlobalClient.class, CloudStackGlobalAsyncClient.class);
|
||||
bind(HttpRetryHandler.class).annotatedWith(ClientError.class).to(InvalidateSessionAndRetryOn401AndLogoutOnClose.class);
|
||||
|
||||
super.configure();
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
*/
|
||||
package org.jclouds.filesystem.config;
|
||||
|
||||
import static org.jclouds.rest.config.BinderUtils.bindClient;
|
||||
|
||||
import org.jclouds.blobstore.AsyncBlobStore;
|
||||
import org.jclouds.blobstore.BlobRequestSigner;
|
||||
import org.jclouds.blobstore.BlobStore;
|
||||
|
@ -35,9 +37,7 @@ import org.jclouds.filesystem.predicates.validators.internal.FilesystemBlobKeyVa
|
|||
import org.jclouds.filesystem.predicates.validators.internal.FilesystemContainerNameValidatorImpl;
|
||||
import org.jclouds.filesystem.strategy.internal.FilesystemStorageStrategyImpl;
|
||||
import org.jclouds.filesystem.util.internal.FileSystemBlobUtilsImpl;
|
||||
import org.jclouds.rest.config.BinderUtils;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.inject.AbstractModule;
|
||||
|
||||
/**
|
||||
|
@ -50,7 +50,7 @@ public class FilesystemBlobStoreContextModule extends AbstractModule {
|
|||
protected void configure() {
|
||||
bind(AsyncBlobStore.class).to(LocalAsyncBlobStore.class).asEagerSingleton();
|
||||
// forward all requests from TransientBlobStore to TransientAsyncBlobStore. needs above binding as cannot proxy a class
|
||||
BinderUtils.bindClient(binder(), LocalBlobStore.class, AsyncBlobStore.class, ImmutableMap.<Class<?>, Class<?>>of());
|
||||
bindClient(binder(), LocalBlobStore.class, AsyncBlobStore.class);
|
||||
bind(BlobStore.class).to(LocalBlobStore.class);
|
||||
|
||||
install(new BlobStoreObjectModule());
|
||||
|
|
|
@ -144,8 +144,7 @@ public class KeystoneAuthenticationModule extends AbstractModule {
|
|||
}
|
||||
|
||||
protected void bindAuthenticationApi() {
|
||||
// AuthenticationApi is used directly for filters and retry handlers, so let's bind it
|
||||
// explicitly
|
||||
// AuthenticationApi is used directly for filters and retry handlers, so let's bind it explicitly
|
||||
bindClientAndAsyncClient(binder(), AuthenticationApi.class, AuthenticationAsyncApi.class);
|
||||
}
|
||||
|
||||
|
|
|
@ -47,10 +47,9 @@ public class CloudIdentityAuthenticationModule extends KeystoneAuthenticationMod
|
|||
|
||||
@Override
|
||||
protected void bindAuthenticationApi() {
|
||||
// AuthenticationApi is used directly for filters and retry handlers, so let's bind it
|
||||
// explicitly
|
||||
// AuthenticationApi is used directly for filters and retry handlers, so let's bind it explicitly
|
||||
bindClientAndAsyncClient(binder(), CloudIdentityAuthenticationApi.class,
|
||||
CloudIdentityAuthenticationAsyncApi.class);
|
||||
CloudIdentityAuthenticationAsyncApi.class);
|
||||
bind(AuthenticationApi.class).to(CloudIdentityAuthenticationApi.class).in(Scopes.SINGLETON);
|
||||
bind(AuthenticationAsyncApi.class).to(CloudIdentityAuthenticationAsyncApi.class).in(Scopes.SINGLETON);
|
||||
}
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
*/
|
||||
package org.jclouds.blobstore.config;
|
||||
|
||||
import static org.jclouds.rest.config.BinderUtils.bindClient;
|
||||
|
||||
import org.jclouds.blobstore.AsyncBlobStore;
|
||||
import org.jclouds.blobstore.BlobRequestSigner;
|
||||
import org.jclouds.blobstore.BlobStore;
|
||||
|
@ -26,9 +28,7 @@ import org.jclouds.blobstore.LocalBlobRequestSigner;
|
|||
import org.jclouds.blobstore.LocalStorageStrategy;
|
||||
import org.jclouds.blobstore.TransientStorageStrategy;
|
||||
import org.jclouds.blobstore.attr.ConsistencyModel;
|
||||
import org.jclouds.rest.config.BinderUtils;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.inject.AbstractModule;
|
||||
|
||||
/**
|
||||
|
@ -41,7 +41,7 @@ public class TransientBlobStoreContextModule extends AbstractModule {
|
|||
protected void configure() {
|
||||
bind(AsyncBlobStore.class).to(LocalAsyncBlobStore.class).asEagerSingleton();
|
||||
// forward all requests from TransientBlobStore to TransientAsyncBlobStore. needs above binding as cannot proxy a class
|
||||
BinderUtils.bindClient(binder(), LocalBlobStore.class, AsyncBlobStore.class, ImmutableMap.<Class<?>, Class<?>>of());
|
||||
bindClient(binder(), LocalBlobStore.class, AsyncBlobStore.class);
|
||||
install(new BlobStoreObjectModule());
|
||||
install(new BlobStoreMapModule());
|
||||
bind(BlobStore.class).to(LocalBlobStore.class);
|
||||
|
|
|
@ -63,8 +63,7 @@ public class OpenStackAuthenticationModule extends AbstractModule {
|
|||
protected void configure() {
|
||||
bind(new TypeLiteral<Function<Credentials, AuthenticationResponse>>() {
|
||||
}).to(GetAuthenticationResponse.class);
|
||||
// OpenStackAuthClient is used directly for filters and retry handlers, so let's bind it
|
||||
// explicitly
|
||||
// OpenStackAuthClient is used directly for filters and retry handlers, so let's bind it explicitly
|
||||
bindClientAndAsyncClient(binder(), OpenStackAuthClient.class, OpenStackAuthAsyncClient.class);
|
||||
install(new FactoryModuleBuilder().build(URIFromAuthenticationResponseForService.Factory.class));
|
||||
bind(HttpRetryHandler.class).annotatedWith(ClientError.class).to(RetryOnRenew.class);
|
||||
|
|
|
@ -63,8 +63,7 @@ public class AuthenticationServiceModule extends AbstractModule {
|
|||
protected void configure() {
|
||||
bind(new TypeLiteral<Function<Credentials, Auth>>() {
|
||||
}).to(GetAuth.class);
|
||||
// ServiceClient is used directly for filters and retry handlers, so let's bind it
|
||||
// explicitly
|
||||
// ServiceClient is used directly for filters and retry handlers, so let's bind it explicitly
|
||||
bindClientAndAsyncClient(binder(), AuthenticationClient.class, AuthenticationAsyncClient.class);
|
||||
install(new FactoryModuleBuilder().implement(RegionIdToURISupplier.class,
|
||||
RegionIdToURIFromAuthForServiceSupplier.class).build(RegionIdToURISupplier.Factory.class));
|
||||
|
|
|
@ -20,7 +20,6 @@ package org.jclouds.concurrent.internal;
|
|||
|
||||
import static com.google.common.base.Optional.fromNullable;
|
||||
import static com.google.common.base.Preconditions.checkState;
|
||||
import static com.google.common.reflect.Reflection.newProxy;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
|
@ -30,15 +29,18 @@ import java.util.Set;
|
|||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
|
||||
import org.jclouds.internal.ClassMethodArgs;
|
||||
import org.jclouds.internal.ClassMethodArgsAndReturnVal;
|
||||
import org.jclouds.logging.Logger;
|
||||
import org.jclouds.rest.annotations.Delegate;
|
||||
import org.jclouds.util.Optionals2;
|
||||
import org.jclouds.util.Throwables2;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Optional;
|
||||
import com.google.common.base.Throwables;
|
||||
|
@ -48,21 +50,30 @@ import com.google.common.collect.ImmutableSet;
|
|||
import com.google.common.reflect.AbstractInvocationHandler;
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
import com.google.inject.ProvisionException;
|
||||
import com.google.inject.assistedinject.Assisted;
|
||||
|
||||
/**
|
||||
* Generates RESTful clients from appropriately annotated interfaces.
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class SyncProxy extends AbstractInvocationHandler {
|
||||
public final class SyncProxy extends AbstractInvocationHandler {
|
||||
|
||||
public static <T> T proxy(Function<ClassMethodArgsAndReturnVal, Optional<Object>> optionalConverter, Class<T> clazz, Object async,
|
||||
@Named("sync") LoadingCache<ClassMethodArgs, Object> delegateMap,
|
||||
Map<Class<?>, Class<?>> sync2Async, Map<String, Long> timeouts) throws IllegalArgumentException, SecurityException,
|
||||
NoSuchMethodException {
|
||||
return newProxy(clazz, new SyncProxy(optionalConverter, clazz, async, delegateMap, sync2Async, timeouts));
|
||||
public static interface Factory {
|
||||
/**
|
||||
* @param declaring
|
||||
* type of the interface where all methods match those of {@code async} except the return values are
|
||||
* dereferenced
|
||||
* @param async
|
||||
* object whose interface matched {@code declaring} except all methods return {@link ListenableFuture}
|
||||
* @return blocking invocation handler
|
||||
*/
|
||||
SyncProxy create(Class<?> declaring, Object async);
|
||||
}
|
||||
|
||||
@Resource
|
||||
private Logger logger = Logger.NULL;
|
||||
|
||||
private final Function<ClassMethodArgsAndReturnVal, Optional<Object>> optionalConverter;
|
||||
private final Object delegate;
|
||||
private final Class<?> declaring;
|
||||
|
@ -74,9 +85,10 @@ public class SyncProxy extends AbstractInvocationHandler {
|
|||
private static final Set<Method> objectMethods = ImmutableSet.copyOf(Object.class.getMethods());
|
||||
|
||||
@Inject
|
||||
private SyncProxy(Function<ClassMethodArgsAndReturnVal, Optional<Object>> optionalConverter, Class<?> declaring, Object async,
|
||||
@Named("sync") LoadingCache<ClassMethodArgs, Object> delegateMap, Map<Class<?>,
|
||||
Class<?>> sync2Async, final Map<String, Long> timeouts)
|
||||
@VisibleForTesting
|
||||
SyncProxy(Function<ClassMethodArgsAndReturnVal, Optional<Object>> optionalConverter,
|
||||
@Named("sync") LoadingCache<ClassMethodArgs, Object> delegateMap, Map<Class<?>, Class<?>> sync2Async,
|
||||
@Named("TIMEOUTS") Map<String, Long> timeouts, @Assisted Class<?> declaring, @Assisted Object async)
|
||||
throws SecurityException, NoSuchMethodException {
|
||||
this.optionalConverter = optionalConverter;
|
||||
this.delegateMap = delegateMap;
|
||||
|
@ -86,7 +98,6 @@ public class SyncProxy extends AbstractInvocationHandler {
|
|||
|
||||
ImmutableMap.Builder<Method, Method> methodMapBuilder = ImmutableMap.builder();
|
||||
ImmutableMap.Builder<Method, Method> syncMethodMapBuilder = ImmutableMap.builder();
|
||||
ImmutableMap.Builder<Method, Optional<Long>> timeoutMapBuilder = ImmutableMap.builder();
|
||||
|
||||
for (Method method : declaring.getMethods()) {
|
||||
if (!objectMethods.contains(method)) {
|
||||
|
@ -95,16 +106,19 @@ public class SyncProxy extends AbstractInvocationHandler {
|
|||
throw new IllegalArgumentException(String.format(
|
||||
"method %s has different typed exceptions than delegated method %s", method, delegatedMethod));
|
||||
if (delegatedMethod.getReturnType().isAssignableFrom(ListenableFuture.class)) {
|
||||
timeoutMapBuilder.put(method, timeoutInMillis(method, timeouts));
|
||||
methodMapBuilder.put(method, delegatedMethod);
|
||||
} else {
|
||||
syncMethodMapBuilder.put(method, delegatedMethod);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
methodMap = methodMapBuilder.build();
|
||||
syncMethodMap = syncMethodMapBuilder.build();
|
||||
|
||||
ImmutableMap.Builder<Method, Optional<Long>> timeoutMapBuilder = ImmutableMap.builder();
|
||||
for (Method method : methodMap.keySet()) {
|
||||
timeoutMapBuilder.put(method, timeoutInNanos(method, timeouts));
|
||||
}
|
||||
timeoutMap = timeoutMapBuilder.build();
|
||||
}
|
||||
|
||||
|
@ -140,10 +154,15 @@ public class SyncProxy extends AbstractInvocationHandler {
|
|||
}
|
||||
} else {
|
||||
try {
|
||||
ListenableFuture<?> future = ((ListenableFuture<?>) methodMap.get(method).invoke(delegate, args));
|
||||
Optional<Long> timeoutNanos = timeoutMap.get(method);
|
||||
if (timeoutNanos.isPresent())
|
||||
Method asyncMethod = methodMap.get(method);
|
||||
String name = asyncMethod.getDeclaringClass().getSimpleName() + "." + asyncMethod.getName();
|
||||
ListenableFuture<?> future = ((ListenableFuture<?>) asyncMethod.invoke(delegate, args));
|
||||
if (timeoutNanos.isPresent()) {
|
||||
logger.debug(">> blocking on %s for %s", name, timeoutNanos);
|
||||
return future.get(timeoutNanos.get(), TimeUnit.NANOSECONDS);
|
||||
}
|
||||
logger.debug(">> blocking on %s", name);
|
||||
return future.get();
|
||||
} catch (ProvisionException e) {
|
||||
throw Throwables2.returnFirstExceptionIfInListOrThrowStandardExceptionOrCause(method.getExceptionTypes(), e);
|
||||
|
@ -156,7 +175,7 @@ public class SyncProxy extends AbstractInvocationHandler {
|
|||
}
|
||||
|
||||
// override timeout by values configured in properties(in ms)
|
||||
private Optional<Long> timeoutInMillis(Method method, Map<String, Long> timeouts) {
|
||||
private Optional<Long> timeoutInNanos(Method method, Map<String, Long> timeouts) {
|
||||
String className = declaring.getSimpleName();
|
||||
Optional<Long> timeoutMillis = fromNullable(timeouts.get(className + "." + method.getName()))
|
||||
.or(fromNullable(timeouts.get(className)))
|
||||
|
@ -168,6 +187,6 @@ public class SyncProxy extends AbstractInvocationHandler {
|
|||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Sync Proxy for: " + delegate.getClass().getSimpleName();
|
||||
return "blocking invocation handler for: " + delegate.getClass().getSimpleName();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -49,21 +49,21 @@ public class BindRestContextWithWildcardExtendsExplicitAndRawType extends Abstra
|
|||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
protected void configure() {
|
||||
TypeToken concreteType = BaseRestApiMetadata.contextToken(TypeToken.of(restApiMetadata.getApi()), TypeToken
|
||||
TypeToken<?> concreteType = BaseRestApiMetadata.contextToken(TypeToken.of(restApiMetadata.getApi()), TypeToken
|
||||
.of(restApiMetadata.getAsyncApi()));
|
||||
// bind explicit type
|
||||
bind(TypeLiteral.get(concreteType.getType())).to(
|
||||
(TypeLiteral) TypeLiteral.get(Types.newParameterizedType(RestContextImpl.class,
|
||||
restApiMetadata.getApi(), restApiMetadata.getAsyncApi())));
|
||||
TypeLiteral.class.cast(TypeLiteral.get(Types.newParameterizedType(RestContextImpl.class,
|
||||
restApiMetadata.getApi(), restApiMetadata.getAsyncApi()))));
|
||||
// bind potentially wildcard type
|
||||
if (!concreteType.equals(restApiMetadata.getContext())) {
|
||||
bind(TypeLiteral.get(restApiMetadata.getContext().getType())).to(
|
||||
(TypeLiteral) TypeLiteral.get(Types.newParameterizedType(RestContextImpl.class, restApiMetadata
|
||||
.getApi(), restApiMetadata.getAsyncApi())));
|
||||
TypeLiteral.class.cast(TypeLiteral.get(Types.newParameterizedType(RestContextImpl.class,
|
||||
restApiMetadata.getApi(), restApiMetadata.getAsyncApi()))));
|
||||
}
|
||||
// bind w/o types
|
||||
bind(TypeLiteral.get(RestContext.class)).to(
|
||||
(TypeLiteral) TypeLiteral.get(Types.newParameterizedType(RestContextImpl.class,
|
||||
restApiMetadata.getApi(), restApiMetadata.getAsyncApi())));
|
||||
TypeLiteral.class.cast(TypeLiteral.get(Types.newParameterizedType(RestContextImpl.class,
|
||||
restApiMetadata.getApi(), restApiMetadata.getAsyncApi()))));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ public class AsyncClientFactory {
|
|||
private final Injector injector;
|
||||
|
||||
@Inject
|
||||
public AsyncClientFactory(Injector injector) {
|
||||
private AsyncClientFactory(Injector injector) {
|
||||
this.injector = injector;
|
||||
}
|
||||
|
||||
|
|
|
@ -23,7 +23,6 @@ import javax.inject.Singleton;
|
|||
|
||||
import org.jclouds.rest.AsyncClientFactory;
|
||||
|
||||
import com.google.inject.Injector;
|
||||
import com.google.inject.Provider;
|
||||
|
||||
/**
|
||||
|
@ -32,19 +31,19 @@ import com.google.inject.Provider;
|
|||
*/
|
||||
@Singleton
|
||||
public class AsyncClientProvider<A> implements Provider<A> {
|
||||
@Inject
|
||||
Injector injector;
|
||||
private final Class<?> asyncClientType;
|
||||
private final Class<A> asyncClientType;
|
||||
private final AsyncClientFactory factory;
|
||||
|
||||
@Inject
|
||||
AsyncClientProvider(Class<?> asyncClientType) {
|
||||
private AsyncClientProvider(AsyncClientFactory factory, Class<A> asyncClientType) {
|
||||
this.factory = factory;
|
||||
this.asyncClientType = asyncClientType;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Singleton
|
||||
public A get() {
|
||||
return (A) injector.getInstance(AsyncClientFactory.class).create(asyncClientType);
|
||||
return factory.create(asyncClientType);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -18,14 +18,11 @@
|
|||
*/
|
||||
package org.jclouds.rest.config;
|
||||
|
||||
import java.lang.reflect.InvocationHandler;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.util.Map;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.reflect.TypeParameter;
|
||||
import com.google.common.reflect.TypeToken;
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
import com.google.inject.Binder;
|
||||
import com.google.inject.Provider;
|
||||
import com.google.inject.TypeLiteral;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -34,64 +31,66 @@ import com.google.inject.Provider;
|
|||
public class BinderUtils {
|
||||
|
||||
/**
|
||||
* adds an explicit binding for a rest client, after which you can inject either the sync or
|
||||
* async client class.
|
||||
*
|
||||
* <h3>note</h3> This client cannot have @Delegate methods, so if you have them, use the
|
||||
* {@link #bindClientAndAsyncClient(Binder, Class, Class, Map) overloaded method}.
|
||||
* adds an explicit binding for {@code async} by parsing its annotations. Then. adds an explicit binding for an
|
||||
* interface which synchronously blocks on similar calls to an {@code async} type.
|
||||
*
|
||||
* @param <S>
|
||||
* sync client type
|
||||
* sync interface that blocks
|
||||
* @param <A>
|
||||
* async client type (all methods have same args as client, but return
|
||||
* listenablefuture)
|
||||
* async type where all methods have same args as {@code sync}, but returns {@link ListenableFuture}
|
||||
* @param binder
|
||||
* guice binder
|
||||
* @param syncClientType
|
||||
* interface for the sync client
|
||||
* @param asyncClientType
|
||||
* interface for the async client
|
||||
* @param sync
|
||||
* type interface that blocks
|
||||
* @param async
|
||||
* type type that returns {@link ListenableFuture}
|
||||
*/
|
||||
public static <S, A> void bindClientAndAsyncClient(Binder binder, Class<?> syncClientType, Class<?> asyncClientType) {
|
||||
bindClientAndAsyncClient(binder, syncClientType, asyncClientType, ImmutableMap.<Class<?>, Class<?>> of());
|
||||
public static <S, A> void bindClientAndAsyncClient(Binder binder, Class<S> sync, Class<A> async) {
|
||||
bindAsyncClient(binder, async);
|
||||
bindClient(binder, sync, async);
|
||||
}
|
||||
|
||||
/**
|
||||
* adds an explicit binding for a rest client, after which you can inject either the sync or
|
||||
* async client class.
|
||||
* adds an explicit binding for an interface which synchronously blocks on similar calls to an {@code async} type.
|
||||
*
|
||||
* @param <S>
|
||||
* sync client type
|
||||
* sync interface that blocks
|
||||
* @param <A>
|
||||
* async client type (all methods have same args as client, but return
|
||||
* listenablefuture)
|
||||
* async type where all methods have same args as {@code sync}, but returns {@link ListenableFuture}
|
||||
* @param binder
|
||||
* guice binder
|
||||
* @param syncClientType
|
||||
* interface for the sync client (ex. LoginClient)
|
||||
* @param asyncClientType
|
||||
* interface for the async client (ex. LoginAsyncClient)
|
||||
* @param sync2Async
|
||||
* presuming your clients are annotated with @Delegate, contains the sync to async
|
||||
* classes relating to these methods
|
||||
* @param sync
|
||||
* type interface that blocks
|
||||
* @param async
|
||||
* type type that returns {@link ListenableFuture}
|
||||
*/
|
||||
public static <S, A> void bindClientAndAsyncClient(Binder binder, Class<?> syncClientType, Class<?> asyncClientType,
|
||||
Map<Class<?>, Class<?>> sync2Async) {
|
||||
bindClient(binder, syncClientType, asyncClientType, sync2Async);
|
||||
bindAsyncClient(binder, asyncClientType);
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <S, A> void bindClient(Binder binder, Class<S> sync, Class<A> async) {
|
||||
bindClass(binder, sync);
|
||||
TypeToken<ClientProvider<S, A>> token = new TypeToken<ClientProvider<S, A>>() {
|
||||
private static final long serialVersionUID = 1L;
|
||||
}.where(new TypeParameter<S>() {
|
||||
}, sync).where(new TypeParameter<A>() {
|
||||
}, async);
|
||||
binder.bind(sync).toProvider(TypeLiteral.class.cast(TypeLiteral.get(token.getType())));
|
||||
}
|
||||
|
||||
public static <K, V> void bindClient(Binder binder, Class<K> syncClientType, Class<V> asyncClientType,
|
||||
Map<Class<?>, Class<?>> sync2Async) {
|
||||
Provider<K> asyncProvider = new ClientProvider<K, V>(syncClientType, asyncClientType, sync2Async);
|
||||
binder.requestInjection(asyncProvider);
|
||||
binder.bind(syncClientType).toProvider(asyncProvider);
|
||||
@SuppressWarnings("unchecked")
|
||||
private static <K> void bindClass(Binder binder, Class<K> sync) {
|
||||
binder.bind(TypeLiteral.class.cast(TypeLiteral.get(new TypeToken<Class<K>>() {
|
||||
private static final long serialVersionUID = 1L;
|
||||
}.where(new TypeParameter<K>() {
|
||||
}, sync).getType()))).toInstance(sync);
|
||||
}
|
||||
|
||||
public static <T> void bindAsyncClient(Binder binder, Class<T> asyncClientType) {
|
||||
Provider<T> asyncProvider = new AsyncClientProvider<T>(asyncClientType);
|
||||
binder.requestInjection(asyncProvider);
|
||||
binder.bind(asyncClientType).toProvider(asyncProvider);
|
||||
@SuppressWarnings("unchecked")
|
||||
private static <T> void bindAsyncClient(Binder binder, Class<T> async) {
|
||||
bindClass(binder, async);
|
||||
TypeToken<AsyncClientProvider<T>> token = new TypeToken<AsyncClientProvider<T>>() {
|
||||
private static final long serialVersionUID = 1L;
|
||||
}.where(new TypeParameter<T>() {
|
||||
}, async);
|
||||
binder.bind(async).toProvider(TypeLiteral.class.cast(TypeLiteral.get(token.getType())));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -18,62 +18,38 @@
|
|||
*/
|
||||
package org.jclouds.rest.config;
|
||||
|
||||
import java.util.Map;
|
||||
import static com.google.common.reflect.Reflection.newProxy;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.concurrent.internal.SyncProxy;
|
||||
import org.jclouds.internal.ClassMethodArgs;
|
||||
import org.jclouds.internal.ClassMethodArgsAndReturnVal;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Optional;
|
||||
import com.google.common.base.Throwables;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
import com.google.inject.Injector;
|
||||
import com.google.inject.Key;
|
||||
import com.google.inject.Provider;
|
||||
import com.google.inject.TypeLiteral;
|
||||
import com.google.inject.name.Names;
|
||||
|
||||
/**
|
||||
* ClientProvider makes the primary interface for the provider context. ex. {@code
|
||||
* context.getProviderSpecificContext().getApi()} is created by ClientProvider, which is a singleton
|
||||
* ClientProvider makes the primary interface for the provider context. ex.
|
||||
* {@code context.getProviderSpecificContext().getApi()} is created by ClientProvider, which is a singleton
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Singleton
|
||||
public class ClientProvider<S, A> implements Provider<S> {
|
||||
@Inject
|
||||
Injector injector;
|
||||
private final Class<?> syncClientType;
|
||||
private final Class<?> asyncClientType;
|
||||
private final Map<Class<?>, Class<?>> sync2Async;
|
||||
|
||||
private final SyncProxy.Factory factory;
|
||||
private final Class<S> syncClientType;
|
||||
private final A asyncClient;
|
||||
|
||||
@Inject
|
||||
ClientProvider(Class<?> syncClientType, Class<?> asyncClientType, Map<Class<?>, Class<?>> sync2Async) {
|
||||
this.asyncClientType = asyncClientType;
|
||||
private ClientProvider(SyncProxy.Factory factory, Class<S> syncClientType, A asyncClient) {
|
||||
this.factory = factory;
|
||||
this.asyncClient = asyncClient;
|
||||
this.syncClientType = syncClientType;
|
||||
this.sync2Async = sync2Async;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Singleton
|
||||
public S get() {
|
||||
A client = (A) injector.getInstance(Key.get(asyncClientType));
|
||||
Function<ClassMethodArgsAndReturnVal, Optional<Object>> optionalConverter = injector.getInstance(Key.get(new TypeLiteral<Function<ClassMethodArgsAndReturnVal, Optional<Object>>>() {
|
||||
}));
|
||||
LoadingCache<ClassMethodArgs, Object> delegateMap = injector.getInstance(Key.get(
|
||||
new TypeLiteral<LoadingCache<ClassMethodArgs, Object>>() {
|
||||
}, Names.named("sync")));
|
||||
Map<String, Long> timeoutsMap = injector.getInstance(Key.get(new TypeLiteral<Map<String, Long>>() {
|
||||
}, Names.named("TIMEOUTS")));
|
||||
try {
|
||||
return (S) SyncProxy.proxy(optionalConverter, syncClientType, client, delegateMap, sync2Async,
|
||||
timeoutsMap);
|
||||
} catch (Exception e) {
|
||||
throw Throwables.propagate(e);
|
||||
}
|
||||
return newProxy(syncClientType, factory.create(syncClientType, asyncClient));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,48 +19,37 @@
|
|||
package org.jclouds.rest.config;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkState;
|
||||
import static com.google.common.reflect.Reflection.newProxy;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Provider;
|
||||
|
||||
import org.jclouds.concurrent.internal.SyncProxy;
|
||||
import org.jclouds.internal.ClassMethodArgs;
|
||||
import org.jclouds.internal.ClassMethodArgsAndReturnVal;
|
||||
import org.jclouds.util.Optionals2;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Optional;
|
||||
import com.google.common.base.Throwables;
|
||||
import com.google.common.cache.CacheLoader;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
import com.google.inject.Injector;
|
||||
import com.google.inject.Key;
|
||||
import com.google.inject.TypeLiteral;
|
||||
import com.google.inject.name.Names;
|
||||
|
||||
/**
|
||||
* CreateClientForCaller is parameterized, so clients it creates aren't singletons. For example,
|
||||
* CreateClientForCaller satisfies a call like this:
|
||||
* {@code context.getProviderSpecificContext().getApi().getOrgClientForName(name)}
|
||||
* CreateClientForCaller is parameterized, so clients it creates aren't singletons. For example, CreateClientForCaller
|
||||
* satisfies a call like this: {@code context.getProviderSpecificContext().getApi().getOrgClientForName(name)}
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class CreateClientForCaller extends CacheLoader<ClassMethodArgs, Object> {
|
||||
@Inject
|
||||
Injector injector;
|
||||
private final SyncProxy.Factory factory;
|
||||
private final LoadingCache<ClassMethodArgs, Object> asyncMap;
|
||||
private final Provider<LoadingCache<ClassMethodArgs, Object>> delegateMap;
|
||||
Map<Class<?>, Class<?>> sync2Async;
|
||||
private final Map<Class<?>, Class<?>> sync2Async;
|
||||
|
||||
@Inject
|
||||
CreateClientForCaller(@Named("async") LoadingCache<ClassMethodArgs, Object> asyncMap,
|
||||
@Named("sync") Provider<LoadingCache<ClassMethodArgs, Object>> delegateMap) {
|
||||
private CreateClientForCaller(SyncProxy.Factory factory,
|
||||
@Named("async") LoadingCache<ClassMethodArgs, Object> asyncMap, Map<Class<?>, Class<?>> sync2Async) {
|
||||
this.factory = factory;
|
||||
this.asyncMap = asyncMap;
|
||||
this.delegateMap = delegateMap;
|
||||
this.sync2Async = sync2Async;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -70,15 +59,6 @@ public class CreateClientForCaller extends CacheLoader<ClassMethodArgs, Object>
|
|||
checkState(asyncClass != null, "configuration error, sync class " + syncClass + " not mapped to an async class");
|
||||
Object asyncClient = asyncMap.getUnchecked(from);
|
||||
checkState(asyncClient != null, "configuration error, sync client for " + from + " not found");
|
||||
Function<ClassMethodArgsAndReturnVal, Optional<Object>> optionalConverter = injector.getInstance(Key.get(new TypeLiteral<Function<ClassMethodArgsAndReturnVal, Optional<Object>>>() {
|
||||
}));
|
||||
Map<String, Long> timeoutsMap = injector.getInstance(Key.get(new TypeLiteral<Map<String, Long>>() {
|
||||
}, Names.named("TIMEOUTS")));
|
||||
try {
|
||||
return SyncProxy.proxy(optionalConverter, syncClass, asyncClient, delegateMap.get(), sync2Async, timeoutsMap);
|
||||
} catch (Exception e) {
|
||||
throw Throwables.propagate(e);
|
||||
}
|
||||
|
||||
return newProxy(syncClass, factory.create(syncClass, asyncClient));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
package org.jclouds.rest.config;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import static org.jclouds.rest.config.BinderUtils.*;
|
||||
import org.jclouds.rest.ConfiguresRestClient;
|
||||
import org.jclouds.util.TypeTokens2;
|
||||
|
||||
|
@ -42,8 +42,10 @@ public class RestClientModule<S, A> extends RestModule {
|
|||
protected RestClientModule(Map<Class<?>, Class<?>> sync2Async) {
|
||||
super(sync2Async);
|
||||
this.syncClientType = TypeTokens2.checkBound(new TypeToken<S>(getClass()) {
|
||||
private static final long serialVersionUID = 1L;
|
||||
});
|
||||
this.asyncClientType = TypeTokens2.checkBound(new TypeToken<A>(getClass()) {
|
||||
private static final long serialVersionUID = 1L;
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -73,8 +75,7 @@ public class RestClientModule<S, A> extends RestModule {
|
|||
@Override
|
||||
protected void configure() {
|
||||
super.configure();
|
||||
bindAsyncClient();
|
||||
bindClient();
|
||||
bindClientAndAsyncClient(binder(), syncClientType.getRawType(), asyncClientType.getRawType());
|
||||
bindErrorHandlers();
|
||||
bindRetryHandlers();
|
||||
}
|
||||
|
@ -109,14 +110,7 @@ public class RestClientModule<S, A> extends RestModule {
|
|||
*
|
||||
*/
|
||||
protected void bindErrorHandlers() {
|
||||
}
|
||||
|
||||
protected void bindAsyncClient() {
|
||||
BinderUtils.bindAsyncClient(binder(), asyncClientType.getRawType());
|
||||
}
|
||||
|
||||
protected void bindClient() {
|
||||
BinderUtils.bindClient(binder(), syncClientType.getRawType(), asyncClientType.getRawType(), sync2Async);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ package org.jclouds.rest.config;
|
|||
|
||||
import static com.google.common.reflect.Reflection.newProxy;
|
||||
import static org.jclouds.Constants.PROPERTY_TIMEOUTS_PREFIX;
|
||||
import static org.jclouds.rest.config.BinderUtils.bindClientAndAsyncClient;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.URI;
|
||||
|
@ -29,6 +30,7 @@ import java.util.concurrent.atomic.AtomicReference;
|
|||
import javax.inject.Named;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.concurrent.internal.SyncProxy;
|
||||
import org.jclouds.functions.IdentityFunction;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
|
@ -76,7 +78,7 @@ public class RestModule extends AbstractModule {
|
|||
|
||||
public static final TypeLiteral<Supplier<URI>> URI_SUPPLIER_TYPE = new TypeLiteral<Supplier<URI>>() {
|
||||
};
|
||||
protected final Map<Class<?>, Class<?>> sync2Async;
|
||||
private final Map<Class<?>, Class<?>> sync2Async;
|
||||
protected final AtomicReference<AuthorizationException> authException = Atomics.newReference();
|
||||
|
||||
public RestModule() {
|
||||
|
@ -93,14 +95,14 @@ public class RestModule extends AbstractModule {
|
|||
|
||||
@Override
|
||||
protected void configure() {
|
||||
bind(new TypeLiteral<Map<Class<?>, Class<?>>>(){}).toInstance(sync2Async);
|
||||
install(new SaxParserModule());
|
||||
install(new GsonModule());
|
||||
install(new FactoryModuleBuilder().build(BindToJsonPayloadWrappedWith.Factory.class));
|
||||
bind(IdentityFunction.class).toInstance(IdentityFunction.INSTANCE);
|
||||
bind(AsyncRestClientProxy.Factory.class).to(Factory.class).in(Scopes.SINGLETON);
|
||||
BinderUtils.bindAsyncClient(binder(), HttpAsyncClient.class);
|
||||
BinderUtils.bindClient(binder(), HttpClient.class, HttpAsyncClient.class, ImmutableMap.<Class<?>, Class<?>> of(
|
||||
HttpClient.class, HttpAsyncClient.class));
|
||||
install(new FactoryModuleBuilder().build(SyncProxy.Factory.class));
|
||||
bindClientAndAsyncClient(binder(), HttpClient.class, HttpAsyncClient.class);
|
||||
// this will help short circuit scenarios that can otherwise lock out users
|
||||
bind(new TypeLiteral<AtomicReference<AuthorizationException>>() {
|
||||
}).toInstance(authException);
|
||||
|
@ -195,14 +197,12 @@ public class RestModule extends AbstractModule {
|
|||
public TransformingHttpCommand<?> create(HttpRequest request, Function<HttpResponse, ?> transformer) {
|
||||
return new TransformingHttpCommandImpl(executorService, request, transformer);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
@Named("sync")
|
||||
LoadingCache<ClassMethodArgs, Object> provideSyncDelegateMap(CreateClientForCaller createClientForCaller) {
|
||||
createClientForCaller.sync2Async = sync2Async;
|
||||
return CacheBuilder.newBuilder().build(createClientForCaller);
|
||||
}
|
||||
|
||||
|
|
|
@ -226,14 +226,14 @@ public class AsyncRestClientProxy<T> extends AbstractInvocationHandler {
|
|||
// else try to create an instance
|
||||
return injector.getInstance(Key.get(genericReturnType, qualifier));
|
||||
}
|
||||
|
||||
|
||||
private ListenableFuture<?> createListenableFutureForHttpRequestMappedToMethodAndArgs(Method method, Object[] args)
|
||||
throws ExecutionException {
|
||||
method = annotationProcessor.getDelegateOrNull(method);
|
||||
logger.trace("Converting %s.%s", declaring.getSimpleName(), method.getName());
|
||||
String name = method.getDeclaringClass().getSimpleName() + "." + method.getName();
|
||||
logger.trace(">> converting %s", name);
|
||||
FutureFallback<?> fallback = fallbacks.getUnchecked(method);
|
||||
// in case there is an exception creating the request, we should at least
|
||||
// pass in args
|
||||
// in case there is an exception creating the request, we should at least pass in args
|
||||
if (fallback instanceof InvocationContext) {
|
||||
InvocationContext.class.cast(fallback).setContext((HttpRequest) null);
|
||||
}
|
||||
|
@ -243,13 +243,12 @@ public class AsyncRestClientProxy<T> extends AbstractInvocationHandler {
|
|||
if (fallback instanceof InvocationContext) {
|
||||
InvocationContext.class.cast(fallback).setContext(request);
|
||||
}
|
||||
logger.trace("Converted %s.%s to %s", declaring.getSimpleName(), method.getName(), request.getRequestLine());
|
||||
logger.trace("<< converted %s to %s", name, request.getRequestLine());
|
||||
|
||||
Function<HttpResponse, ?> transformer = annotationProcessor.createResponseParser(method, request);
|
||||
logger.trace("Response from %s.%s is parsed by %s", declaring.getSimpleName(), method.getName(), transformer
|
||||
.getClass().getSimpleName());
|
||||
logger.trace("<< response from %s is parsed by %s", name, transformer.getClass().getSimpleName());
|
||||
|
||||
logger.debug("Invoking %s.%s", declaring.getSimpleName(), method.getName());
|
||||
logger.debug(">> invoking %s", name);
|
||||
result = commandFactory.create(request, transformer).execute();
|
||||
} catch (RuntimeException e) {
|
||||
AuthorizationException aex = Throwables2.getFirstThrowableOfType(e, AuthorizationException.class);
|
||||
|
@ -261,8 +260,7 @@ public class AsyncRestClientProxy<T> extends AbstractInvocationHandler {
|
|||
return immediateFailedFuture(ex);
|
||||
}
|
||||
}
|
||||
logger.trace("Exceptions from %s.%s are parsed by %s", declaring.getSimpleName(), method.getName(),
|
||||
fallback.getClass().getSimpleName());
|
||||
logger.trace("<< exceptions from %s are parsed by %s", name, fallback.getClass().getSimpleName());
|
||||
return withFallback(result, fallback);
|
||||
}
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
*/
|
||||
package org.jclouds.concurrent.internal;
|
||||
|
||||
import static com.google.common.reflect.Reflection.newProxy;
|
||||
import static org.easymock.EasyMock.createMock;
|
||||
import static org.easymock.EasyMock.expect;
|
||||
import static org.easymock.EasyMock.replay;
|
||||
|
@ -69,53 +70,45 @@ public class SyncProxyTest {
|
|||
}
|
||||
|
||||
public void testWithDefaultPropTimeout() throws Exception {
|
||||
LoadingCache<ClassMethodArgs, Object> cache = CacheBuilder.newBuilder().build(
|
||||
CacheLoader.from(Functions.<Object> constant(null)));
|
||||
Sync withOverride = SyncProxy.proxy(new AlwaysPresentImplicitOptionalConverter(), Sync.class, new Async(), cache,
|
||||
ImmutableMap.<Class<?>, Class<?>> of(), ImmutableMap.<String, Long> of("default", 250L));
|
||||
|
||||
Sync withOverride = syncProxyForTimeouts(ImmutableMap.of("default", 250L));
|
||||
assertEquals(withOverride.get(), "foo");
|
||||
verify(future);
|
||||
|
||||
}
|
||||
|
||||
public void testWithClassPropTimeout() throws Exception {
|
||||
LoadingCache<ClassMethodArgs, Object> cache = CacheBuilder.newBuilder().build(
|
||||
CacheLoader.from(Functions.<Object> constant(null)));
|
||||
Sync withOverride = SyncProxy.proxy(new AlwaysPresentImplicitOptionalConverter(), Sync.class, new Async(), cache,
|
||||
ImmutableMap.<Class<?>, Class<?>> of(), ImmutableMap.<String, Long> of("default", 50L, "Sync", 250L));
|
||||
|
||||
Sync withOverride = syncProxyForTimeouts(ImmutableMap.of("default", 50L, "Sync", 250L));
|
||||
assertEquals(withOverride.get(), "foo");
|
||||
verify(future);
|
||||
|
||||
}
|
||||
|
||||
public void testWithMethodPropTimeout() throws Exception {
|
||||
LoadingCache<ClassMethodArgs, Object> cache = CacheBuilder.newBuilder().build(
|
||||
CacheLoader.from(Functions.<Object> constant(null)));
|
||||
Sync withOverride = SyncProxy.proxy(new AlwaysPresentImplicitOptionalConverter(), Sync.class, new Async(), cache,
|
||||
ImmutableMap.<Class<?>, Class<?>> of(),
|
||||
ImmutableMap.<String, Long> of("default", 50L, "Sync", 100L, "Sync.get", 250L));
|
||||
|
||||
Sync withOverride = syncProxyForTimeouts(ImmutableMap.of("default", 50L, "Sync", 100L, "Sync.get", 250L));
|
||||
assertEquals(withOverride.get(), "foo");
|
||||
verify(future);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testWithMethodWithNoTimeoutsCallGetDirectly() throws Exception {
|
||||
LoadingCache<ClassMethodArgs, Object> cache = CacheBuilder.newBuilder().build(
|
||||
CacheLoader.from(Functions.<Object> constant(null)));
|
||||
Sync withOverride = SyncProxy.proxy(new AlwaysPresentImplicitOptionalConverter(), Sync.class, new Async(), cache,
|
||||
ImmutableMap.<Class<?>, Class<?>> of(),
|
||||
ImmutableMap.<String, Long> of());
|
||||
|
||||
future = createMock(ListenableFuture.class);
|
||||
expect(future.get()).andReturn("foo");
|
||||
replay(future);
|
||||
|
||||
assertEquals(withOverride.get(), "foo");
|
||||
Sync noOverrides = syncProxyForTimeouts(ImmutableMap.<String, Long> of());
|
||||
|
||||
assertEquals(noOverrides.get(), "foo");
|
||||
verify(future);
|
||||
|
||||
}
|
||||
|
||||
private Sync syncProxyForTimeouts(ImmutableMap<String, Long> timeouts) throws NoSuchMethodException {
|
||||
LoadingCache<ClassMethodArgs, Object> cache = CacheBuilder.newBuilder().build(
|
||||
CacheLoader.from(Functions.<Object> constant(null)));
|
||||
return newProxy(
|
||||
Sync.class,
|
||||
new SyncProxy(new AlwaysPresentImplicitOptionalConverter(), cache, ImmutableMap.<Class<?>, Class<?>> of(
|
||||
Sync.class, Async.class), timeouts, Sync.class, new Async()));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ import static org.testng.Assert.assertTrue;
|
|||
import org.jclouds.Constants;
|
||||
import org.jclouds.concurrent.config.ExecutorServiceModule;
|
||||
import org.jclouds.events.config.annotations.AsyncBus;
|
||||
import org.testng.annotations.BeforeMethod;
|
||||
import org.testng.annotations.BeforeClass;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.eventbus.AsyncEventBus;
|
||||
|
@ -44,7 +44,7 @@ import com.google.inject.name.Names;
|
|||
public class EventBusModuleTest {
|
||||
private Injector injector;
|
||||
|
||||
@BeforeMethod
|
||||
@BeforeClass
|
||||
public void setup() {
|
||||
ExecutorServiceModule executorServiceModule = new ExecutorServiceModule() {
|
||||
@Override
|
||||
|
|
|
@ -21,6 +21,7 @@ package org.jclouds.abiquo.config;
|
|||
|
||||
import static org.jclouds.Constants.PROPERTY_SESSION_INTERVAL;
|
||||
import static org.jclouds.abiquo.domain.DomainWrapper.wrap;
|
||||
import static org.jclouds.rest.config.BinderUtils.bindClientAndAsyncClient;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
@ -65,7 +66,6 @@ import org.jclouds.rest.AuthorizationException;
|
|||
import org.jclouds.rest.ConfiguresRestClient;
|
||||
import org.jclouds.rest.RestContext;
|
||||
import org.jclouds.rest.Utils;
|
||||
import org.jclouds.rest.config.BinderUtils;
|
||||
import org.jclouds.rest.config.RestClientModule;
|
||||
import org.jclouds.rest.suppliers.MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier;
|
||||
import org.jclouds.util.Suppliers2;
|
||||
|
@ -100,22 +100,10 @@ public class AbiquoRestClientModule extends RestClientModule<AbiquoApi, AbiquoAs
|
|||
super(DELEGATE_MAP);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void bindAsyncClient() {
|
||||
super.bindAsyncClient();
|
||||
BinderUtils.bindAsyncClient(binder(), AbiquoHttpAsyncClient.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void bindClient() {
|
||||
super.bindClient();
|
||||
BinderUtils.bindClient(binder(), AbiquoHttpClient.class, AbiquoHttpAsyncClient.class,
|
||||
ImmutableMap.<Class<?>, Class<?>> of(AbiquoHttpClient.class, AbiquoHttpAsyncClient.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
super.configure();
|
||||
bindClientAndAsyncClient(binder(), AbiquoHttpClient.class, AbiquoHttpAsyncClient.class);
|
||||
bind(Utils.class).to(ExtendedUtils.class);
|
||||
}
|
||||
|
||||
|
|
|
@ -37,7 +37,6 @@ import org.jclouds.http.annotation.ServerError;
|
|||
import org.jclouds.location.Provider;
|
||||
import org.jclouds.rest.ConfiguresRestClient;
|
||||
import org.jclouds.rest.RestContext;
|
||||
import org.jclouds.rest.config.BinderUtils;
|
||||
import org.jclouds.rest.config.RestClientModule;
|
||||
import org.jclouds.rest.internal.RestContextImpl;
|
||||
import org.jclouds.util.Suppliers2;
|
||||
|
@ -140,22 +139,6 @@ public class VCloudDirectorRestClientModule extends RestClientModule<VCloudDirec
|
|||
.put(UserApi.class, UserAsyncApi.class)
|
||||
.build();
|
||||
|
||||
@Override
|
||||
protected void bindAsyncClient() {
|
||||
// bind the user api (default)
|
||||
super.bindAsyncClient();
|
||||
// bind the admin api
|
||||
BinderUtils.bindAsyncClient(binder(), VCloudDirectorAdminAsyncApi.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void bindClient() {
|
||||
// bind the user api (default)
|
||||
super.bindClient();
|
||||
// bind the admin api
|
||||
BinderUtils.bindClient(binder(), VCloudDirectorAdminApi.class, VCloudDirectorAdminAsyncApi.class, ADMIN_DELEGATE_MAP);
|
||||
}
|
||||
|
||||
public VCloudDirectorRestClientModule() {
|
||||
super(ADMIN_DELEGATE_MAP);
|
||||
}
|
||||
|
@ -176,6 +159,8 @@ public class VCloudDirectorRestClientModule extends RestClientModule<VCloudDirec
|
|||
bind(HttpRetryHandler.class).annotatedWith(ClientError.class).to(InvalidateSessionAndRetryOn401AndLogoutOnClose.class);
|
||||
|
||||
super.configure();
|
||||
bindClientAndAsyncClient(binder(), VCloudDirectorAdminApi.class, VCloudDirectorAdminAsyncApi.class);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
Loading…
Reference in New Issue