From d476016bd57bcbdd6ff465dc8fddaeeb3c4694d5 Mon Sep 17 00:00:00 2001 From: Adrian Cole Date: Mon, 26 Jul 2010 14:57:37 -0700 Subject: [PATCH] Issue 322: switched to Suppliers.memoizeWithExpiration --- .../config/AtmosStorageRestClientModule.java | 4 +- .../aws/s3/config/S3RestClientModule.java | 4 +- .../config/AzureStorageRestClientModule.java | 4 +- .../chef/config/BaseChefRestClientModule.java | 4 +- .../jclouds/concurrent/ExpirableSupplier.java | 59 ------------ .../gogrid/config/GoGridRestClientModule.java | 19 ++-- .../RackspaceAuthenticationRestModule.java | 6 +- .../config/BaseVCloudRestClientModule.java | 95 +++++++++---------- 8 files changed, 64 insertions(+), 131 deletions(-) delete mode 100644 core/src/main/java/org/jclouds/concurrent/ExpirableSupplier.java diff --git a/atmos/src/main/java/org/jclouds/atmosonline/saas/config/AtmosStorageRestClientModule.java b/atmos/src/main/java/org/jclouds/atmosonline/saas/config/AtmosStorageRestClientModule.java index 1e02157d2a..1b549c5956 100644 --- a/atmos/src/main/java/org/jclouds/atmosonline/saas/config/AtmosStorageRestClientModule.java +++ b/atmos/src/main/java/org/jclouds/atmosonline/saas/config/AtmosStorageRestClientModule.java @@ -27,7 +27,6 @@ import org.jclouds.atmosonline.saas.AtmosStorageAsyncClient; import org.jclouds.atmosonline.saas.AtmosStorageClient; import org.jclouds.atmosonline.saas.handlers.AtmosStorageClientErrorRetryHandler; import org.jclouds.atmosonline.saas.handlers.ParseAtmosStorageErrorFromXmlContent; -import org.jclouds.concurrent.ExpirableSupplier; import org.jclouds.date.DateService; import org.jclouds.date.TimeStamp; import org.jclouds.http.HttpErrorHandler; @@ -40,6 +39,7 @@ import org.jclouds.rest.ConfiguresRestClient; import org.jclouds.rest.config.RestClientModule; import com.google.common.base.Supplier; +import com.google.common.base.Suppliers; import com.google.inject.Provides; /** @@ -75,7 +75,7 @@ public class AtmosStorageRestClientModule extends RestClientModule provideTimeStampCache(@Named(Constants.PROPERTY_SESSION_INTERVAL) long seconds, final DateService dateService) { - return new ExpirableSupplier(new Supplier() { + return Suppliers.memoizeWithExpiration(new Supplier() { public String get() { return dateService.rfc822DateFormat(); } diff --git a/aws/core/src/main/java/org/jclouds/aws/s3/config/S3RestClientModule.java b/aws/core/src/main/java/org/jclouds/aws/s3/config/S3RestClientModule.java index 40452baf71..7b250b0e32 100755 --- a/aws/core/src/main/java/org/jclouds/aws/s3/config/S3RestClientModule.java +++ b/aws/core/src/main/java/org/jclouds/aws/s3/config/S3RestClientModule.java @@ -28,7 +28,6 @@ import org.jclouds.aws.config.AWSRestClientModule; import org.jclouds.aws.s3.S3AsyncClient; import org.jclouds.aws.s3.S3Client; import org.jclouds.aws.s3.filters.RequestAuthorizeSignature; -import org.jclouds.concurrent.ExpirableSupplier; import org.jclouds.date.DateService; import org.jclouds.date.TimeStamp; import org.jclouds.http.RequiresHttp; @@ -36,6 +35,7 @@ import org.jclouds.rest.ConfiguresRestClient; import org.jclouds.rest.RequestSigner; import com.google.common.base.Supplier; +import com.google.common.base.Suppliers; import com.google.inject.Provides; import com.google.inject.Scopes; @@ -79,7 +79,7 @@ public class S3RestClientModule extends AWSRestClientModule provideTimeStampCache(@Named(Constants.PROPERTY_SESSION_INTERVAL) long seconds, final DateService dateService) { - return new ExpirableSupplier(new Supplier() { + return Suppliers.memoizeWithExpiration(new Supplier() { public String get() { return dateService.rfc822DateFormat(); } diff --git a/azure/src/main/java/org/jclouds/azure/storage/config/AzureStorageRestClientModule.java b/azure/src/main/java/org/jclouds/azure/storage/config/AzureStorageRestClientModule.java index 8657032f96..ef7ec29dd9 100644 --- a/azure/src/main/java/org/jclouds/azure/storage/config/AzureStorageRestClientModule.java +++ b/azure/src/main/java/org/jclouds/azure/storage/config/AzureStorageRestClientModule.java @@ -26,7 +26,6 @@ import javax.inject.Named; import org.jclouds.azure.storage.handlers.AzureStorageClientErrorRetryHandler; import org.jclouds.azure.storage.handlers.ParseAzureStorageErrorFromXmlContent; -import org.jclouds.concurrent.ExpirableSupplier; import org.jclouds.date.DateService; import org.jclouds.date.TimeStamp; import org.jclouds.http.HttpErrorHandler; @@ -39,6 +38,7 @@ import org.jclouds.rest.ConfiguresRestClient; import org.jclouds.rest.config.RestClientModule; import com.google.common.base.Supplier; +import com.google.common.base.Suppliers; import com.google.inject.Provides; /** @@ -67,7 +67,7 @@ public class AzureStorageRestClientModule extends RestClientModule { @TimeStamp protected Supplier provideTimeStampCache(@Named(PROPERTY_SESSION_INTERVAL) long seconds, final DateService dateService) { - return new ExpirableSupplier(new Supplier() { + return Suppliers.memoizeWithExpiration(new Supplier() { public String get() { return dateService.rfc822DateFormat(); } diff --git a/chef/src/main/java/org/jclouds/chef/config/BaseChefRestClientModule.java b/chef/src/main/java/org/jclouds/chef/config/BaseChefRestClientModule.java index 74b75c5f9b..b019eaa330 100644 --- a/chef/src/main/java/org/jclouds/chef/config/BaseChefRestClientModule.java +++ b/chef/src/main/java/org/jclouds/chef/config/BaseChefRestClientModule.java @@ -31,7 +31,6 @@ import javax.inject.Singleton; import org.jclouds.chef.handlers.ChefClientErrorRetryHandler; import org.jclouds.chef.handlers.ChefErrorHandler; -import org.jclouds.concurrent.ExpirableSupplier; import org.jclouds.date.DateService; import org.jclouds.date.TimeStamp; import org.jclouds.encryption.EncryptionService; @@ -45,6 +44,7 @@ import org.jclouds.rest.ConfiguresRestClient; import org.jclouds.rest.config.RestClientModule; import com.google.common.base.Supplier; +import com.google.common.base.Suppliers; import com.google.inject.Provides; /** @@ -77,7 +77,7 @@ public class BaseChefRestClientModule extends RestClientModule { @Provides @TimeStamp Supplier provideTimeStampCache(@Named(PROPERTY_SESSION_INTERVAL) long seconds, final DateService dateService) { - return new ExpirableSupplier(new Supplier() { + return Suppliers.memoizeWithExpiration(new Supplier() { public String get() { return dateService.iso8601SecondsDateFormat(); } diff --git a/core/src/main/java/org/jclouds/concurrent/ExpirableSupplier.java b/core/src/main/java/org/jclouds/concurrent/ExpirableSupplier.java deleted file mode 100644 index b4c27a835a..0000000000 --- a/core/src/main/java/org/jclouds/concurrent/ExpirableSupplier.java +++ /dev/null @@ -1,59 +0,0 @@ -/** - * - * Copyright (C) 2009 Cloud Conscious, LLC. - * - * ==================================================================== - * Licensed 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.concurrent; - -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicLong; -import java.util.concurrent.atomic.AtomicReference; - -import com.google.common.base.Supplier; - -/** - * Works in google app engine since it doesn't use threads. - * - * @author Adrian Cole - */ -public class ExpirableSupplier implements Supplier { - private final Supplier supplier; - private final AtomicReference currentValue; - private final AtomicLong trigger; - private final long expirationNanos; - - public ExpirableSupplier(Supplier supplier, long duration, TimeUnit unit) { - this.supplier = supplier; - this.expirationNanos = unit.toNanos(duration); - this.currentValue = new AtomicReference(null); - trigger = new AtomicLong(System.nanoTime() + expirationNanos); - } - - void updateIfExpired() { - V current = currentValue.get(); - if (current == null || trigger.get() - System.nanoTime() <= 0) { - trigger.set(System.nanoTime() + expirationNanos); - // we always want the last one to win. think login session - currentValue.set(supplier.get()); - } - } - - public V get() { - updateIfExpired(); - return currentValue.get(); - } - -} \ No newline at end of file diff --git a/gogrid/src/main/java/org/jclouds/gogrid/config/GoGridRestClientModule.java b/gogrid/src/main/java/org/jclouds/gogrid/config/GoGridRestClientModule.java index 7002133432..df2d8961a5 100644 --- a/gogrid/src/main/java/org/jclouds/gogrid/config/GoGridRestClientModule.java +++ b/gogrid/src/main/java/org/jclouds/gogrid/config/GoGridRestClientModule.java @@ -25,7 +25,6 @@ import java.util.concurrent.TimeUnit; import javax.inject.Named; -import org.jclouds.concurrent.ExpirableSupplier; import org.jclouds.date.TimeStamp; import org.jclouds.gogrid.GoGridAsyncClient; import org.jclouds.gogrid.GoGridClient; @@ -49,6 +48,7 @@ import org.jclouds.rest.ConfiguresRestClient; import org.jclouds.rest.config.RestClientModule; import com.google.common.base.Supplier; +import com.google.common.base.Suppliers; import com.google.common.collect.ImmutableMap; import com.google.inject.Provides; @@ -61,14 +61,13 @@ import com.google.inject.Provides; @RequiresHttp @ConfiguresRestClient public class GoGridRestClientModule extends RestClientModule { - public static final Map, Class> DELEGATE_MAP = ImmutableMap - ., Class> builder()// - .put(GridServerClient.class, GridServerAsyncClient.class)// - .put(GridJobClient.class, GridJobAsyncClient.class)// - .put(GridIpClient.class, GridIpAsyncClient.class)// - .put(GridLoadBalancerClient.class, GridLoadBalancerAsyncClient.class)// - .put(GridImageClient.class, GridImageAsyncClient.class)// - .build(); + public static final Map, Class> DELEGATE_MAP = ImmutableMap., Class> builder()// + .put(GridServerClient.class, GridServerAsyncClient.class)// + .put(GridJobClient.class, GridJobAsyncClient.class)// + .put(GridIpClient.class, GridIpAsyncClient.class)// + .put(GridLoadBalancerClient.class, GridLoadBalancerAsyncClient.class)// + .put(GridImageClient.class, GridImageAsyncClient.class)// + .build(); public GoGridRestClientModule() { super(GoGridClient.class, GoGridAsyncClient.class, DELEGATE_MAP); @@ -86,7 +85,7 @@ public class GoGridRestClientModule extends RestClientModule provideTimeStampCache(@Named(PROPERTY_SESSION_INTERVAL) long seconds) { - return new ExpirableSupplier(new Supplier() { + return Suppliers.memoizeWithExpiration(new Supplier() { public Long get() { return System.currentTimeMillis() / 1000; } diff --git a/rackspace/src/main/java/org/jclouds/rackspace/config/RackspaceAuthenticationRestModule.java b/rackspace/src/main/java/org/jclouds/rackspace/config/RackspaceAuthenticationRestModule.java index dcc3366064..4ab207ccfd 100755 --- a/rackspace/src/main/java/org/jclouds/rackspace/config/RackspaceAuthenticationRestModule.java +++ b/rackspace/src/main/java/org/jclouds/rackspace/config/RackspaceAuthenticationRestModule.java @@ -28,7 +28,6 @@ import javax.inject.Named; import javax.inject.Singleton; import org.jclouds.Constants; -import org.jclouds.concurrent.ExpirableSupplier; import org.jclouds.concurrent.RetryOnTimeOutExceptionSupplier; import org.jclouds.date.TimeStamp; import org.jclouds.http.RequiresHttp; @@ -41,6 +40,7 @@ import org.jclouds.rackspace.RackspaceAuthAsyncClient.AuthenticationResponse; import org.jclouds.rest.AsyncClientFactory; import com.google.common.base.Supplier; +import com.google.common.base.Suppliers; import com.google.common.base.Throwables; import com.google.common.util.concurrent.ListenableFuture; import com.google.inject.AbstractModule; @@ -79,7 +79,7 @@ public class RackspaceAuthenticationRestModule extends AbstractModule { @Singleton Supplier provideAuthenticationResponseCache(final AsyncClientFactory factory, @Named(Constants.PROPERTY_IDENTITY) final String user, @Named(Constants.PROPERTY_CREDENTIAL) final String key) { - return new ExpirableSupplier(new RetryOnTimeOutExceptionSupplier( + return Suppliers.memoizeWithExpiration(new RetryOnTimeOutExceptionSupplier( new Supplier() { public AuthenticationResponse get() { try { @@ -99,7 +99,7 @@ public class RackspaceAuthenticationRestModule extends AbstractModule { @Singleton @TimeStamp protected Supplier provideCacheBusterDate() { - return new ExpirableSupplier(new Supplier() { + return Suppliers.memoizeWithExpiration(new Supplier() { public Date get() { return new Date(); } diff --git a/vcloud/core/src/main/java/org/jclouds/vcloud/config/BaseVCloudRestClientModule.java b/vcloud/core/src/main/java/org/jclouds/vcloud/config/BaseVCloudRestClientModule.java index ee0308efd4..eee5ac023e 100644 --- a/vcloud/core/src/main/java/org/jclouds/vcloud/config/BaseVCloudRestClientModule.java +++ b/vcloud/core/src/main/java/org/jclouds/vcloud/config/BaseVCloudRestClientModule.java @@ -37,7 +37,6 @@ import javax.annotation.Resource; import javax.inject.Named; import javax.inject.Singleton; -import org.jclouds.concurrent.ExpirableSupplier; import org.jclouds.concurrent.RetryOnTimeOutExceptionSupplier; import org.jclouds.http.HttpErrorHandler; import org.jclouds.http.RequiresHttp; @@ -73,20 +72,22 @@ import org.jclouds.vcloud.predicates.TaskSuccess; import com.google.common.base.Predicate; import com.google.common.base.Supplier; +import com.google.common.base.Suppliers; import com.google.common.base.Throwables; import com.google.common.collect.Iterables; import com.google.inject.Provides; import com.google.inject.internal.Maps; /** - * Configures the VCloud authentication service connection, including logging and http transport. + * Configures the VCloud authentication service connection, including logging + * and http transport. * * @author Adrian Cole */ @RequiresHttp @ConfiguresRestClient -public abstract class BaseVCloudRestClientModule - extends RestClientModule { +public abstract class BaseVCloudRestClientModule extends + RestClientModule { public BaseVCloudRestClientModule(Class syncClientType, Class asyncClientType) { super(syncClientType, asyncClientType); @@ -104,7 +105,7 @@ public abstract class BaseVCloudRestClientModule successTester(TaskSuccess success, - @Named(PROPERTY_VCLOUD_TIMEOUT_TASK_COMPLETED) long completed) { + @Named(PROPERTY_VCLOUD_TIMEOUT_TASK_COMPLETED) long completed) { return new RetryablePredicate(success, completed); } @@ -124,8 +125,7 @@ public abstract class BaseVCloudRestClientModule provideVDCtoORG(@Org Iterable orgs, - VCloudClient client) { + protected Map provideVDCtoORG(@Org Iterable orgs, VCloudClient client) { Map returnVal = Maps.newLinkedHashMap(); for (NamedResource orgr : orgs) { for (NamedResource vdc : client.getOrganization(orgr.getId()).getVDCs().values()) { @@ -138,8 +138,7 @@ public abstract class BaseVCloudRestClientModule provideOrgs(Supplier cache, - @Named(PROPERTY_IDENTITY) String user) { + protected Iterable provideOrgs(Supplier cache, @Named(PROPERTY_IDENTITY) String user) { VCloudSession discovery = cache.get(); checkState(discovery.getOrgs().size() > 0, "No orgs present for user: " + user); return discovery.getOrgs().values(); @@ -160,47 +159,44 @@ public abstract class BaseVCloudRestClientModule provideVCloudTokenCache(@Named(PROPERTY_SESSION_INTERVAL) long seconds, - final VCloudLoginAsyncClient login) { - return new ExpirableSupplier( - new RetryOnTimeOutExceptionSupplier(new Supplier() { - public VCloudSession get() { - // http://code.google.com/p/google-guice/issues/detail?id=483 - // guice doesn't remember when singleton providers throw - // exceptions. - // in this case, if describeRegions fails, 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 - if (authException != null) - throw authException; - try { - return login.login().get(10, TimeUnit.SECONDS); - } catch (AuthorizationException e) { - BaseVCloudRestClientModule.this.authException = e; - throw e; - } catch (Exception e) { - Throwables.propagate(e); - assert false : e; - return null; - } + final VCloudLoginAsyncClient login) { + return Suppliers.memoizeWithExpiration(new RetryOnTimeOutExceptionSupplier( + new Supplier() { + public VCloudSession get() { + // http://code.google.com/p/google-guice/issues/detail?id=483 + // guice doesn't remember when singleton providers throw + // exceptions. + // in this case, if describeRegions fails, 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 + if (authException != null) + throw authException; + try { + return login.login().get(10, TimeUnit.SECONDS); + } catch (AuthorizationException e) { + BaseVCloudRestClientModule.this.authException = e; + throw e; + } catch (Exception e) { + Throwables.propagate(e); + assert false : e; + return null; } + } - }), seconds, TimeUnit.SECONDS); + }), seconds, TimeUnit.SECONDS); } @Provides @Singleton @org.jclouds.vcloud.endpoints.VCloudLogin protected URI provideAuthenticationURI(VCloudVersionsAsyncClient versionService, - @Named(PROPERTY_API_VERSION) String version) throws InterruptedException, - ExecutionException, TimeoutException { - SortedMap versions = versionService.getSupportedVersions().get(180, - TimeUnit.SECONDS); + @Named(PROPERTY_API_VERSION) String version) throws InterruptedException, ExecutionException, TimeoutException { + SortedMap versions = versionService.getSupportedVersions().get(180, TimeUnit.SECONDS); checkState(versions.size() > 0, "No versions present"); - checkState(versions.containsKey(version), "version " + version + " not present in: " - + versions); + checkState(versions.containsKey(version), "version " + version + " not present in: " + versions); return versions.get(version); } @@ -239,8 +235,8 @@ public abstract class BaseVCloudRestClientModule