diff --git a/apis/cloudloadbalancers/src/main/java/org/jclouds/cloudloadbalancers/config/CloudLoadBalancersRestClientModule.java b/apis/cloudloadbalancers/src/main/java/org/jclouds/cloudloadbalancers/config/CloudLoadBalancersRestClientModule.java index f7bc1f307c..5ccaf9af5e 100644 --- a/apis/cloudloadbalancers/src/main/java/org/jclouds/cloudloadbalancers/config/CloudLoadBalancersRestClientModule.java +++ b/apis/cloudloadbalancers/src/main/java/org/jclouds/cloudloadbalancers/config/CloudLoadBalancersRestClientModule.java @@ -48,10 +48,10 @@ import org.jclouds.openstack.keystone.v1_1.config.AuthenticationServiceModule; import org.jclouds.rest.ConfiguresRestClient; import org.jclouds.rest.annotations.ApiVersion; import org.jclouds.rest.config.RestClientModule; +import org.jclouds.util.Suppliers2; import com.google.common.base.Function; import com.google.common.base.Supplier; -import com.google.common.base.Suppliers; import com.google.common.collect.ImmutableMap; import com.google.inject.AbstractModule; import com.google.inject.Provides; @@ -94,7 +94,7 @@ public class CloudLoadBalancersRestClientModule extends @Singleton @Named(RackspaceConstants.PROPERTY_ACCOUNT_ID) protected Supplier accountID(RegionIdToURISupplier.Factory factory, @ApiVersion String apiVersion) { - return Suppliers.compose(new Function() { + return Suppliers2.compose(new Function() { @Override public String apply(URI arg0) { diff --git a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/compute/config/CloudStackComputeServiceContextModule.java b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/compute/config/CloudStackComputeServiceContextModule.java index abcc733f0a..f36b771d08 100644 --- a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/compute/config/CloudStackComputeServiceContextModule.java +++ b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/compute/config/CloudStackComputeServiceContextModule.java @@ -18,7 +18,6 @@ */ package org.jclouds.cloudstack.compute.config; -import static com.google.common.base.Preconditions.checkNotNull; import static org.jclouds.Constants.PROPERTY_SESSION_INTERVAL; import java.util.Map; @@ -26,7 +25,6 @@ import java.util.Set; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicReference; -import javax.inject.Inject; import javax.inject.Named; import javax.inject.Singleton; @@ -56,7 +54,6 @@ import org.jclouds.cloudstack.functions.GetFirewallRulesByVirtualMachine; import org.jclouds.cloudstack.functions.GetIPForwardingRulesByVirtualMachine; import org.jclouds.cloudstack.functions.StaticNATVirtualMachineInNetwork; import org.jclouds.cloudstack.functions.ZoneIdToZone; -import org.jclouds.cloudstack.options.ListFirewallRulesOptions; import org.jclouds.cloudstack.predicates.JobComplete; import org.jclouds.cloudstack.suppliers.GetCurrentUser; import org.jclouds.cloudstack.suppliers.NetworksForCurrentUser; @@ -70,17 +67,16 @@ import org.jclouds.compute.options.TemplateOptions; import org.jclouds.domain.Location; import org.jclouds.predicates.RetryablePredicate; import org.jclouds.rest.AuthorizationException; -import org.jclouds.rest.ResourceNotFoundException; import org.jclouds.rest.suppliers.MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier; import com.google.common.base.Function; +import com.google.common.base.Objects; import com.google.common.base.Predicate; import com.google.common.base.Supplier; import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheLoader; import com.google.common.cache.LoadingCache; import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableSet; import com.google.common.collect.Maps; import com.google.inject.Provides; import com.google.inject.TypeLiteral; @@ -127,14 +123,18 @@ public class CloudStackComputeServiceContextModule extends @Memoized public Supplier> listOSCategories(AtomicReference authException, @Named(PROPERTY_SESSION_INTERVAL) long seconds, final CloudStackClient client) { - return new MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier>(authException, - seconds, new Supplier>() { + return MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier.create(authException, + new Supplier>() { @Override public Map get() { GuestOSClient guestOSClient = client.getGuestOSClient(); return guestOSClient.listOSCategories(); } - }); + @Override + public String toString() { + return Objects.toStringHelper(client.getGuestOSClient()).add("method", "listOSCategories").toString(); + } + }, seconds, TimeUnit.SECONDS); } @Provides @@ -142,8 +142,8 @@ public class CloudStackComputeServiceContextModule extends @Memoized public Supplier> listOSTypes(AtomicReference authException, @Named(PROPERTY_SESSION_INTERVAL) long seconds, final CloudStackClient client) { - return new MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier>(authException, - seconds, new Supplier>() { + return MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier.create(authException, + new Supplier>() { @Override public Map get() { GuestOSClient guestOSClient = client.getGuestOSClient(); @@ -155,7 +155,11 @@ public class CloudStackComputeServiceContextModule extends } }); } - }); + @Override + public String toString() { + return Objects.toStringHelper(client.getGuestOSClient()).add("method", "listOSTypes").toString(); + } + }, seconds, TimeUnit.SECONDS); } @Provides @@ -163,8 +167,8 @@ public class CloudStackComputeServiceContextModule extends @Memoized public Supplier> listNetworks(AtomicReference authException, @Named(PROPERTY_SESSION_INTERVAL) long seconds, final NetworksForCurrentUser networksForCurrentUser) { - return new MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier>(authException, - seconds, networksForCurrentUser); + return MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier.create(authException, networksForCurrentUser, + seconds, TimeUnit.SECONDS); } @Provides @@ -172,8 +176,8 @@ public class CloudStackComputeServiceContextModule extends @Memoized public Supplier getCurrentUser(AtomicReference authException, @Named(PROPERTY_SESSION_INTERVAL) long seconds, final GetCurrentUser getCurrentUser) { - return new MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier(authException, seconds, - getCurrentUser); + return MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier.create(authException, getCurrentUser, + seconds, TimeUnit.SECONDS); } @Provides diff --git a/apis/deltacloud/src/main/java/org/jclouds/deltacloud/config/DeltacloudRestClientModule.java b/apis/deltacloud/src/main/java/org/jclouds/deltacloud/config/DeltacloudRestClientModule.java index 73974a067d..0bff28c1e1 100644 --- a/apis/deltacloud/src/main/java/org/jclouds/deltacloud/config/DeltacloudRestClientModule.java +++ b/apis/deltacloud/src/main/java/org/jclouds/deltacloud/config/DeltacloudRestClientModule.java @@ -23,6 +23,7 @@ import static org.jclouds.Constants.PROPERTY_SESSION_INTERVAL; import java.net.URI; import java.util.NoSuchElementException; import java.util.Set; +import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicReference; import javax.inject.Named; @@ -47,11 +48,12 @@ import org.jclouds.rest.AuthorizationException; import org.jclouds.rest.ConfiguresRestClient; import org.jclouds.rest.config.RestClientModule; import org.jclouds.rest.suppliers.MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier; +import org.jclouds.util.Suppliers2; import com.google.common.base.Function; +import com.google.common.base.Objects; import com.google.common.base.Predicate; import com.google.common.base.Supplier; -import com.google.common.base.Suppliers; import com.google.common.collect.Iterables; import com.google.inject.Provides; @@ -81,13 +83,17 @@ public class DeltacloudRestClientModule extends RestClientModule> provideCollections( @Named(PROPERTY_SESSION_INTERVAL) long seconds, final DeltacloudClient client) { - return new MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier>( - authException, seconds, new Supplier>() { + return MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier.create( + authException, new Supplier>() { @Override public Set get() { return client.getCollections(); } - }); + @Override + public String toString() { + return Objects.toStringHelper(client).add("method", "getCollections").toString(); + } + }, seconds, TimeUnit.SECONDS); } /** @@ -97,7 +103,7 @@ public class DeltacloudRestClientModule extends RestClientModule provideImageCollection(Supplier> collectionSupplier) { - return Suppliers.compose(new FindCollectionWithRelAndReturnHref("images"), collectionSupplier); + return Suppliers2.compose(new FindCollectionWithRelAndReturnHref("images"), collectionSupplier); } public static class FindCollectionWithRelAndReturnHref implements Function, URI> { @@ -128,24 +134,24 @@ public class DeltacloudRestClientModule extends RestClientModule provideHardwareProfileCollection(Supplier> collectionSupplier) { - return Suppliers.compose(new FindCollectionWithRelAndReturnHref("hardware_profiles"), collectionSupplier); + return Suppliers2.compose(new FindCollectionWithRelAndReturnHref("hardware_profiles"), collectionSupplier); } @Provides @Instances protected Supplier provideInstanceCollection(Supplier> collectionSupplier) { - return Suppliers.compose(new FindCollectionWithRelAndReturnHref("instances"), collectionSupplier); + return Suppliers2.compose(new FindCollectionWithRelAndReturnHref("instances"), collectionSupplier); } @Provides @Realms protected Supplier provideRealmCollection(Supplier> collectionSupplier) { - return Suppliers.compose(new FindCollectionWithRelAndReturnHref("realms"), collectionSupplier); + return Suppliers2.compose(new FindCollectionWithRelAndReturnHref("realms"), collectionSupplier); } @Provides @InstanceStates protected Supplier provideInstanceStateCollection(Supplier> collectionSupplier) { - return Suppliers.compose(new FindCollectionWithRelAndReturnHref("instance_states"), collectionSupplier); + return Suppliers2.compose(new FindCollectionWithRelAndReturnHref("instance_states"), collectionSupplier); } } diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/KeystoneApiMetadata.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/KeystoneApiMetadata.java index c15f193b99..03e4b07a19 100644 --- a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/KeystoneApiMetadata.java +++ b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/KeystoneApiMetadata.java @@ -26,8 +26,11 @@ import java.util.Properties; import org.jclouds.apis.ApiMetadata; import org.jclouds.openstack.keystone.v2_0.config.CredentialTypes; +import org.jclouds.openstack.keystone.v2_0.config.KeystoneAuthenticationModule; +import org.jclouds.openstack.keystone.v2_0.config.KeystoneParserModule; import org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties; import org.jclouds.openstack.keystone.v2_0.config.KeystoneRestClientModule; +import org.jclouds.openstack.keystone.v2_0.config.KeystoneRestClientModule.KeystoneAdminURLModule; import org.jclouds.openstack.v2_0.ServiceType; import org.jclouds.rest.RestContext; import org.jclouds.rest.internal.BaseRestApiMetadata; @@ -85,7 +88,11 @@ public class KeystoneApiMetadata extends BaseRestApiMetadata { .version("2.0") .defaultEndpoint("http://localhost:5000") .defaultProperties(KeystoneApiMetadata.defaultProperties()) - .defaultModules(ImmutableSet.>of(KeystoneRestClientModule.class)); + .defaultModules(ImmutableSet.>builder() + .add(KeystoneAuthenticationModule.class) + .add(KeystoneAdminURLModule.class) + .add(KeystoneParserModule.class) + .add(KeystoneRestClientModule.class).build()); } @Override diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/config/KeystoneAuthenticationModule.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/config/KeystoneAuthenticationModule.java index c556487086..e89b9d8d2f 100644 --- a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/config/KeystoneAuthenticationModule.java +++ b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/config/KeystoneAuthenticationModule.java @@ -35,12 +35,18 @@ import org.jclouds.domain.Credentials; import org.jclouds.http.HttpRetryHandler; import org.jclouds.http.annotation.ClientError; import org.jclouds.location.Provider; +import org.jclouds.location.suppliers.ImplicitLocationSupplier; +import org.jclouds.location.suppliers.LocationsSupplier; import org.jclouds.location.suppliers.RegionIdToURISupplier; import org.jclouds.location.suppliers.RegionIdsSupplier; import org.jclouds.location.suppliers.ZoneIdToURISupplier; import org.jclouds.location.suppliers.ZoneIdsSupplier; +import org.jclouds.location.suppliers.all.RegionToProvider; +import org.jclouds.location.suppliers.all.ZoneToProvider; import org.jclouds.location.suppliers.derived.RegionIdsFromRegionIdToURIKeySet; import org.jclouds.location.suppliers.derived.ZoneIdsFromZoneIdToURIKeySet; +import org.jclouds.location.suppliers.implicit.FirstRegion; +import org.jclouds.location.suppliers.implicit.FirstZone; import org.jclouds.openstack.keystone.v2_0.AuthenticationAsyncClient; import org.jclouds.openstack.keystone.v2_0.AuthenticationClient; import org.jclouds.openstack.keystone.v2_0.domain.Access; @@ -62,8 +68,8 @@ import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet.Builder; import com.google.inject.AbstractModule; import com.google.inject.Injector; -import com.google.inject.Module; import com.google.inject.Provides; +import com.google.inject.Scopes; import com.google.inject.assistedinject.FactoryModuleBuilder; /** @@ -71,25 +77,6 @@ import com.google.inject.assistedinject.FactoryModuleBuilder; * @author Adrian Cole */ public class KeystoneAuthenticationModule extends AbstractModule { - private final Module locationModule; - - public KeystoneAuthenticationModule() { - this(new RegionModule()); - } - - protected KeystoneAuthenticationModule(Module locationModule) { - this.locationModule = locationModule; - } - - public static class KeystoneAuthenticationModuleForRegions extends KeystoneAuthenticationModule { - public KeystoneAuthenticationModuleForRegions() { - super(new RegionModule()); - } - } - - public static Module forRegions() { - return new KeystoneAuthenticationModuleForRegions(); - } public static class RegionModule extends AbstractModule { @Override @@ -100,6 +87,8 @@ public class KeystoneAuthenticationModule extends AbstractModule { RegionIdToAdminURIFromAccessForTypeAndVersion.class).build(RegionIdToAdminURISupplier.Factory.class)); // dynamically build the region list as opposed to from properties bind(RegionIdsSupplier.class).to(RegionIdsFromRegionIdToURIKeySet.class); + bind(ImplicitLocationSupplier.class).to(FirstRegion.class).in(Scopes.SINGLETON); + bind(LocationsSupplier.class).to(RegionToProvider.class).in(Scopes.SINGLETON); } // supply the region to id map from keystone, based on the servicetype and api version in @@ -132,6 +121,8 @@ public class KeystoneAuthenticationModule extends AbstractModule { ZoneIdToURIFromAccessForTypeAndVersion.class).build(ZoneIdToURISupplier.Factory.class)); // dynamically build the zone list as opposed to from properties bind(ZoneIdsSupplier.class).to(ZoneIdsFromZoneIdToURIKeySet.class); + bind(ImplicitLocationSupplier.class).to(FirstZone.class).in(Scopes.SINGLETON); + bind(LocationsSupplier.class).to(ZoneToProvider.class).in(Scopes.SINGLETON); } // supply the zone to id map from keystone, based on the servicetype and api version in @@ -146,21 +137,10 @@ public class KeystoneAuthenticationModule extends AbstractModule { } - public static class KeystoneAuthenticationModuleForZones extends KeystoneAuthenticationModule { - public KeystoneAuthenticationModuleForZones() { - super(new ZoneModule()); - } - } - - public static Module forZones() { - return new KeystoneAuthenticationModuleForZones(); - } - @Override protected void configure() { bind(HttpRetryHandler.class).annotatedWith(ClientError.class).to(RetryOnRenew.class); bindAuthenticationClient(); - install(locationModule); } protected void bindAuthenticationClient() { diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/config/KeystoneParserModule.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/config/KeystoneParserModule.java index 51e2927073..55b2508759 100644 --- a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/config/KeystoneParserModule.java +++ b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/config/KeystoneParserModule.java @@ -61,6 +61,7 @@ public class KeystoneParserModule extends AbstractModule { * Treats [A,B,C] and {"values"=[A,B,C], "someotherstuff"=...} as the same Set */ public static class SetTypeAdapterFactory implements TypeAdapterFactory { + @SuppressWarnings("unchecked") public TypeAdapter create(Gson gson, TypeToken typeToken) { Type type = typeToken.getType(); if (typeToken.getRawType() != Set.class || !(type instanceof ParameterizedType)) { @@ -69,7 +70,7 @@ public class KeystoneParserModule extends AbstractModule { Type elementType = ((ParameterizedType) type).getActualTypeArguments()[0]; TypeAdapter elementAdapter = gson.getAdapter(TypeToken.get(elementType)); - return (TypeAdapter) newSetAdapter(elementAdapter); + return TypeAdapter.class.cast(newSetAdapter(elementAdapter)); } private TypeAdapter> newSetAdapter(final TypeAdapter elementAdapter) { diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/config/KeystoneRestClientModule.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/config/KeystoneRestClientModule.java index 88cf19ee7b..62263f6cfb 100644 --- a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/config/KeystoneRestClientModule.java +++ b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/config/KeystoneRestClientModule.java @@ -67,15 +67,13 @@ public class KeystoneRestClientModule { public static final Map, Class> DELEGATE_MAP = ImmutableMap., Class> builder() - .put(ServiceClient.class, ServiceAsyncClient.class) - .put(TokenClient.class, TokenAsyncClient.class) - .put(UserClient.class, UserAsyncClient.class) - .put(TenantClient.class, TenantAsyncClient.class).build(); + .put(ServiceClient.class, ServiceAsyncClient.class).put(TokenClient.class, TokenAsyncClient.class) + .put(UserClient.class, UserAsyncClient.class).put(TenantClient.class, TenantAsyncClient.class).build(); @SuppressWarnings("unchecked") public KeystoneRestClientModule() { - super((TypeToken) TypeToken.of(KeystoneClient.class), (TypeToken) TypeToken.of(KeystoneAsyncClient.class), - DELEGATE_MAP); + super(TypeToken.class.cast(TypeToken.of(KeystoneClient.class)), TypeToken.class.cast(TypeToken + .of(KeystoneAsyncClient.class)), DELEGATE_MAP); } protected KeystoneRestClientModule(TypeToken syncClientType, TypeToken asyncClientType, @@ -83,23 +81,11 @@ public class KeystoneRestClientModule>of(KeystoneAuthenticationModuleForZones.class, NovaRestClientModule.class, NovaComputeServiceContextModule.class)); + .defaultModules(ImmutableSet.>builder() + .add(KeystoneAuthenticationModule.class) + .add(ZoneModule.class) + .add(NovaRestClientModule.class) + .add(NovaComputeServiceContextModule.class).build()); } @Override diff --git a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/NovaComputeServiceAdapter.java b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/NovaComputeServiceAdapter.java index eb0830c726..21844e1ac1 100644 --- a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/NovaComputeServiceAdapter.java +++ b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/NovaComputeServiceAdapter.java @@ -19,6 +19,7 @@ package org.jclouds.openstack.nova.v2_0.compute; import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.base.Preconditions.checkState; import static com.google.common.collect.Iterables.filter; import static com.google.common.collect.Iterables.transform; import static org.jclouds.compute.util.ComputeServiceUtils.metadataAndTagsAsCommaDelimitedValue; @@ -155,7 +156,9 @@ public class NovaComputeServiceAdapter implements @Override public Iterable listImages() { Builder builder = ImmutableSet.builder(); - for (final String zoneId : zoneIds.get()) { + Set zones = zoneIds.get(); + checkState(zones.size() > 0, "no zones found in supplier %s", zoneIds); + for (final String zoneId : zones) { Set images = novaClient.getImageClientForZone(zoneId).listImagesInDetail(); if (images.size() == 0) { logger.debug("no images found in zone %s", zoneId); diff --git a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/config/NovaComputeServiceContextModule.java b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/config/NovaComputeServiceContextModule.java index 6e191420b8..7217db047b 100644 --- a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/config/NovaComputeServiceContextModule.java +++ b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/config/NovaComputeServiceContextModule.java @@ -72,13 +72,13 @@ import org.jclouds.openstack.nova.v2_0.domain.zonescoped.ZoneSecurityGroupNameAn import org.jclouds.openstack.nova.v2_0.predicates.FindSecurityGroupWithNameAndReturnTrue; import org.jclouds.predicates.PredicateWithResult; import org.jclouds.predicates.RetryablePredicate; +import org.jclouds.util.Suppliers2; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Function; import com.google.common.base.Optional; import com.google.common.base.Predicate; import com.google.common.base.Supplier; -import com.google.common.base.Suppliers; import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheLoader; import com.google.common.cache.LoadingCache; @@ -200,7 +200,7 @@ public class NovaComputeServiceContextModule extends @Singleton protected Supplier> createLocationIndexedById( @Memoized Supplier> locations) { - return Suppliers.compose(new Function, Map>() { + return Suppliers2.compose(new Function, Map>() { @SuppressWarnings("unchecked") @Override diff --git a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/functions/ImageInZoneToImage.java b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/functions/ImageInZoneToImage.java index 76eb8ec85f..3e3423fda2 100644 --- a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/functions/ImageInZoneToImage.java +++ b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/functions/ImageInZoneToImage.java @@ -33,6 +33,7 @@ import org.jclouds.openstack.nova.v2_0.domain.Image.Status; import org.jclouds.openstack.nova.v2_0.domain.zonescoped.ImageInZone; import com.google.common.base.Function; +import com.google.common.base.Objects; import com.google.common.base.Supplier; /** @@ -63,4 +64,9 @@ public class ImageInZoneToImage implements Function { .userMetadata(image.getMetadata()).operatingSystem(imageToOs.apply(image)).description(image.getName()) .location(location).status(toPortableImageStatus.get(image.getStatus())).build(); } + + @Override + public String toString() { + return Objects.toStringHelper(this).toString(); + } } diff --git a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/config/NovaRestClientModule.java b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/config/NovaRestClientModule.java index 35c965838c..52e84ea5cd 100644 --- a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/config/NovaRestClientModule.java +++ b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/config/NovaRestClientModule.java @@ -29,10 +29,6 @@ import org.jclouds.http.HttpErrorHandler; import org.jclouds.http.annotation.ClientError; import org.jclouds.http.annotation.Redirection; import org.jclouds.http.annotation.ServerError; -import org.jclouds.location.suppliers.ImplicitLocationSupplier; -import org.jclouds.location.suppliers.LocationsSupplier; -import org.jclouds.location.suppliers.all.ZoneToProvider; -import org.jclouds.location.suppliers.implicit.FirstZone; import org.jclouds.openstack.nova.v2_0.NovaAsyncClient; import org.jclouds.openstack.nova.v2_0.NovaClient; import org.jclouds.openstack.nova.v2_0.domain.Extension; @@ -83,7 +79,6 @@ import com.google.common.cache.CacheLoader; import com.google.common.cache.LoadingCache; import com.google.common.collect.ImmutableMap; import com.google.inject.Provides; -import com.google.inject.Scopes; /** * Configures the Nova connection. @@ -124,13 +119,6 @@ public class NovaRestClientModule extends RestClientModule> provideExtensionsByZone(final Provider novaClient) { diff --git a/apis/swift/src/main/java/org/jclouds/openstack/swift/config/SwiftRestClientModule.java b/apis/swift/src/main/java/org/jclouds/openstack/swift/config/SwiftRestClientModule.java index 983b9d85f0..830aafb650 100644 --- a/apis/swift/src/main/java/org/jclouds/openstack/swift/config/SwiftRestClientModule.java +++ b/apis/swift/src/main/java/org/jclouds/openstack/swift/config/SwiftRestClientModule.java @@ -34,7 +34,7 @@ import org.jclouds.json.config.GsonModule.Iso8601DateAdapter; import org.jclouds.location.suppliers.RegionIdToURISupplier; import org.jclouds.openstack.config.OpenStackAuthenticationModule; import org.jclouds.openstack.functions.URIFromAuthenticationResponseForService; -import org.jclouds.openstack.keystone.v2_0.config.KeystoneAuthenticationModule.KeystoneAuthenticationModuleForRegions; +import org.jclouds.openstack.keystone.v2_0.config.KeystoneAuthenticationModule; import org.jclouds.openstack.reference.AuthHeaders; import org.jclouds.openstack.services.ServiceType; import org.jclouds.openstack.swift.CommonSwiftAsyncClient; @@ -62,8 +62,8 @@ public class SwiftRestClientModule, Class> of()); + this(TypeToken.class.cast(TypeToken.of(SwiftClient.class)), TypeToken.class.cast(TypeToken + .of(SwiftAsyncClient.class)), ImmutableMap., Class> of()); } protected SwiftRestClientModule(TypeToken syncClientType, TypeToken asyncClientType, @@ -80,7 +80,7 @@ public class SwiftRestClientModule networkConfig(@Network Supplier network, final FenceMode defaultFenceMode) { - return Suppliers.compose(new Function() { + return Suppliers2.compose(new Function() { @Override public NetworkConfig apply(ReferenceType input) { diff --git a/apis/vcloud/src/main/java/org/jclouds/vcloud/config/DefaultOrgForUser.java b/apis/vcloud/src/main/java/org/jclouds/vcloud/config/DefaultOrgForUser.java index 143e9d601d..f0ce1b671d 100644 --- a/apis/vcloud/src/main/java/org/jclouds/vcloud/config/DefaultOrgForUser.java +++ b/apis/vcloud/src/main/java/org/jclouds/vcloud/config/DefaultOrgForUser.java @@ -26,6 +26,7 @@ import javax.inject.Inject; import javax.inject.Singleton; import org.jclouds.config.ValueOfConfigurationKeyOrNull; +import org.jclouds.util.Suppliers2; import org.jclouds.vcloud.domain.ReferenceType; import org.jclouds.vcloud.domain.VCloudSession; import org.jclouds.vcloud.endpoints.Org; @@ -34,7 +35,6 @@ import org.jclouds.vcloud.suppliers.OnlyReferenceTypeFirstWithNameMatchingConfig import com.google.common.base.Function; import com.google.common.base.Predicate; import com.google.common.base.Supplier; -import com.google.common.base.Suppliers; /** * @@ -57,7 +57,7 @@ public class DefaultOrgForUser implements Function apply(final String user) { - return Suppliers.compose(new Function() { + return Suppliers2.compose(new Function() { @Override public ReferenceType apply(VCloudSession session) { diff --git a/apis/vcloud/src/main/java/org/jclouds/vcloud/config/DefaultVCloudReferencesModule.java b/apis/vcloud/src/main/java/org/jclouds/vcloud/config/DefaultVCloudReferencesModule.java index fe8c4088a9..099d4e4b33 100644 --- a/apis/vcloud/src/main/java/org/jclouds/vcloud/config/DefaultVCloudReferencesModule.java +++ b/apis/vcloud/src/main/java/org/jclouds/vcloud/config/DefaultVCloudReferencesModule.java @@ -27,6 +27,7 @@ import javax.inject.Singleton; import org.jclouds.logging.Logger; import org.jclouds.rest.annotations.Identity; +import org.jclouds.util.Suppliers2; import org.jclouds.vcloud.domain.Catalog; import org.jclouds.vcloud.domain.ReferenceType; @@ -72,7 +73,7 @@ public class DefaultVCloudReferencesModule extends AbstractModule { @Singleton protected Supplier provideDefaultTasksList(DefaultTasksListForOrg defaultTasksListURIForOrg, @org.jclouds.vcloud.endpoints.Org Supplier defaultOrg) { - return Suppliers.compose(defaultTasksListURIForOrg, defaultOrg); + return Suppliers2.compose(defaultTasksListURIForOrg, defaultOrg); } @Provides @@ -80,7 +81,7 @@ public class DefaultVCloudReferencesModule extends AbstractModule { @Singleton protected Supplier provideDefaultCatalog(DefaultCatalogForOrg defaultCatalogURIForOrg, @org.jclouds.vcloud.endpoints.Org Supplier defaultOrg) { - return Suppliers.compose(defaultCatalogURIForOrg, defaultOrg); + return Suppliers2.compose(defaultCatalogURIForOrg, defaultOrg); } @Provides @@ -146,7 +147,7 @@ public class DefaultVCloudReferencesModule extends AbstractModule { @Singleton protected Supplier provideDefaultVDC(DefaultVDCForOrg defaultVDCURIForOrg, @org.jclouds.vcloud.endpoints.Org Supplier defaultOrg) { - return Suppliers.compose(defaultVDCURIForOrg, defaultOrg); + return Suppliers2.compose(defaultVDCURIForOrg, defaultOrg); } @Provides @@ -161,7 +162,7 @@ public class DefaultVCloudReferencesModule extends AbstractModule { @Singleton protected Supplier provideDefaultNetwork(DefaultNetworkForVDC defaultNetworkURIForVDC, @org.jclouds.vcloud.endpoints.VDC Supplier defaultVDC) { - return Suppliers.compose(defaultNetworkURIForVDC, defaultVDC); + return Suppliers2.compose(defaultNetworkURIForVDC, defaultVDC); } @Provides diff --git a/apis/vcloud/src/main/java/org/jclouds/vcloud/config/VCloudRestClientModule.java b/apis/vcloud/src/main/java/org/jclouds/vcloud/config/VCloudRestClientModule.java index c84b1a37d6..1040931bfe 100644 --- a/apis/vcloud/src/main/java/org/jclouds/vcloud/config/VCloudRestClientModule.java +++ b/apis/vcloud/src/main/java/org/jclouds/vcloud/config/VCloudRestClientModule.java @@ -21,7 +21,6 @@ package org.jclouds.vcloud.config; import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkState; import static com.google.common.base.Predicates.notNull; -import static com.google.common.base.Suppliers.compose; import static com.google.common.collect.Iterables.concat; import static com.google.common.collect.Iterables.filter; import static com.google.common.collect.Iterables.getLast; @@ -35,8 +34,9 @@ import static org.jclouds.vcloud.reference.VCloudConstants.PROPERTY_VCLOUD_TIMEO import java.net.URI; import java.util.Map; -import java.util.SortedMap; import java.util.Map.Entry; +import java.util.SortedMap; +import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicReference; import javax.inject.Inject; @@ -58,6 +58,7 @@ import org.jclouds.rest.ConfiguresRestClient; import org.jclouds.rest.annotations.ApiVersion; import org.jclouds.rest.config.RestClientModule; import org.jclouds.rest.suppliers.MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier; +import org.jclouds.util.Suppliers2; import org.jclouds.vcloud.VCloudAsyncClient; import org.jclouds.vcloud.VCloudClient; import org.jclouds.vcloud.VCloudToken; @@ -110,15 +111,15 @@ import org.jclouds.vcloud.predicates.TaskSuccess; import org.jclouds.vcloud.xml.ovf.VCloudResourceAllocationSettingDataHandler; import com.google.common.base.Function; +import com.google.common.base.Objects; import com.google.common.base.Predicate; import com.google.common.base.Supplier; -import com.google.common.base.Suppliers; import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheLoader; import com.google.common.cache.LoadingCache; import com.google.common.collect.ImmutableMap; -import com.google.common.collect.Lists; import com.google.common.collect.ImmutableMap.Builder; +import com.google.common.collect.Lists; import com.google.inject.Injector; import com.google.inject.Provides; import com.google.inject.Scopes; @@ -151,15 +152,19 @@ public class VCloudRestClientModule extends RestClientModule provideVCloudTokenCache(@Named(PROPERTY_SESSION_INTERVAL) long seconds, AtomicReference authException, final VCloudLoginClient login) { - return new MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier(authException, seconds, + return MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier.create(authException, new Supplier() { @Override public VCloudSession get() { return login.login(); } - - }); + + @Override + public String toString() { + return Objects.toStringHelper(login).add("method", "login").toString(); + } + }, seconds, TimeUnit.SECONDS); } @Override @@ -219,7 +224,7 @@ public class VCloudRestClientModule extends RestClientModule> provideVDCtoORG(Supplier> orgNameToOrgSuppier) { - return compose(new Function, Map>() { + return Suppliers2.compose(new Function, Map>() { @Override public Map apply(Map arg0) { @@ -239,15 +244,15 @@ public class VCloudRestClientModule extends RestClientModule> provideOrgMapCache(@Named(PROPERTY_SESSION_INTERVAL) long seconds, AtomicReference authException, OrgMapSupplier supplier) { - return new MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier>(authException, seconds, - supplier); + return MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier.create(authException, supplier, seconds, + TimeUnit.SECONDS); } @Provides @Singleton @OrgList protected Supplier provideOrgListURI(Supplier sessionSupplier) { - return Suppliers.compose(new Function() { + return Suppliers2.compose(new Function() { @Override public URI apply(VCloudSession arg0) { @@ -318,7 +323,7 @@ public class VCloudRestClientModule extends RestClientModule provideVCloudToken(Supplier cache) { - return Suppliers.compose(new Function() { + return Suppliers2.compose(new Function() { @Override public String apply(VCloudSession input) { @@ -332,8 +337,8 @@ public class VCloudRestClientModule extends RestClientModule> provideVDCtoORG(@Named(PROPERTY_SESSION_INTERVAL) long seconds, AtomicReference authException, OrgNameToOrgSupplier supplier) { - return new MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier>( - authException, seconds, supplier); + return MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier.create(authException, supplier, seconds, + TimeUnit.SECONDS); } @Provides @@ -341,8 +346,8 @@ public class VCloudRestClientModule extends RestClientModule> provideURIToVDC( @Named(PROPERTY_SESSION_INTERVAL) long seconds, AtomicReference authException, URItoVDC supplier) { - return new MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier>( - authException, seconds, supplier); + return MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier.create(authException, supplier, seconds, + TimeUnit.SECONDS); } @Singleton @@ -411,7 +416,6 @@ public class VCloudRestClientModule extends RestClientModule> { private final Supplier sessionSupplier; - @SuppressWarnings("unused") @Inject OrgNameToOrgSupplier(Supplier sessionSupplier) { this.sessionSupplier = sessionSupplier; @@ -428,7 +432,7 @@ public class VCloudRestClientModule extends RestClientModule provideOrg(final Supplier> orgSupplier, @org.jclouds.vcloud.endpoints.Org Supplier defaultOrg) { - return Suppliers.compose(new Function() { + return Suppliers2.compose(new Function() { @Override public Org apply(ReferenceType input) { @@ -450,8 +454,8 @@ public class VCloudRestClientModule extends RestClientModule>> provideOrgCatalogItemMapSupplierCache( @Named(PROPERTY_SESSION_INTERVAL) long seconds, AtomicReference authException, OrgCatalogSupplier supplier) { - return new MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier>>( - authException, seconds, supplier); + return MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier.create(authException, supplier, seconds, + TimeUnit.SECONDS); } @Provides @@ -459,8 +463,8 @@ public class VCloudRestClientModule extends RestClientModule>> provideOrgVDCSupplierCache( @Named(PROPERTY_SESSION_INTERVAL) long seconds, AtomicReference authException, OrgVDCSupplier supplier) { - return new MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier>>( - authException, seconds, supplier); + return MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier.create(authException, supplier, seconds, + TimeUnit.SECONDS); } @Singleton @@ -533,8 +537,8 @@ public class VCloudRestClientModule extends RestClientModule>>> provideOrgCatalogItemSupplierCache( @Named(PROPERTY_SESSION_INTERVAL) long seconds, AtomicReference authException, OrgCatalogItemSupplier supplier) { - return new MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier>>>( - authException, seconds, supplier); + return MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier.create(authException, supplier, seconds, + TimeUnit.SECONDS); } @Provides diff --git a/common/trmk/src/main/java/org/jclouds/trmk/vcloud_0_8/config/DefaultOrgForUser.java b/common/trmk/src/main/java/org/jclouds/trmk/vcloud_0_8/config/DefaultOrgForUser.java index 448489b3ab..eeb50c9c63 100644 --- a/common/trmk/src/main/java/org/jclouds/trmk/vcloud_0_8/config/DefaultOrgForUser.java +++ b/common/trmk/src/main/java/org/jclouds/trmk/vcloud_0_8/config/DefaultOrgForUser.java @@ -30,11 +30,11 @@ import org.jclouds.trmk.vcloud_0_8.domain.ReferenceType; import org.jclouds.trmk.vcloud_0_8.domain.VCloudSession; import org.jclouds.trmk.vcloud_0_8.endpoints.Org; import org.jclouds.trmk.vcloud_0_8.suppliers.OnlyReferenceTypeFirstWithNameMatchingConfigurationKeyOrDefault; +import org.jclouds.util.Suppliers2; import com.google.common.base.Function; import com.google.common.base.Predicate; import com.google.common.base.Supplier; -import com.google.common.base.Suppliers; /** * @@ -57,7 +57,7 @@ public class DefaultOrgForUser implements Function apply(final String user) { - return Suppliers.compose(new Function() { + return Suppliers2.compose(new Function() { @Override public ReferenceType apply(VCloudSession session) { diff --git a/common/trmk/src/main/java/org/jclouds/trmk/vcloud_0_8/config/DefaultVCloudReferencesModule.java b/common/trmk/src/main/java/org/jclouds/trmk/vcloud_0_8/config/DefaultVCloudReferencesModule.java index e37f5eb34a..c2b2efd86e 100644 --- a/common/trmk/src/main/java/org/jclouds/trmk/vcloud_0_8/config/DefaultVCloudReferencesModule.java +++ b/common/trmk/src/main/java/org/jclouds/trmk/vcloud_0_8/config/DefaultVCloudReferencesModule.java @@ -26,6 +26,7 @@ import javax.inject.Singleton; import org.jclouds.rest.annotations.Identity; import org.jclouds.trmk.vcloud_0_8.domain.Catalog; import org.jclouds.trmk.vcloud_0_8.domain.ReferenceType; +import org.jclouds.util.Suppliers2; import com.google.common.base.Function; import com.google.common.base.Predicate; @@ -69,7 +70,7 @@ public class DefaultVCloudReferencesModule extends AbstractModule { @Singleton protected Supplier provideDefaultTasksList(DefaultTasksListForOrg defaultTasksListURIForOrg, @org.jclouds.trmk.vcloud_0_8.endpoints.Org Supplier defaultOrg) { - return Suppliers.compose(defaultTasksListURIForOrg, defaultOrg); + return Suppliers2.compose(defaultTasksListURIForOrg, defaultOrg); } @Provides @@ -84,7 +85,7 @@ public class DefaultVCloudReferencesModule extends AbstractModule { @Singleton protected Supplier provideDefaultCatalog(DefaultCatalogForOrg defaultCatalogURIForOrg, @org.jclouds.trmk.vcloud_0_8.endpoints.Org Supplier defaultOrg) { - return Suppliers.compose(defaultCatalogURIForOrg, defaultOrg); + return Suppliers2.compose(defaultCatalogURIForOrg, defaultOrg); } @Provides @@ -121,7 +122,7 @@ public class DefaultVCloudReferencesModule extends AbstractModule { @Singleton protected Supplier provideDefaultVDC(DefaultVDCForOrg defaultVDCURIForOrg, @org.jclouds.trmk.vcloud_0_8.endpoints.Org Supplier defaultOrg) { - return Suppliers.compose(defaultVDCURIForOrg, defaultOrg); + return Suppliers2.compose(defaultVDCURIForOrg, defaultOrg); } @Provides @@ -136,7 +137,7 @@ public class DefaultVCloudReferencesModule extends AbstractModule { @Singleton protected Supplier provideDefaultNetwork(DefaultNetworkForVDC defaultNetworkURIForVDC, @org.jclouds.trmk.vcloud_0_8.endpoints.VDC Supplier defaultVDC) { - return Suppliers.compose(defaultNetworkURIForVDC, defaultVDC); + return Suppliers2.compose(defaultNetworkURIForVDC, defaultVDC); } @Provides diff --git a/common/trmk/src/main/java/org/jclouds/trmk/vcloud_0_8/config/TerremarkVCloudRestClientModule.java b/common/trmk/src/main/java/org/jclouds/trmk/vcloud_0_8/config/TerremarkVCloudRestClientModule.java index 848eab3d46..0a5e86b4d0 100644 --- a/common/trmk/src/main/java/org/jclouds/trmk/vcloud_0_8/config/TerremarkVCloudRestClientModule.java +++ b/common/trmk/src/main/java/org/jclouds/trmk/vcloud_0_8/config/TerremarkVCloudRestClientModule.java @@ -32,8 +32,9 @@ import static org.jclouds.trmk.vcloud_0_8.reference.VCloudConstants.PROPERTY_VCL import java.io.IOException; import java.net.URI; import java.util.Map; -import java.util.SortedMap; import java.util.Map.Entry; +import java.util.SortedMap; +import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicReference; import javax.inject.Inject; @@ -81,14 +82,15 @@ import org.jclouds.trmk.vcloud_0_8.location.DefaultVDC; import org.jclouds.trmk.vcloud_0_8.location.OrgAndVDCToLocationSupplier; import org.jclouds.trmk.vcloud_0_8.predicates.TaskSuccess; import org.jclouds.util.Strings2; +import org.jclouds.util.Suppliers2; import com.google.common.base.Function; +import com.google.common.base.Objects; import com.google.common.base.Predicate; import com.google.common.base.Supplier; -import com.google.common.base.Suppliers; import com.google.common.collect.ImmutableMap; -import com.google.common.collect.Maps; import com.google.common.collect.ImmutableMap.Builder; +import com.google.common.collect.Maps; import com.google.inject.Injector; import com.google.inject.Provides; import com.google.inject.Scopes; @@ -141,7 +143,7 @@ public class TerremarkVCloudRestClientModule extends RestClientModule> provideVDCtoORG( Supplier> orgNameToOrgSuppier) { - return Suppliers.compose( + return Suppliers2.compose( new Function, Map>() { @Override @@ -163,15 +165,15 @@ public class TerremarkVCloudRestClientModule extends RestClientModule> provideOrgMapCache( @Named(PROPERTY_SESSION_INTERVAL) long seconds, AtomicReference authException, OrgMapSupplier supplier) { - return new MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier>( - authException, seconds, supplier); + return MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier.create(authException, supplier, seconds, + TimeUnit.SECONDS); } @Provides @Singleton @OrgList protected Supplier provideOrgListURI(Supplier sessionSupplier) { - return Suppliers.compose(new Function() { + return Suppliers2.compose(new Function() { @Override public URI apply(VCloudSession arg0) { @@ -250,8 +252,8 @@ public class TerremarkVCloudRestClientModule extends RestClientModule> provideVDCtoORG(@Named(PROPERTY_SESSION_INTERVAL) long seconds, AtomicReference authException, OrgNameToOrgSupplier supplier) { - return new MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier>( - authException, seconds, supplier); + return MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier.create(authException, supplier, seconds, + TimeUnit.SECONDS); } @Provides @@ -259,8 +261,8 @@ public class TerremarkVCloudRestClientModule extends RestClientModule> provideURIToVDC( @Named(PROPERTY_SESSION_INTERVAL) long seconds, AtomicReference authException, URItoVDC supplier) { - return new MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier>( - authException, seconds, supplier); + return MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier.create(authException, supplier, seconds, + TimeUnit.SECONDS); } @Singleton @@ -333,7 +335,6 @@ public class TerremarkVCloudRestClientModule extends RestClientModule> { private final Supplier sessionSupplier; - @SuppressWarnings("unused") @Inject OrgNameToOrgSupplier(Supplier sessionSupplier) { this.sessionSupplier = sessionSupplier; @@ -351,7 +352,7 @@ public class TerremarkVCloudRestClientModule extends RestClientModule provideOrg( final Supplier> orgSupplier, @org.jclouds.trmk.vcloud_0_8.endpoints.Org Supplier defaultOrg) { - return Suppliers.compose(new Function() { + return Suppliers2.compose(new Function() { @Override public org.jclouds.trmk.vcloud_0_8.domain.Org apply(ReferenceType input) { @@ -373,8 +374,8 @@ public class TerremarkVCloudRestClientModule extends RestClientModule>> provideOrgCatalogItemMapSupplierCache( @Named(PROPERTY_SESSION_INTERVAL) long seconds, AtomicReference authException, OrgCatalogSupplier supplier) { - return new MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier>>( - authException, seconds, supplier); + return MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier.create(authException, supplier, seconds, + TimeUnit.SECONDS); } @Provides @@ -382,8 +383,8 @@ public class TerremarkVCloudRestClientModule extends RestClientModule>> provideOrgVDCSupplierCache( @Named(PROPERTY_SESSION_INTERVAL) long seconds, AtomicReference authException, OrgVDCSupplier supplier) { - return new MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier>>( - authException, seconds, supplier); + return MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier.create(authException, supplier, seconds, + TimeUnit.SECONDS); } @Singleton @@ -460,8 +461,8 @@ public class TerremarkVCloudRestClientModule extends RestClientModule>>> provideOrgCatalogItemSupplierCache( @Named(PROPERTY_SESSION_INTERVAL) long seconds, AtomicReference authException, OrgCatalogItemSupplier supplier) { - return new MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier>>>( - authException, seconds, supplier); + return MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier.create(authException, supplier, seconds, + TimeUnit.SECONDS); } /** @@ -479,15 +480,19 @@ public class TerremarkVCloudRestClientModule extends RestClientModule provideVCloudTokenCache(@Named(PROPERTY_SESSION_INTERVAL) long seconds, AtomicReference authException, final TerremarkVCloudLoginClient login) { - return new MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier(authException, seconds, + return MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier.create(authException, new Supplier() { @Override public VCloudSession get() { return login.login(); } - - }); + + @Override + public String toString() { + return Objects.toStringHelper(login).add("method", "login").toString(); + } + }, seconds, TimeUnit.SECONDS); } @Singleton @@ -541,8 +546,8 @@ public class TerremarkVCloudRestClientModule extends RestClientModule> provideOrgToKeysListCache( @Named(PROPERTY_SESSION_INTERVAL) long seconds, AtomicReference authException, OrgNameToKeysListSupplier supplier) { - return new MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier>( - authException, seconds, supplier); + return MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier.create(authException, supplier, seconds, + TimeUnit.SECONDS); } @Singleton diff --git a/compute/src/main/java/org/jclouds/compute/config/BaseComputeServiceContextModule.java b/compute/src/main/java/org/jclouds/compute/config/BaseComputeServiceContextModule.java index 3c95c02aab..fbe346d033 100644 --- a/compute/src/main/java/org/jclouds/compute/config/BaseComputeServiceContextModule.java +++ b/compute/src/main/java/org/jclouds/compute/config/BaseComputeServiceContextModule.java @@ -26,6 +26,7 @@ import static org.jclouds.compute.domain.OsFamily.UBUNTU; import java.util.Map; import java.util.Set; import java.util.concurrent.Callable; +import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicReference; import javax.inject.Named; @@ -61,11 +62,11 @@ import org.jclouds.rest.AuthorizationException; import org.jclouds.rest.suppliers.MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier; import org.jclouds.scriptbuilder.domain.Statement; import org.jclouds.ssh.SshClient; +import org.jclouds.util.Suppliers2; import com.google.common.base.Function; import com.google.common.base.Optional; import com.google.common.base.Supplier; -import com.google.common.base.Suppliers; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Maps; import com.google.inject.AbstractModule; @@ -209,7 +210,7 @@ public abstract class BaseComputeServiceContextModule extends AbstractModule { @Provides @Singleton protected Supplier> provideImageMap(@Memoized Supplier> images) { - return Suppliers.compose(new Function, Map>() { + return Suppliers2.compose(new Function, Map>() { @Override public Map apply(Set from) { @@ -244,13 +245,8 @@ public abstract class BaseComputeServiceContextModule extends AbstractModule { protected Supplier> supplyImageCache(AtomicReference authException, @Named(PROPERTY_SESSION_INTERVAL) long seconds, final Supplier> imageSupplier) { - return new MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier>(authException, - seconds, new Supplier>() { - @Override - public Set get() { - return imageSupplier.get(); - } - }); + return MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier.create(authException, imageSupplier, seconds, + TimeUnit.SECONDS); } /** @@ -264,7 +260,7 @@ public abstract class BaseComputeServiceContextModule extends AbstractModule { @Provides @Singleton protected Supplier> provideSizeMap(@Memoized Supplier> sizes) { - return Suppliers.compose(new Function, Map>() { + return Suppliers2.compose(new Function, Map>() { @Override public Map apply(Set from) { @@ -286,13 +282,8 @@ public abstract class BaseComputeServiceContextModule extends AbstractModule { @Memoized protected Supplier> supplySizeCache(AtomicReference authException, @Named(PROPERTY_SESSION_INTERVAL) long seconds, final Supplier> hardwareSupplier) { - return new MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier>(authException, - seconds, new Supplier>() { - @Override - public Set get() { - return hardwareSupplier.get(); - } - }); + return MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier.create(authException, hardwareSupplier, + seconds, TimeUnit.SECONDS); } @Provides diff --git a/compute/src/main/java/org/jclouds/compute/config/ComputeServiceAdapterContextModule.java b/compute/src/main/java/org/jclouds/compute/config/ComputeServiceAdapterContextModule.java index cdeb42d309..e088529a00 100644 --- a/compute/src/main/java/org/jclouds/compute/config/ComputeServiceAdapterContextModule.java +++ b/compute/src/main/java/org/jclouds/compute/config/ComputeServiceAdapterContextModule.java @@ -48,6 +48,7 @@ import org.jclouds.domain.LoginCredentials; import org.jclouds.location.suppliers.LocationsSupplier; import com.google.common.base.Function; +import com.google.common.base.Objects; import com.google.common.base.Supplier; import com.google.common.collect.ImmutableSet; import com.google.inject.AbstractModule; @@ -88,6 +89,11 @@ public class ComputeServiceAdapterContextModule extends BaseComputeS Iterable locations = filter(adapter.listLocations(), notNull()); return ImmutableSet. copyOf(transform(locations, transformer)); } + + @Override + public String toString() { + return Objects.toStringHelper(adapter).add("method", "listLocations").toString(); + } }; } } @@ -102,7 +108,12 @@ public class ComputeServiceAdapterContextModule extends BaseComputeS public Iterable get() { return adapter.listHardwareProfiles(); } - + + @Override + public String toString() { + return Objects.toStringHelper(adapter).add("method", "listHardwareProfiles").toString(); + } + }, transformer); } @@ -116,7 +127,12 @@ public class ComputeServiceAdapterContextModule extends BaseComputeS public Iterable get() { return filter(adapter.listImages(), notNull()); } - + + @Override + public String toString() { + return Objects.toStringHelper(adapter).add("method", "listImages").toString(); + } + }, compose(addDefaultCredentialsToImage, transformer)); } @@ -139,7 +155,7 @@ public class ComputeServiceAdapterContextModule extends BaseComputeS @Override public String toString() { - return "addDefaultCredentialsToImage()"; + return Objects.toStringHelper(this).add("credsForImage", credsForImage).toString(); } } diff --git a/compute/src/main/java/org/jclouds/compute/strategy/impl/ReturnCredentialsBoundToImage.java b/compute/src/main/java/org/jclouds/compute/strategy/impl/ReturnCredentialsBoundToImage.java index 2e51b9b000..a049e83ee8 100644 --- a/compute/src/main/java/org/jclouds/compute/strategy/impl/ReturnCredentialsBoundToImage.java +++ b/compute/src/main/java/org/jclouds/compute/strategy/impl/ReturnCredentialsBoundToImage.java @@ -33,6 +33,8 @@ import org.jclouds.domain.Credentials; import org.jclouds.domain.LoginCredentials; import org.jclouds.javax.annotation.Nullable; +import com.google.common.base.Objects; + /** * @author Adrian Cole */ @@ -67,4 +69,9 @@ public class ReturnCredentialsBoundToImage implements PopulateDefaultLoginCreden return LoginCredentials.builder().user("root").build(); } } + + @Override + public String toString() { + return Objects.toStringHelper(this).toString(); + } } diff --git a/core/src/main/java/org/jclouds/collect/TransformingSetSupplier.java b/core/src/main/java/org/jclouds/collect/TransformingSetSupplier.java index 2010e8beaf..693026bd50 100644 --- a/core/src/main/java/org/jclouds/collect/TransformingSetSupplier.java +++ b/core/src/main/java/org/jclouds/collect/TransformingSetSupplier.java @@ -20,20 +20,23 @@ package org.jclouds.collect; import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Predicates.notNull; -import static com.google.common.collect.Iterables.filter; -import static com.google.common.collect.Iterables.transform; +import java.io.Serializable; import java.util.Set; import com.google.common.base.Function; +import com.google.common.base.Objects; import com.google.common.base.Supplier; -import com.google.common.collect.ImmutableSet; +import com.google.common.collect.FluentIterable; /** * * @author Adrian Cole */ -public class TransformingSetSupplier implements Supplier> { +public class TransformingSetSupplier implements Supplier>, Serializable { + /** The serialVersionUID */ + private static final long serialVersionUID = -8747953419394840218L; + private final Supplier> backingSupplier; private final Function converter; @@ -44,7 +47,33 @@ public class TransformingSetSupplier implements Supplier> @Override public Set get() { - return ImmutableSet.copyOf(filter(transform(filter(backingSupplier.get(), notNull()), converter), notNull())); + Iterable original = backingSupplier.get(); + return FluentIterable.from(original) + .filter(notNull()) + .transform(converter) + .filter(notNull()) + .toImmutableSet(); } + @Override + public int hashCode() { + return Objects.hashCode(backingSupplier, converter); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + TransformingSetSupplier that = TransformingSetSupplier.class.cast(obj); + return Objects.equal(backingSupplier, that.backingSupplier) && Objects.equal(converter, that.converter); + } + + @Override + public String toString() { + return Objects.toStringHelper(this).add("backingSupplier", backingSupplier).add("converter", converter).toString(); + } } diff --git a/core/src/main/java/org/jclouds/location/config/LocationModule.java b/core/src/main/java/org/jclouds/location/config/LocationModule.java index c3737ffec0..089b62f06a 100644 --- a/core/src/main/java/org/jclouds/location/config/LocationModule.java +++ b/core/src/main/java/org/jclouds/location/config/LocationModule.java @@ -24,6 +24,7 @@ import static org.jclouds.Constants.PROPERTY_SESSION_INTERVAL; import java.net.URI; import java.util.Map; import java.util.Set; +import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicReference; import javax.inject.Named; @@ -51,12 +52,12 @@ import org.jclouds.location.suppliers.ZoneIdsSupplier; import org.jclouds.rest.AuthorizationException; import org.jclouds.rest.functions.ImplicitOptionalConverter; import org.jclouds.rest.suppliers.MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier; +import org.jclouds.util.Suppliers2; import com.google.common.base.Function; import com.google.common.base.Optional; import com.google.common.base.Predicate; import com.google.common.base.Supplier; -import com.google.common.base.Suppliers; import com.google.common.collect.Sets; import com.google.inject.AbstractModule; import com.google.inject.Provides; @@ -81,7 +82,8 @@ public class LocationModule extends AbstractModule { protected Supplier>>> isoCodesSupplier( AtomicReference authException, @Named(PROPERTY_SESSION_INTERVAL) long seconds, LocationIdToIso3166CodesSupplier uncached) { - return MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier.create(authException, seconds, uncached); + return MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier.create(authException, uncached, seconds, + TimeUnit.SECONDS); } @Provides @@ -89,14 +91,16 @@ public class LocationModule extends AbstractModule { @Provider protected Supplier provideProvider(AtomicReference authException, @Named(PROPERTY_SESSION_INTERVAL) long seconds, ProviderURISupplier uncached) { - return MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier.create(authException, seconds, uncached); + return MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier.create(authException, uncached, seconds, + TimeUnit.SECONDS); } @Provides @Singleton protected Supplier implicitLocationSupplier(AtomicReference authException, @Named(PROPERTY_SESSION_INTERVAL) long seconds, ImplicitLocationSupplier uncached) { - return MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier.create(authException, seconds, uncached); + return MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier.create(authException, uncached, seconds, + TimeUnit.SECONDS); } @Provides @@ -106,7 +110,8 @@ public class LocationModule extends AbstractModule { protected Supplier> memoizedLocationsSupplier( AtomicReference authException, @Named(PROPERTY_SESSION_INTERVAL) long seconds, LocationsSupplier uncached) { - return MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier.create(authException, seconds, uncached); + return MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier.create(authException, uncached, seconds, + TimeUnit.SECONDS); } @Provides @@ -114,8 +119,8 @@ public class LocationModule extends AbstractModule { @Region protected Supplier> regionIdsSupplier(AtomicReference authException, @Named(PROPERTY_SESSION_INTERVAL) long seconds, RegionIdFilter filter, RegionIdsSupplier uncached) { - return MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier.create(authException, seconds, - Suppliers.compose(new FilterStrings(filter), uncached)); + return MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier.create(authException, + Suppliers2.compose(new FilterStrings(filter), uncached), seconds, TimeUnit.SECONDS); } @Provides @@ -124,8 +129,8 @@ public class LocationModule extends AbstractModule { protected Supplier> zoneIdsSupplier( AtomicReference authException, @Named(PROPERTY_SESSION_INTERVAL) long seconds, ZoneIdFilter filter, ZoneIdsSupplier uncached) { - return MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier.create(authException, seconds, - Suppliers.compose(new FilterStrings(filter), uncached)); + return MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier.create(authException, + Suppliers2.compose(new FilterStrings(filter), uncached), seconds, TimeUnit.SECONDS); } static class FilterStrings implements Function, Set>{ @@ -149,7 +154,8 @@ public class LocationModule extends AbstractModule { protected Supplier>> regionIdToURISupplier( AtomicReference authException, @Named(PROPERTY_SESSION_INTERVAL) long seconds, RegionIdToURISupplier uncached) { - return MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier.create(authException, seconds, uncached); + return MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier.create(authException, uncached, seconds, + TimeUnit.SECONDS); } @Provides @@ -157,7 +163,8 @@ public class LocationModule extends AbstractModule { @Region protected Supplier implicitRegionIdSupplier(AtomicReference authException, @Named(PROPERTY_SESSION_INTERVAL) long seconds, ImplicitRegionIdSupplier uncached) { - return MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier.create(authException, seconds, uncached); + return MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier.create(authException, uncached, seconds, + TimeUnit.SECONDS); } @@ -167,7 +174,8 @@ public class LocationModule extends AbstractModule { protected Supplier>>> regionIdToZoneIdsSupplier( AtomicReference authException, @Named(PROPERTY_SESSION_INTERVAL) long seconds, RegionIdToZoneIdsSupplier uncached) { - return MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier.create(authException, seconds, uncached); + return MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier.create(authException, uncached, seconds, + TimeUnit.SECONDS); } @Provides @@ -176,6 +184,7 @@ public class LocationModule extends AbstractModule { protected Supplier>> zoneIdToURISupplier( AtomicReference authException, @Named(PROPERTY_SESSION_INTERVAL) long seconds, ZoneIdToURISupplier uncached) { - return MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier.create(authException, seconds, uncached); + return MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier.create(authException, uncached, seconds, + TimeUnit.SECONDS); } } \ No newline at end of file diff --git a/core/src/main/java/org/jclouds/rest/suppliers/MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier.java b/core/src/main/java/org/jclouds/rest/suppliers/MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier.java index 166cf62646..41876de892 100644 --- a/core/src/main/java/org/jclouds/rest/suppliers/MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier.java +++ b/core/src/main/java/org/jclouds/rest/suppliers/MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier.java @@ -18,15 +18,24 @@ */ package org.jclouds.rest.suppliers; -import static org.jclouds.util.Suppliers2.memoizeWithExpirationAfterWrite; +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.base.Throwables.propagate; +import static org.jclouds.util.Throwables2.getFirstThrowableOfType; +import java.io.Serializable; +import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicReference; -import org.jclouds.concurrent.RetryOnTimeOutExceptionSupplier; import org.jclouds.rest.AuthorizationException; +import com.google.common.base.Objects; import com.google.common.base.Supplier; +import com.google.common.cache.CacheBuilder; +import com.google.common.cache.CacheLoader; +import com.google.common.cache.LoadingCache; +import com.google.common.collect.ForwardingObject; +import com.google.common.util.concurrent.UncheckedExecutionException; /** * This will retry the supplier if it encounters a timeout exception, but not if it encounters an @@ -41,31 +50,110 @@ import com.google.common.base.Supplier; * it is called again for each provider method that depends on it. To short-circuit this, we * remember the last exception trusting that guice is single-threaded. * + * Note this implementation is folded into the same class, vs being decorated as stacktraces are + * exceptionally long and difficult to grok otherwise. We use {@link LoadingCache} to deal with + * concurrency issues related to the supplier. + * * @author Adrian Cole */ -public class MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier implements Supplier { +public class MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier extends ForwardingObject implements + Supplier, Serializable { + + /** The serialVersionUID */ + private static final long serialVersionUID = 7626769175726919353L; + + static class NullValueException extends RuntimeException { + + /** The serialVersionUID */ + private static final long serialVersionUID = 5064521423206078374L; + + } + + static class SetAndThrowAuthorizationExceptionSupplierBackedLoader extends CacheLoader implements + Serializable { + /** The serialVersionUID */ + private static final long serialVersionUID = -6129510622181946809L; + + private final Supplier delegate; + private final AtomicReference authException; + + public SetAndThrowAuthorizationExceptionSupplierBackedLoader(Supplier delegate, + AtomicReference authException) { + this.delegate = checkNotNull(delegate, "delegate"); + this.authException = checkNotNull(authException, "authException"); + } + + @Override + public V load(String key) { + if (authException.get() != null) + throw authException.get(); + try { + V value = delegate.get(); + if (value == null) + throw new NullValueException(); + return value; + } catch (Exception e) { + AuthorizationException aex = getFirstThrowableOfType(e, AuthorizationException.class); + if (aex != null) { + authException.set(aex); + throw aex; + } + throw propagate(e); + } + } + + @Override + public String toString() { + return Objects.toStringHelper(this).add("delegate", delegate).toString(); + } + + } + private final Supplier delegate; - private final long seconds; + private final long duration; + private final TimeUnit unit; + private final LoadingCache cache; public static MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier create( - AtomicReference authException, long seconds, Supplier delegate) { - return new MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier(authException, seconds, delegate); + AtomicReference authException, Supplier delegate, long duration, TimeUnit unit) { + return new MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier(authException, delegate, duration, + unit); } - - public MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier( - AtomicReference authException, long seconds, Supplier delegate) { - this.delegate = memoizeWithExpirationAfterWrite(new RetryOnTimeOutExceptionSupplier( - new SetAndThrowAuthorizationExceptionSupplier(delegate, authException)), seconds, TimeUnit.SECONDS); - this.seconds = seconds; + + MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier(AtomicReference authException, + Supplier delegate, long duration, TimeUnit unit) { + this.delegate = delegate; + this.duration = duration; + this.unit = unit; + this.cache = CacheBuilder.newBuilder().expireAfterWrite(duration, unit) + .build(new SetAndThrowAuthorizationExceptionSupplierBackedLoader(delegate, authException)); + } + + @Override + protected Supplier delegate() { + return delegate; } @Override public T get() { - return delegate.get(); + try { + T returnVal = cache.get("FOO"); + return returnVal; + } catch (UncheckedExecutionException e) { + NullValueException nullV = getFirstThrowableOfType(e, NullValueException.class); + if (nullV != null) { + return null; + } + throw propagate(e.getCause()); + } catch (ExecutionException e) { + throw propagate(e.getCause()); + } } @Override public String toString() { - return "memoizeWithExpiration(" + delegate + ", seconds=" + seconds + ")"; + return Objects.toStringHelper(this).add("delegate", delegate).add("duration", duration).add("unit", unit) + .toString(); } + } \ No newline at end of file diff --git a/core/src/main/java/org/jclouds/util/Suppliers2.java b/core/src/main/java/org/jclouds/util/Suppliers2.java index 8456f00040..bc9b80b350 100644 --- a/core/src/main/java/org/jclouds/util/Suppliers2.java +++ b/core/src/main/java/org/jclouds/util/Suppliers2.java @@ -24,16 +24,12 @@ import java.io.IOException; import java.io.OutputStream; import java.io.Serializable; import java.util.Map; -import java.util.concurrent.TimeUnit; import com.google.common.base.Function; import com.google.common.base.Objects; +import com.google.common.base.Preconditions; import com.google.common.base.Supplier; import com.google.common.base.Suppliers; -import com.google.common.cache.CacheBuilder; -import com.google.common.cache.CacheLoader; -import com.google.common.cache.LoadingCache; -import com.google.common.collect.ForwardingObject; import com.google.common.collect.Iterables; import com.google.common.io.OutputSupplier; @@ -44,7 +40,7 @@ import com.google.common.io.OutputSupplier; public class Suppliers2 { public static Supplier getLastValueInMap(Supplier>> input) { - return Suppliers.compose(new Function>, V>() { + return Suppliers2.compose(new Function>, V>() { @Override public V apply(Map> input) { @@ -86,63 +82,35 @@ public class Suppliers2 { }; } - /** - * same as {@link Supplier.memoizeWithExpiration} except that the expiration ticker starts after - * write vs after call to {@code get}. - * - * @see Supplier.memoizeWithExpiration - */ - public static Supplier memoizeWithExpirationAfterWrite(Supplier delegate, long duration, TimeUnit unit) { - return new ExpireAfterWriteSupplier(delegate, duration, unit); + // only here until guava compose gives a toString! + // http://code.google.com/p/guava-libraries/issues/detail?id=1052 + public static Supplier compose(Function function, Supplier supplier) { + Preconditions.checkNotNull(function); + Preconditions.checkNotNull(supplier); + return new SupplierComposition(function, supplier); } - static class ExpireAfterWriteSupplier extends ForwardingObject implements Supplier, Serializable { - private final Supplier delegate; - private final long duration; - private final TimeUnit unit; - private final LoadingCache cache; + private static class SupplierComposition implements Supplier, Serializable { + /** The serialVersionUID */ + private static final long serialVersionUID = 1023509665531743802L; - public ExpireAfterWriteSupplier(Supplier delegate, long duration, TimeUnit unit) { - this.delegate = delegate; - this.duration = duration; - this.unit = unit; - cache = CacheBuilder.newBuilder().expireAfterWrite(duration, unit).build(CacheLoader.from(delegate)); - } + final Function function; + final Supplier supplier; - @Override - protected Supplier delegate() { - return delegate; + SupplierComposition(Function function, Supplier supplier) { + this.function = function; + this.supplier = supplier; } @Override public T get() { - return cache.getUnchecked("FOO"); - } - - private static final long serialVersionUID = 0; - - @Override - public int hashCode() { - return Objects.hashCode(delegate, duration, unit); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - ExpireAfterWriteSupplier that = ExpireAfterWriteSupplier.class.cast(obj); - return Objects.equal(delegate, that.delegate) && Objects.equal(duration, that.duration); + return function.apply(supplier.get()); } @Override public String toString() { - return Objects.toStringHelper(this).add("delegate", delegate).add("duration", duration).add("unit", unit) - .toString(); + return Objects.toStringHelper(this).add("function", function).add("supplier", supplier).toString(); } - } + } diff --git a/core/src/test/java/org/jclouds/rest/suppliers/MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplierTest.java b/core/src/test/java/org/jclouds/rest/suppliers/MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplierTest.java new file mode 100644 index 0000000000..32114b4f1b --- /dev/null +++ b/core/src/test/java/org/jclouds/rest/suppliers/MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplierTest.java @@ -0,0 +1,300 @@ +/** + * Licensed to jclouds, Inc. (jclouds) under one or more + * contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. jclouds licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.jclouds.rest.suppliers; + +import static com.google.common.base.Preconditions.checkNotNull; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertSame; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.Serializable; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; + +import org.jclouds.rest.AuthorizationException; +import org.jclouds.rest.suppliers.MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier.SetAndThrowAuthorizationExceptionSupplierBackedLoader; +import org.testng.annotations.Test; + +import com.google.common.base.Function; +import com.google.common.base.Supplier; +import com.google.common.base.Suppliers; + +/** + * + * @author Adrian Cole + */ +@SuppressWarnings({ "unchecked", "rawtypes" }) +@Test(groups = "unit", testName = "MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplierTest") +public class MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplierTest { + @Test + public void testLoaderNormal() { + AtomicReference authException = new AtomicReference(); + assertEquals(new SetAndThrowAuthorizationExceptionSupplierBackedLoader(Suppliers.ofInstance("foo"), + authException).load("KEY"), "foo"); + assertEquals(authException.get(), null); + } + + @Test(expectedExceptions = AuthorizationException.class) + public void testLoaderThrowsAuthorizationExceptionAndAlsoSetsExceptionType() { + AtomicReference authException = new AtomicReference(); + try { + new SetAndThrowAuthorizationExceptionSupplierBackedLoader(new Supplier() { + + @Override + public String get() { + throw new AuthorizationException(); + } + }, authException).load("KEY"); + } finally { + assertEquals(authException.get().getClass(), AuthorizationException.class); + } + } + + @Test(expectedExceptions = AuthorizationException.class) + public void testLoaderThrowsAuthorizationExceptionAndAlsoSetsExceptionTypeWhenNested() { + AtomicReference authException = new AtomicReference(); + try { + new SetAndThrowAuthorizationExceptionSupplierBackedLoader(new Supplier() { + + @Override + public String get() { + throw new RuntimeException(new ExecutionException(new AuthorizationException())); + } + }, authException).load("KEY"); + } finally { + assertEquals(authException.get().getClass(), AuthorizationException.class); + } + } + + @Test(expectedExceptions = RuntimeException.class) + public void testLoaderThrowsOriginalExceptionAndAlsoSetsExceptionTypeWhenNestedAndNotAuthorizationException() { + AtomicReference authException = new AtomicReference(); + try { + new SetAndThrowAuthorizationExceptionSupplierBackedLoader(new Supplier() { + + @Override + public String get() { + throw new RuntimeException(new IllegalArgumentException("foo")); + } + }, authException).load("KEY"); + } finally { + assertEquals(authException.get().getClass(), RuntimeException.class); + } + } + + @Test + public void testMemoizeKeepsValueForFullDurationWhenDelegateCallIsSlow() { + final long SLEEP_TIME = 250; + final long EXPIRATION_TIME = 200; + + Supplier slowSupplier = new CountingSupplier() { + private static final long serialVersionUID = 1L; + + @Override + public Integer get() { + try { + Thread.sleep(SLEEP_TIME); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + return super.get(); + } + }; + + Supplier memoizedSupplier = new MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier( + new AtomicReference(), slowSupplier, EXPIRATION_TIME, TimeUnit.MILLISECONDS); + + assertEquals(memoizedSupplier.get(), (Integer) 10); + assertEquals(memoizedSupplier.get(), (Integer) 10); + } + + // ================================= + // + // TODO Everything below this point is taken from SuppliersTest, to test our version of the + // Suppliers2.memoizeWithExpiration + // It should be deleted when we can switch back to using the google + // Supplier.memoizeWithExpiration. + + private static class CountingSupplier implements Supplier, Serializable { + private static final long serialVersionUID = 0L; + transient int calls = 0; + + @Override + public Integer get() { + calls++; + return calls * 10; + } + } + + @Test + public void testMemoizeWithExpiration() throws InterruptedException { + CountingSupplier countingSupplier = new CountingSupplier(); + + Supplier memoizedSupplier = new MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier( + new AtomicReference(), countingSupplier, 75, TimeUnit.MILLISECONDS); + + checkExpiration(countingSupplier, memoizedSupplier); + } + + @Test + public void testMemoizeWithExpirationSerialized() throws InterruptedException { + CountingSupplier countingSupplier = new CountingSupplier(); + + Supplier memoizedSupplier = new MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier( + new AtomicReference(), countingSupplier, 75, TimeUnit.MILLISECONDS); + // Calls to the original memoized supplier shouldn't affect its copy. + memoizedSupplier.get(); + + Supplier copy = reserialize(memoizedSupplier); + memoizedSupplier.get(); + + CountingSupplier countingCopy = (CountingSupplier) ((MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier) copy) + .delegate(); + checkExpiration(countingCopy, copy); + } + + private void checkExpiration(CountingSupplier countingSupplier, Supplier memoizedSupplier) + throws InterruptedException { + // the underlying supplier hasn't executed yet + assertEquals(0, countingSupplier.calls); + + assertEquals(10, (int) memoizedSupplier.get()); + // now it has + assertEquals(1, countingSupplier.calls); + + assertEquals(10, (int) memoizedSupplier.get()); + // it still should only have executed once due to memoization + assertEquals(1, countingSupplier.calls); + + Thread.sleep(150); + + assertEquals(20, (int) memoizedSupplier.get()); + // old value expired + assertEquals(2, countingSupplier.calls); + + assertEquals(20, (int) memoizedSupplier.get()); + // it still should only have executed twice due to memoization + assertEquals(2, countingSupplier.calls); + } + + @Test + public void testExpiringMemoizedSupplierThreadSafe() throws Throwable { + Function, Supplier> memoizer = new Function, Supplier>() { + @Override + public Supplier apply(Supplier supplier) { + return new MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier( + new AtomicReference(), supplier, Long.MAX_VALUE, TimeUnit.NANOSECONDS); + } + }; + supplierThreadSafe(memoizer); + } + + private void supplierThreadSafe(Function, Supplier> memoizer) throws Throwable { + final AtomicInteger count = new AtomicInteger(0); + final AtomicReference thrown = new AtomicReference(null); + final int numThreads = 3; + final Thread[] threads = new Thread[numThreads]; + final long timeout = TimeUnit.SECONDS.toNanos(60); + + final Supplier supplier = new Supplier() { + boolean isWaiting(Thread thread) { + switch (thread.getState()) { + case BLOCKED: + case WAITING: + case TIMED_WAITING: + return true; + default: + return false; + } + } + + int waitingThreads() { + int waitingThreads = 0; + for (Thread thread : threads) { + if (isWaiting(thread)) { + waitingThreads++; + } + } + return waitingThreads; + } + + @Override + public Boolean get() { + // Check that this method is called exactly once, by the first + // thread to synchronize. + long t0 = System.nanoTime(); + while (waitingThreads() != numThreads - 1) { + if (System.nanoTime() - t0 > timeout) { + thrown.set(new TimeoutException("timed out waiting for other threads to block" + + " synchronizing on supplier")); + break; + } + Thread.yield(); + } + count.getAndIncrement(); + return Boolean.TRUE; + } + }; + + final Supplier memoizedSupplier = memoizer.apply(supplier); + + for (int i = 0; i < numThreads; i++) { + threads[i] = new Thread() { + @Override + public void run() { + assertSame(Boolean.TRUE, memoizedSupplier.get()); + } + }; + } + for (Thread t : threads) { + t.start(); + } + for (Thread t : threads) { + t.join(); + } + + if (thrown.get() != null) { + throw thrown.get(); + } + assertEquals(1, count.get()); + } + + // Taken from com.google.common.testing.SerializableTester + private static T reserialize(T object) { + checkNotNull(object); + ByteArrayOutputStream bytes = new ByteArrayOutputStream(); + try { + ObjectOutputStream out = new ObjectOutputStream(bytes); + out.writeObject(object); + ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(bytes.toByteArray())); + return (T) in.readObject(); + } catch (IOException e) { + throw new RuntimeException(e); + } catch (ClassNotFoundException e) { + throw new RuntimeException(e); + } + } +} diff --git a/core/src/test/java/org/jclouds/rest/suppliers/SetAndThrowAuthorizationExceptionSupplierTest.java b/core/src/test/java/org/jclouds/rest/suppliers/SetAndThrowAuthorizationExceptionSupplierTest.java index 3163750db9..a94f094a6a 100644 --- a/core/src/test/java/org/jclouds/rest/suppliers/SetAndThrowAuthorizationExceptionSupplierTest.java +++ b/core/src/test/java/org/jclouds/rest/suppliers/SetAndThrowAuthorizationExceptionSupplierTest.java @@ -30,11 +30,10 @@ import com.google.common.base.Supplier; import com.google.common.base.Suppliers; /** - * Tests behavior of {@code SetAndThrowAuthorizationExceptionSupplier} * * @author Adrian Cole */ -@Test(groups = "unit") +@Test(groups = "unit", testName = "MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplierTest") public class SetAndThrowAuthorizationExceptionSupplierTest { @Test public void testNormal() { diff --git a/core/src/test/java/org/jclouds/util/Suppliers2Test.java b/core/src/test/java/org/jclouds/util/Suppliers2Test.java index d82bf9c33d..6ff27ccbff 100644 --- a/core/src/test/java/org/jclouds/util/Suppliers2Test.java +++ b/core/src/test/java/org/jclouds/util/Suppliers2Test.java @@ -56,199 +56,4 @@ public class Suppliers2Test { assertEquals(Suppliers2.ofInstanceFunction().apply("foo").get(), "foo"); } - @Test - public void testMemoizeKeepsValueForFullDurationWhenDelegateCallIsSlow() { - final long SLEEP_TIME = 250; - final long EXPIRATION_TIME = 200; - - Supplier slowSupplier = new CountingSupplier() { - private static final long serialVersionUID = 1L; - - @Override public Integer get() { - try { - Thread.sleep(SLEEP_TIME); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } - return super.get(); - } - }; - - Supplier memoizedSupplier = Suppliers2.memoizeWithExpirationAfterWrite( - slowSupplier, EXPIRATION_TIME, TimeUnit.MILLISECONDS); - - assertEquals(memoizedSupplier.get(), (Integer)10); - assertEquals(memoizedSupplier.get(), (Integer)10); - } - - // ================================= - // - // TODO Everything below this point is taken from SuppliersTest, to test our version of the Suppliers2.memoizeWithExpiration - // It should be deleted when we can switch back to using the google Supplier.memoizeWithExpiration. - - private static class CountingSupplier implements Supplier, Serializable { - private static final long serialVersionUID = 0L; - transient int calls = 0; - @Override - public Integer get() { - calls++; - return calls * 10; - } - } - - @Test - public void testMemoizeWithExpiration() throws InterruptedException { - CountingSupplier countingSupplier = new CountingSupplier(); - - Supplier memoizedSupplier = Suppliers2.memoizeWithExpirationAfterWrite( - countingSupplier, 75, TimeUnit.MILLISECONDS); - - checkExpiration(countingSupplier, memoizedSupplier); - } - - @Test - public void testMemoizeWithExpirationSerialized() - throws InterruptedException { - CountingSupplier countingSupplier = new CountingSupplier(); - - Supplier memoizedSupplier = Suppliers2.memoizeWithExpirationAfterWrite( - countingSupplier, 75, TimeUnit.MILLISECONDS); - // Calls to the original memoized supplier shouldn't affect its copy. - memoizedSupplier.get(); - - Supplier copy = reserialize(memoizedSupplier); - memoizedSupplier.get(); - - CountingSupplier countingCopy = (CountingSupplier) - ((Suppliers2.ExpireAfterWriteSupplier) copy).delegate(); - checkExpiration(countingCopy, copy); - } - - private void checkExpiration( - CountingSupplier countingSupplier, Supplier memoizedSupplier) - throws InterruptedException { - // the underlying supplier hasn't executed yet - assertEquals(0, countingSupplier.calls); - - assertEquals(10, (int) memoizedSupplier.get()); - // now it has - assertEquals(1, countingSupplier.calls); - - assertEquals(10, (int) memoizedSupplier.get()); - // it still should only have executed once due to memoization - assertEquals(1, countingSupplier.calls); - - Thread.sleep(150); - - assertEquals(20, (int) memoizedSupplier.get()); - // old value expired - assertEquals(2, countingSupplier.calls); - - assertEquals(20, (int) memoizedSupplier.get()); - // it still should only have executed twice due to memoization - assertEquals(2, countingSupplier.calls); - } - - @Test - public void testExpiringMemoizedSupplierThreadSafe() throws Throwable { - Function, Supplier> memoizer = - new Function, Supplier>() { - @Override public Supplier apply(Supplier supplier) { - return Suppliers2.memoizeWithExpirationAfterWrite( - supplier, Long.MAX_VALUE, TimeUnit.NANOSECONDS); - } - }; - testSupplierThreadSafe(memoizer); - } - - public void testSupplierThreadSafe( - Function, Supplier> memoizer) - throws Throwable { - final AtomicInteger count = new AtomicInteger(0); - final AtomicReference thrown = - new AtomicReference(null); - final int numThreads = 3; - final Thread[] threads = new Thread[numThreads]; - final long timeout = TimeUnit.SECONDS.toNanos(60); - - final Supplier supplier = new Supplier() { - boolean isWaiting(Thread thread) { - switch (thread.getState()) { - case BLOCKED: - case WAITING: - case TIMED_WAITING: - return true; - default: - return false; - } - } - - int waitingThreads() { - int waitingThreads = 0; - for (Thread thread : threads) { - if (isWaiting(thread)) { - waitingThreads++; - } - } - return waitingThreads; - } - - @Override - public Boolean get() { - // Check that this method is called exactly once, by the first - // thread to synchronize. - long t0 = System.nanoTime(); - while (waitingThreads() != numThreads - 1) { - if (System.nanoTime() - t0 > timeout) { - thrown.set(new TimeoutException( - "timed out waiting for other threads to block" + - " synchronizing on supplier")); - break; - } - Thread.yield(); - } - count.getAndIncrement(); - return Boolean.TRUE; - } - }; - - final Supplier memoizedSupplier = memoizer.apply(supplier); - - for (int i = 0; i < numThreads; i++) { - threads[i] = new Thread() { - @Override public void run() { - assertSame(Boolean.TRUE, memoizedSupplier.get()); - } - }; - } - for (Thread t : threads) { - t.start(); - } - for (Thread t : threads) { - t.join(); - } - - if (thrown.get() != null) { - throw thrown.get(); - } - assertEquals(1, count.get()); - } - - // Taken from com.google.common.testing.SerializableTester - @SuppressWarnings("unchecked") - private static T reserialize(T object) { - checkNotNull(object); - ByteArrayOutputStream bytes = new ByteArrayOutputStream(); - try { - ObjectOutputStream out = new ObjectOutputStream(bytes); - out.writeObject(object); - ObjectInputStream in = new ObjectInputStream( - new ByteArrayInputStream(bytes.toByteArray())); - return (T) in.readObject(); - } catch (IOException e) { - throw new RuntimeException(e); - } catch (ClassNotFoundException e) { - throw new RuntimeException(e); - } - } } diff --git a/labs/joyent-sdc/src/main/java/org/jclouds/joyent/sdc/v6_5/compute/config/SDCComputeServiceContextModule.java b/labs/joyent-sdc/src/main/java/org/jclouds/joyent/sdc/v6_5/compute/config/SDCComputeServiceContextModule.java index b8c5a291be..1dc909fa8c 100644 --- a/labs/joyent-sdc/src/main/java/org/jclouds/joyent/sdc/v6_5/compute/config/SDCComputeServiceContextModule.java +++ b/labs/joyent-sdc/src/main/java/org/jclouds/joyent/sdc/v6_5/compute/config/SDCComputeServiceContextModule.java @@ -56,11 +56,11 @@ import org.jclouds.joyent.sdc.v6_5.domain.datacenterscoped.DatasetInDatacenter; import org.jclouds.joyent.sdc.v6_5.domain.datacenterscoped.MachineInDatacenter; import org.jclouds.joyent.sdc.v6_5.domain.datacenterscoped.PackageInDatacenter; import org.jclouds.util.Iterables2; +import org.jclouds.util.Suppliers2; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Function; import com.google.common.base.Supplier; -import com.google.common.base.Suppliers; import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheLoader; import com.google.common.cache.LoadingCache; @@ -134,7 +134,7 @@ public class SDCComputeServiceContextModule extends @Singleton protected Supplier> createLocationIndexedById( @Memoized Supplier> locations) { - return Suppliers.compose(new Function, Map>() { + return Suppliers2.compose(new Function, Map>() { @Override public Map apply(Set arg0) { diff --git a/labs/nodepool/src/main/java/org/jclouds/nodepool/config/BindBackendComputeService.java b/labs/nodepool/src/main/java/org/jclouds/nodepool/config/BindBackendComputeService.java index 49c14da33d..b3c3429b52 100644 --- a/labs/nodepool/src/main/java/org/jclouds/nodepool/config/BindBackendComputeService.java +++ b/labs/nodepool/src/main/java/org/jclouds/nodepool/config/BindBackendComputeService.java @@ -36,6 +36,7 @@ import org.jclouds.location.Provider; import org.jclouds.nodepool.Backend; import org.jclouds.rest.annotations.ApiVersion; import org.jclouds.rest.annotations.BuildVersion; +import org.jclouds.util.Suppliers2; import com.google.common.base.Function; import com.google.common.base.Predicate; @@ -117,7 +118,7 @@ public class BindBackendComputeService extends BindJcloudsModules { @Backend @Exposed protected Supplier