removed cycle in cloudstack binding

This commit is contained in:
Adrian Cole 2012-02-01 09:52:14 -08:00
parent ec6796883d
commit e6c06e0cd0
2 changed files with 86 additions and 39 deletions

View File

@ -18,17 +18,16 @@
*/ */
package org.jclouds.cloudstack.config; package org.jclouds.cloudstack.config;
import com.google.common.base.Function; import static com.google.common.base.Throwables.propagate;
import com.google.common.base.Supplier; import static org.jclouds.rest.config.BinderUtils.bindClientAndAsyncClient;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader; import java.net.URI;
import com.google.common.cache.LoadingCache; import java.util.Map;
import com.google.common.collect.ImmutableMap; import java.util.concurrent.ExecutionException;
import com.google.inject.Inject; import java.util.concurrent.TimeUnit;
import com.google.inject.Provides;
import com.google.inject.Singleton; import javax.ws.rs.core.UriBuilder;
import com.google.inject.TypeLiteral;
import com.google.inject.name.Named;
import org.jclouds.Constants; import org.jclouds.Constants;
import org.jclouds.cloudstack.CloudStackAsyncClient; import org.jclouds.cloudstack.CloudStackAsyncClient;
import org.jclouds.cloudstack.CloudStackClient; import org.jclouds.cloudstack.CloudStackClient;
@ -123,9 +122,11 @@ import org.jclouds.cloudstack.filters.AuthenticationFilter;
import org.jclouds.cloudstack.filters.QuerySigner; import org.jclouds.cloudstack.filters.QuerySigner;
import org.jclouds.cloudstack.functions.LoginWithPasswordCredentials; import org.jclouds.cloudstack.functions.LoginWithPasswordCredentials;
import org.jclouds.cloudstack.handlers.CloudStackErrorHandler; import org.jclouds.cloudstack.handlers.CloudStackErrorHandler;
import org.jclouds.cloudstack.handlers.RetryOnRenewAndLogoutOnClose;
import org.jclouds.concurrent.RetryOnTimeOutExceptionFunction; import org.jclouds.concurrent.RetryOnTimeOutExceptionFunction;
import org.jclouds.domain.Credentials; import org.jclouds.domain.Credentials;
import org.jclouds.http.HttpErrorHandler; import org.jclouds.http.HttpErrorHandler;
import org.jclouds.http.HttpRetryHandler;
import org.jclouds.http.RequiresHttp; import org.jclouds.http.RequiresHttp;
import org.jclouds.http.annotation.ClientError; import org.jclouds.http.annotation.ClientError;
import org.jclouds.http.annotation.Redirection; import org.jclouds.http.annotation.Redirection;
@ -138,13 +139,17 @@ import org.jclouds.rest.config.BinderUtils;
import org.jclouds.rest.config.RestClientModule; import org.jclouds.rest.config.RestClientModule;
import org.jclouds.rest.internal.RestContextImpl; import org.jclouds.rest.internal.RestContextImpl;
import javax.ws.rs.core.UriBuilder; import com.google.common.base.Function;
import java.net.URI; import com.google.common.base.Supplier;
import java.util.Map; import com.google.common.cache.CacheBuilder;
import java.util.concurrent.ExecutionException; import com.google.common.cache.CacheLoader;
import java.util.concurrent.TimeUnit; import com.google.common.cache.LoadingCache;
import com.google.common.collect.ImmutableMap;
import static com.google.common.base.Throwables.propagate; import com.google.inject.Inject;
import com.google.inject.Provides;
import com.google.inject.Singleton;
import com.google.inject.TypeLiteral;
import com.google.inject.name.Named;
/** /**
* Configures the cloudstack connection. * Configures the cloudstack connection.
@ -233,7 +238,11 @@ public class CloudStackRestClientModule extends RestClientModule<CloudStackClien
}); });
install(new CloudStackParserModule()); install(new CloudStackParserModule());
bind(CredentialType.class).toProvider(CredentialTypeFromPropertyOrDefault.class); bind(CredentialType.class).toProvider(CredentialTypeFromPropertyOrDefault.class);
// bind(HttpRetryHandler.class).annotatedWith(ClientError.class).to(RetryOnRenewAndLogoutOnClose.class);
// session client is used directly for filters and retry handlers, so let's bind it explicitly
bindClientAndAsyncClient(binder(), SessionClient.class, SessionAsyncClient.class);
bind(HttpRetryHandler.class).annotatedWith(ClientError.class).to(RetryOnRenewAndLogoutOnClose.class);
super.configure(); super.configure();
} }
@ -253,15 +262,6 @@ public class CloudStackRestClientModule extends RestClientModule<CloudStackClien
return uriBuilder.get().scheme(normal.getScheme()).host(normal.getHost()).path("/").port(port).build(); return uriBuilder.get().scheme(normal.getScheme()).host(normal.getHost()).path("/").port(port).build();
} }
/**
* Session client is used in login-related functionality
*/
@Provides
@Singleton
protected SessionClient bindSessionClient(CloudStackClient client) {
return client.getSessionClient();
}
@Singleton @Singleton
static class CredentialTypeFromPropertyOrDefault implements javax.inject.Provider<CredentialType> { static class CredentialTypeFromPropertyOrDefault implements javax.inject.Provider<CredentialType> {
/** /**

View File

@ -23,6 +23,7 @@ import java.lang.reflect.Method;
import java.lang.reflect.Proxy; import java.lang.reflect.Proxy;
import java.util.Map; import java.util.Map;
import com.google.common.collect.ImmutableMap;
import com.google.inject.Binder; import com.google.inject.Binder;
import com.google.inject.Provider; import com.google.inject.Provider;
@ -32,10 +33,57 @@ import com.google.inject.Provider;
*/ */
public class BinderUtils { public class BinderUtils {
public static <K, V> void bindClient(Binder binder, Class<K> syncClientType, /**
Class<V> asyncClientType, Map<Class<?>, Class<?>> delegates) { * adds an explicit binding for a rest client, after which you can inject either the sync or
Provider<K> asyncProvider = new ClientProvider<K, V>(syncClientType, asyncClientType, * async client class.
delegates); *
* <h3>note</h3> This client cannot have @Delegate methods, so if you have them, use the
* {@link #bindClientAndAsyncClient(Binder, Class, Class, Map) overloaded method}.
*
* @param <S>
* sync client type
* @param <A>
* async client type (all methods have same args as client, but return
* listenablefuture)
* @param binder
* guice binder
* @param syncClientType
* interface for the sync client
* @param asyncClientType
* interface for the async client
*/
public static <S, A> void bindClientAndAsyncClient(Binder binder, Class<S> syncClientType, Class<A> asyncClientType) {
bindClientAndAsyncClient(binder, syncClientType, asyncClientType, ImmutableMap.<Class<?>, Class<?>> of());
}
/**
* adds an explicit binding for a rest client, after which you can inject either the sync or
* async client class.
*
* @param <S>
* sync client type
* @param <A>
* async client type (all methods have same args as client, but return
* listenablefuture)
* @param binder
* guice binder
* @param syncClientType
* interface for the sync client (ex. LoginClient)
* @param asyncClientType
* interface for the async client (ex. LoginAsyncClient)
* @param delegates
* presuming your clients are annotated with @Delegate, contains the sync to async
* classes relating to these methods
*/
public static <S, A> void bindClientAndAsyncClient(Binder binder, Class<S> syncClientType, Class<A> asyncClientType,
Map<Class<?>, Class<?>> delegates) {
bindClient(binder, syncClientType, asyncClientType, delegates);
bindAsyncClient(binder, asyncClientType);
}
public static <K, V> void bindClient(Binder binder, Class<K> syncClientType, Class<V> asyncClientType,
Map<Class<?>, Class<?>> delegates) {
Provider<K> asyncProvider = new ClientProvider<K, V>(syncClientType, asyncClientType, delegates);
binder.requestInjection(asyncProvider); binder.requestInjection(asyncProvider);
binder.bind(syncClientType).toProvider(asyncProvider); binder.bind(syncClientType).toProvider(asyncProvider);
} }
@ -48,8 +96,7 @@ public class BinderUtils {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public static <T> T newNullProxy(Class<T> clazz) { public static <T> T newNullProxy(Class<T> clazz) {
return (T) Proxy.newProxyInstance(clazz.getClassLoader(), new Class<?>[] { clazz }, return (T) Proxy.newProxyInstance(clazz.getClassLoader(), new Class<?>[] { clazz }, new InvocationHandler() {
new InvocationHandler() {
@Override @Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {