From 3962b30808312d349cac8e9556e5a78e94ee5a6e Mon Sep 17 00:00:00 2001 From: Adrian Cole Date: Sun, 13 Jan 2013 09:31:10 -0800 Subject: [PATCH] updated to use standard guava Futures and ListenableFuture --- .../atmos/blobstore/AtmosAsyncBlobStore.java | 44 +++++------ .../strategy/FindMD5InUserMetadata.java | 15 ++-- .../atmos/internal/StubAtmosAsyncClient.java | 34 ++++---- .../blobstore/CloudFilesAsyncBlobStore.java | 15 ++-- .../CloudServersImageExtension.java | 17 ++-- .../CloudSigmaComputeServiceAdapter.java | 17 ++-- .../ec2/compute/EC2ComputeService.java | 6 +- .../compute/extensions/EC2ImageExtension.java | 13 ++-- .../strategy/DescribeImagesParallel.java | 21 ++--- .../EC2CreateNodesInGroupThenAddToSet.java | 4 +- .../strategy/EC2ListNodesStrategy.java | 25 +++--- .../ElasticStackComputeServiceAdapter.java | 16 ++-- .../nova/v2_0/compute/NovaComputeService.java | 6 +- .../extensions/NovaImageExtension.java | 13 ++-- ...sWithGroupEncodedIntoNameThenAddToSet.java | 18 ++--- ...oadBalancersListLoadBalancersStrategy.java | 33 ++------ .../main/java/org/jclouds/s3/S3Client.java | 3 + .../s3/blobstore/S3AsyncBlobStore.java | 28 +++---- .../functions/BucketsToStorageMetadata.java | 12 +-- .../handlers/ParseS3ErrorFromXmlContent.java | 6 +- .../org/jclouds/s3/xml/ListBucketHandler.java | 1 + .../org/jclouds/s3/S3AsyncClientTest.java | 2 +- .../java/org/jclouds/s3/S3ClientLiveTest.java | 6 +- .../s3/internal/StubS3AsyncClient.java | 19 +++-- .../swift/blobstore/SwiftAsyncBlobStore.java | 26 +++---- .../ParallelMultipartUploadStrategy.java | 60 +++++++-------- .../swift/internal/StubSwiftAsyncClient.java | 18 ++--- .../functions/CatalogItemsInCatalog.java | 19 ++--- .../vcloud/functions/CatalogsInOrg.java | 18 ++--- .../vcloud/functions/NetworksInOrg.java | 18 ++--- .../vcloud/functions/OrgsForLocations.java | 19 ++--- .../vcloud/functions/OrgsForNames.java | 20 ++--- .../VAppTemplatesForCatalogItems.java | 23 ++---- .../jclouds/vcloud/functions/VDCsInOrg.java | 19 ++--- .../suppliers/VAppTemplatesSupplier.java | 25 +++--- .../blobstore/LocalAsyncBlobStore.java | 6 +- .../internal/BaseAsyncBlobStore.java | 33 ++++---- .../internal/DeleteAllKeysInList.java | 20 +++-- .../strategy/internal/FetchBlobMetadata.java | 13 ++-- .../GetAllBlobsInListAndRetryOnFailure.java | 13 ++-- .../MarkersDeleteDirectoryStrategy.java | 10 +-- .../internal/PutBlobsStrategyImpl.java | 10 +-- .../internal/BaseBlobIntegrationTest.java | 10 +-- .../BaseBlobStoreIntegrationTest.java | 7 +- .../TerremarkVCloudComputeService.java | 6 +- ...agIntoNameRunNodesAndAddToSetStrategy.java | 10 +-- .../suppliers/VCloudHardwareSupplier.java | 18 ++--- .../suppliers/VCloudImageSupplier.java | 18 ++--- .../functions/AllCatalogItemsInCatalog.java | 30 +++----- .../functions/AllCatalogsInOrg.java | 25 +++--- .../vcloud_0_8/functions/AllVDCsInOrg.java | 23 +++--- .../functions/OrgsForLocations.java | 26 ++----- .../vcloud_0_8/functions/OrgsForNames.java | 19 ++--- .../VAppTemplatesForCatalogItems.java | 22 ++---- .../VAppTemplatesForResourceEntities.java | 22 ++---- ...nitScriptStatusIsZeroThenReturnOutput.java | 15 ++-- .../compute/internal/BaseComputeService.java | 77 ++++++++----------- .../jclouds/compute/internal/UtilsImpl.java | 8 +- .../CreateNodesInGroupThenAddToSet.java | 4 +- ...sWithGroupEncodedIntoNameThenAddToSet.java | 29 +++---- .../config/StubComputeServiceAdapter.java | 18 ++--- .../jclouds/compute/util/ComputeUtils.java | 16 ++-- .../util/ConcurrentOpenSocketFinder.java | 11 ++- ...criptStatusIsZeroThenReturnOutputTest.java | 18 ++--- .../internal/BaseComputeServiceLiveTest.java | 4 +- .../util/ConcurrentOpenSocketFinderTest.java | 19 ++--- .../ApacheHCHttpCommandExecutorService.java | 6 +- .../config/EnterpriseConfigurationModule.java | 8 +- .../AsyncGaeHttpCommandExecutorService.java | 20 ++--- .../gae/GaeHttpCommandExecutorService.java | 5 +- ...yncGoogleAppEngineConfigurationModule.java | 4 +- .../CurrentRequestExecutorServiceModule.java | 8 +- .../GoogleAppEngineConfigurationModule.java | 10 +-- .../ssh/jsch/JschSshClientLiveTest.java | 6 +- .../abiquo/rest/internal/ExtendedUtils.java | 8 +- .../strategy/cloud/ListVirtualAppliances.java | 13 ++-- .../cloud/ListVirtualDatacenters.java | 12 +-- .../strategy/cloud/ListVirtualMachines.java | 13 ++-- .../ListVirtualMachineTemplates.java | 13 ++-- .../strategy/infrastructure/ListMachines.java | 17 ++-- .../ELBListLoadBalancersStrategy.java | 19 +++-- .../compute/JoyentCloudComputeService.java | 6 +- ...sWithGroupEncodedIntoNameThenAddToSet.java | 10 +-- .../BaseVirtualBoxClientLiveTest.java | 5 +- .../aws/ec2/compute/AWSEC2ComputeService.java | 6 +- .../strategy/AWSEC2ListNodesStrategy.java | 17 ++-- .../suppliers/AWSEC2ImageSupplier.java | 16 ++-- .../aws/s3/blobstore/AWSS3AsyncBlobStore.java | 6 +- .../ParallelMultipartUploadStrategy.java | 16 ++-- .../blobstore/AzureAsyncBlobStore.java | 24 +++--- .../compute/GleSYSComputeServiceAdapter.java | 18 ++--- .../gogrid/compute/GoGridComputeService.java | 6 +- .../HPCloudObjectStorageAsyncBlobStore.java | 15 ++-- 93 files changed, 684 insertions(+), 822 deletions(-) diff --git a/apis/atmos/src/main/java/org/jclouds/atmos/blobstore/AtmosAsyncBlobStore.java b/apis/atmos/src/main/java/org/jclouds/atmos/blobstore/AtmosAsyncBlobStore.java index 18c1b084be..8918e3bc5b 100644 --- a/apis/atmos/src/main/java/org/jclouds/atmos/blobstore/AtmosAsyncBlobStore.java +++ b/apis/atmos/src/main/java/org/jclouds/atmos/blobstore/AtmosAsyncBlobStore.java @@ -19,12 +19,12 @@ package org.jclouds.atmos.blobstore; import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.util.concurrent.Futures.transform; import static org.jclouds.atmos.options.PutOptions.Builder.publicRead; import java.net.URI; import java.util.Set; import java.util.concurrent.Callable; -import java.util.concurrent.ExecutorService; import javax.inject.Inject; import javax.inject.Named; @@ -56,7 +56,6 @@ import org.jclouds.blobstore.options.PutOptions; import org.jclouds.blobstore.strategy.internal.FetchBlobMetadata; import org.jclouds.blobstore.util.BlobUtils; import org.jclouds.collect.Memoized; -import org.jclouds.concurrent.Futures; import org.jclouds.crypto.Crypto; import org.jclouds.domain.Location; import org.jclouds.http.options.GetOptions; @@ -66,6 +65,7 @@ import com.google.common.base.Supplier; import com.google.common.cache.CacheLoader; import com.google.common.cache.LoadingCache; import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.ListeningExecutorService; /** * @author Adrian Cole @@ -86,14 +86,14 @@ public class AtmosAsyncBlobStore extends BaseAsyncBlobStore { @Inject AtmosAsyncBlobStore(BlobStoreContext context, BlobUtils blobUtils, - @Named(Constants.PROPERTY_USER_THREADS) ExecutorService service, Supplier defaultLocation, + @Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor, Supplier defaultLocation, @Memoized Supplier> locations, AtmosAsyncClient async, AtmosClient sync, ObjectToBlob object2Blob, ObjectToBlobMetadata object2BlobMd, BlobToObject blob2Object, BlobStoreListOptionsToListOptions container2ContainerListOptions, DirectoryEntryListToResourceMetadataList container2ResourceList, Crypto crypto, BlobToHttpGetOptions blob2ObjectGetOptions, Provider fetchBlobMetadataProvider, LoadingCache isPublic) { - super(context, blobUtils, service, defaultLocation, locations); + super(context, blobUtils, userExecutor, defaultLocation, locations); this.blob2ObjectGetOptions = checkNotNull(blob2ObjectGetOptions, "blob2ObjectGetOptions"); this.sync = checkNotNull(sync, "sync"); this.async = checkNotNull(async, "async"); @@ -113,12 +113,12 @@ public class AtmosAsyncBlobStore extends BaseAsyncBlobStore { */ @Override public ListenableFuture blobMetadata(String container, String key) { - return Futures.compose(async.headFile(container + "/" + key), new Function() { + return transform(async.headFile(container + "/" + key), new Function() { @Override public BlobMetadata apply(AtmosObject from) { return object2BlobMd.apply(from); } - }, service); + }, userExecutor); } /** @@ -128,13 +128,11 @@ public class AtmosAsyncBlobStore extends BaseAsyncBlobStore { */ @Override public ListenableFuture createContainerInLocation(Location location, String container) { - return Futures.compose(async.createDirectory(container), new Function() { - + return transform(async.createDirectory(container), new Function() { public Boolean apply(URI from) { return true; } - - }, service); + }, userExecutor); } /** @@ -142,13 +140,11 @@ public class AtmosAsyncBlobStore extends BaseAsyncBlobStore { */ @Override public ListenableFuture createDirectory(String container, String directory) { - return Futures.compose(async.createDirectory(container + "/" + directory), new Function() { - + return transform(async.createDirectory(container + "/" + directory), new Function() { public Void apply(URI from) { return null;// no etag } - - }, service); + }, userExecutor); } /** @@ -204,7 +200,7 @@ public class AtmosAsyncBlobStore extends BaseAsyncBlobStore { public ListenableFuture getBlob(String container, String key, org.jclouds.blobstore.options.GetOptions options) { GetOptions httpOptions = blob2ObjectGetOptions.apply(options); ListenableFuture returnVal = async.readFile(container + "/" + key, httpOptions); - return Futures.compose(returnVal, object2Blob, service); + return transform(returnVal, object2Blob, userExecutor); } /** @@ -212,7 +208,7 @@ public class AtmosAsyncBlobStore extends BaseAsyncBlobStore { */ @Override public ListenableFuture> list() { - return Futures.compose(async.listDirectories(), container2ResourceList, service); + return transform(async.listDirectories(), container2ResourceList, userExecutor); } /** @@ -224,10 +220,10 @@ public class AtmosAsyncBlobStore extends BaseAsyncBlobStore { container = AtmosUtils.adjustContainerIfDirOptionPresent(container, options); ListOptions nativeOptions = container2ContainerListOptions.apply(options); ListenableFuture> returnVal = async.listDirectory(container, nativeOptions); - ListenableFuture> list = Futures.compose(returnVal, container2ResourceList, - service); - return (ListenableFuture>) (options.isDetailed() ? Futures.compose(list, - fetchBlobMetadataProvider.get().setContainerName(container), service) : list); + ListenableFuture> list = transform(returnVal, container2ResourceList, + userExecutor); + return (ListenableFuture>) (options.isDetailed() ? transform(list, + fetchBlobMetadataProvider.get().setContainerName(container)) : list); } /** @@ -244,7 +240,7 @@ public class AtmosAsyncBlobStore extends BaseAsyncBlobStore { } catch (CacheLoader.InvalidCacheLoadException e) { // nulls not permitted } - return Futures.makeListenable(service.submit(new Callable() { + return userExecutor.submit(new Callable() { @Override public String call() throws Exception { @@ -255,7 +251,7 @@ public class AtmosAsyncBlobStore extends BaseAsyncBlobStore { public String toString() { return "putBlob(" + container + "," + blob.getMetadata().getName() + ")"; } - }), service); + }); } @@ -277,13 +273,13 @@ public class AtmosAsyncBlobStore extends BaseAsyncBlobStore { public ListenableFuture createContainerInLocation(Location location, String container, CreateContainerOptions options) { if (options.isPublicRead()) - return Futures.compose(async.createDirectory(container, publicRead()), new Function() { + return transform(async.createDirectory(container, publicRead()), new Function() { public Boolean apply(URI from) { return true; } - }, service); + }, userExecutor); return createContainerInLocation(location, container); } diff --git a/apis/atmos/src/main/java/org/jclouds/atmos/blobstore/strategy/FindMD5InUserMetadata.java b/apis/atmos/src/main/java/org/jclouds/atmos/blobstore/strategy/FindMD5InUserMetadata.java index 7b7a1766c5..c1e9758fed 100644 --- a/apis/atmos/src/main/java/org/jclouds/atmos/blobstore/strategy/FindMD5InUserMetadata.java +++ b/apis/atmos/src/main/java/org/jclouds/atmos/blobstore/strategy/FindMD5InUserMetadata.java @@ -26,11 +26,9 @@ import java.util.Arrays; import java.util.Map; import java.util.concurrent.BlockingQueue; import java.util.concurrent.ExecutionException; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Future; import java.util.concurrent.SynchronousQueue; -import java.util.concurrent.TimeoutException; import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; import javax.annotation.Resource; import javax.inject.Named; @@ -45,12 +43,12 @@ import org.jclouds.blobstore.internal.BlobRuntimeException; import org.jclouds.blobstore.options.ListContainerOptions; import org.jclouds.blobstore.strategy.ContainsValueInListStrategy; import org.jclouds.blobstore.strategy.ListBlobsInContainer; -import org.jclouds.concurrent.Futures; import org.jclouds.logging.Logger; import com.google.common.base.Throwables; import com.google.common.collect.Maps; import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.ListeningExecutorService; import com.google.inject.Inject; /** @@ -65,7 +63,7 @@ public class FindMD5InUserMetadata implements ContainsValueInListStrategy { protected final ObjectMD5 objectMD5; protected final ListBlobsInContainer getAllBlobMetadata; private final AtmosAsyncClient client; - private final ExecutorService userExecutor; + private final ListeningExecutorService userExecutor; /** * maximum duration of an blob Request */ @@ -74,7 +72,7 @@ public class FindMD5InUserMetadata implements ContainsValueInListStrategy { protected Long maxTime; @Inject - FindMD5InUserMetadata(@Named(Constants.PROPERTY_USER_THREADS) ExecutorService userExecutor, ObjectMD5 objectMD5, + FindMD5InUserMetadata(@Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor, ObjectMD5 objectMD5, ListBlobsInContainer getAllBlobMetadata, AtmosAsyncClient client) { this.objectMD5 = objectMD5; this.getAllBlobMetadata = getAllBlobMetadata; @@ -86,10 +84,9 @@ public class FindMD5InUserMetadata implements ContainsValueInListStrategy { public boolean execute(final String containerName, Object value, ListContainerOptions options) { final byte[] toSearch = objectMD5.apply(value); final BlockingQueue queue = new SynchronousQueue(); - Map> responses = Maps.newHashMap(); + Map> responses = Maps.newHashMap(); for (BlobMetadata md : getAllBlobMetadata.execute(containerName, options)) { - final ListenableFuture future = Futures.makeListenable( - client.headFile(containerName + "/" + md.getName()), userExecutor); + final ListenableFuture future = client.headFile(containerName + "/" + md.getName()); future.addListener(new Runnable() { public void run() { try { diff --git a/apis/atmos/src/test/java/org/jclouds/atmos/internal/StubAtmosAsyncClient.java b/apis/atmos/src/test/java/org/jclouds/atmos/internal/StubAtmosAsyncClient.java index c4bd2c02a4..5c8bb91bda 100644 --- a/apis/atmos/src/test/java/org/jclouds/atmos/internal/StubAtmosAsyncClient.java +++ b/apis/atmos/src/test/java/org/jclouds/atmos/internal/StubAtmosAsyncClient.java @@ -24,7 +24,6 @@ import static com.google.common.util.concurrent.Futures.immediateFuture; import java.net.URI; import java.util.concurrent.ExecutionException; -import java.util.concurrent.ExecutorService; import javax.inject.Inject; import javax.inject.Named; @@ -47,12 +46,13 @@ import org.jclouds.blobstore.LocalAsyncBlobStore; import org.jclouds.blobstore.domain.Blob; import org.jclouds.blobstore.domain.BlobMetadata; import org.jclouds.blobstore.functions.HttpGetOptionsListToGetOptions; -import org.jclouds.concurrent.Futures; import org.jclouds.http.options.GetOptions; import com.google.common.base.Function; import com.google.common.base.Throwables; +import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.ListeningExecutorService; /** * Implementation of {@link AtmosAsyncClient} which keeps all data in a local Map object. @@ -68,13 +68,13 @@ public class StubAtmosAsyncClient implements AtmosAsyncClient { private final BlobMetadataToObject blob2ObjectInfo; private final ListOptionsToBlobStoreListOptions container2ContainerListOptions; private final ResourceMetadataListToDirectoryEntryList resource2ObjectList; - private final ExecutorService service; + private final ListeningExecutorService userExecutor; @Inject private StubAtmosAsyncClient(LocalAsyncBlobStore blobStore, AtmosObject.Factory objectProvider, HttpGetOptionsListToGetOptions httpGetOptionsConverter, ObjectToBlob object2Blob, BlobToObject blob2Object, BlobMetadataToObject blob2ObjectInfo, ListOptionsToBlobStoreListOptions container2ContainerListOptions, - @Named(Constants.PROPERTY_USER_THREADS) ExecutorService service, + @Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor, ResourceMetadataListToDirectoryEntryList resource2ContainerList) { this.blobStore = blobStore; this.objectProvider = objectProvider; @@ -85,7 +85,7 @@ public class StubAtmosAsyncClient implements AtmosAsyncClient { this.container2ContainerListOptions = checkNotNull(container2ContainerListOptions, "container2ContainerListOptions"); this.resource2ObjectList = checkNotNull(resource2ContainerList, "resource2ContainerList"); - this.service = service; + this.userExecutor = userExecutor; } @Override @@ -99,7 +99,7 @@ public class StubAtmosAsyncClient implements AtmosAsyncClient { container = directoryName; path = null; } - return Futures.compose(blobStore.createContainerInLocation(null, container), new Function() { + return Futures.transform(blobStore.createContainerInLocation(null, container), new Function() { public URI apply(Boolean from) { if (path != null) { @@ -109,7 +109,7 @@ public class StubAtmosAsyncClient implements AtmosAsyncClient { return URI.create("http://stub/containers/" + container); } - }, service); + }, userExecutor); } @Override @@ -124,27 +124,27 @@ public class StubAtmosAsyncClient implements AtmosAsyncClient { object.getContentMetadata().setName(path + "/" + file); } Blob blob = object2Blob.apply(object); - return Futures.compose(blobStore.putBlob(container, blob), new Function() { + return Futures.transform(blobStore.putBlob(container, blob), new Function() { public URI apply(String from) { return URI.create(uri); } - }, service); + }, userExecutor); } @Override public ListenableFuture deletePath(String path) { if (path.indexOf('/') == path.length() - 1) { // chop off the trailing slash - return Futures.compose(blobStore.deleteContainerIfEmpty(path.substring(0, path.length() - 1)), + return Futures.transform(blobStore.deleteContainerIfEmpty(path.substring(0, path.length() - 1)), new Function() { public Void apply(Boolean from) { return null; } - }, service); + }, userExecutor); } else { String container = path.substring(0, path.indexOf('/')); path = path.substring(path.indexOf('/') + 1); @@ -164,11 +164,11 @@ public class StubAtmosAsyncClient implements AtmosAsyncClient { else { String container = path.substring(0, path.indexOf('/')); path = path.substring(path.indexOf('/') + 1); - return Futures.compose(blobStore.blobMetadata(container, path), new Function() { + return Futures.transform(blobStore.blobMetadata(container, path), new Function() { public UserMetadata apply(BlobMetadata from) { return blob2ObjectInfo.apply(from).getUserMetadata(); } - }, service); + }, userExecutor); } } @@ -177,7 +177,7 @@ public class StubAtmosAsyncClient implements AtmosAsyncClient { String container = path.substring(0, path.indexOf('/')); path = path.substring(path.indexOf('/') + 1); try { - return Futures.compose(blobStore.getBlob(container, path), blob2Object, service); + return Futures.transform(blobStore.getBlob(container, path), blob2Object, userExecutor); } catch (Exception e) { return immediateFailedFuture(Throwables.getRootCause(e)); } @@ -187,7 +187,7 @@ public class StubAtmosAsyncClient implements AtmosAsyncClient { public ListenableFuture> listDirectories(ListOptions... optionsList) { // org.jclouds.blobstore.options.ListOptions options = container2ContainerListOptions // .apply(optionsList); - return Futures.compose(blobStore.list(), resource2ObjectList, service); + return Futures.transform(blobStore.list(), resource2ObjectList, userExecutor); } @Override @@ -201,7 +201,7 @@ public class StubAtmosAsyncClient implements AtmosAsyncClient { if (!path.equals("")) options.inDirectory(path); } - return Futures.compose(blobStore.list(container, options), resource2ObjectList, service); + return Futures.transform(blobStore.list(container, options), resource2ObjectList, userExecutor); } @Override @@ -232,7 +232,7 @@ public class StubAtmosAsyncClient implements AtmosAsyncClient { String container = path.substring(0, path.indexOf('/')); String blobName = path.substring(path.indexOf('/') + 1); org.jclouds.blobstore.options.GetOptions getOptions = httpGetOptionsConverter.apply(options); - return Futures.compose(blobStore.getBlob(container, blobName, getOptions), blob2Object, service); + return Futures.transform(blobStore.getBlob(container, blobName, getOptions), blob2Object, userExecutor); } @Override diff --git a/apis/cloudfiles/src/main/java/org/jclouds/cloudfiles/blobstore/CloudFilesAsyncBlobStore.java b/apis/cloudfiles/src/main/java/org/jclouds/cloudfiles/blobstore/CloudFilesAsyncBlobStore.java index 5578c89579..bdbd715fe7 100644 --- a/apis/cloudfiles/src/main/java/org/jclouds/cloudfiles/blobstore/CloudFilesAsyncBlobStore.java +++ b/apis/cloudfiles/src/main/java/org/jclouds/cloudfiles/blobstore/CloudFilesAsyncBlobStore.java @@ -18,8 +18,9 @@ */ package org.jclouds.cloudfiles.blobstore; +import static com.google.common.util.concurrent.Futures.transform; + import java.util.Set; -import java.util.concurrent.ExecutorService; import javax.inject.Inject; import javax.inject.Named; @@ -36,7 +37,6 @@ import org.jclouds.cloudfiles.CloudFilesAsyncClient; import org.jclouds.cloudfiles.CloudFilesClient; import org.jclouds.cloudfiles.blobstore.functions.EnableCDNAndCache; import org.jclouds.collect.Memoized; -import org.jclouds.concurrent.Futures; import org.jclouds.domain.Location; import org.jclouds.openstack.swift.blobstore.SwiftAsyncBlobStore; import org.jclouds.openstack.swift.blobstore.functions.BlobStoreListContainerOptionsToListContainerOptions; @@ -45,11 +45,12 @@ import org.jclouds.openstack.swift.blobstore.functions.ContainerToResourceList; import org.jclouds.openstack.swift.blobstore.functions.ContainerToResourceMetadata; import org.jclouds.openstack.swift.blobstore.functions.ObjectToBlob; import org.jclouds.openstack.swift.blobstore.functions.ObjectToBlobMetadata; +import org.jclouds.openstack.swift.blobstore.strategy.internal.AsyncMultipartUploadStrategy; import com.google.common.base.Function; import com.google.common.base.Supplier; import com.google.common.util.concurrent.ListenableFuture; -import org.jclouds.openstack.swift.blobstore.strategy.internal.AsyncMultipartUploadStrategy; +import com.google.common.util.concurrent.ListeningExecutorService; /** * @@ -61,7 +62,7 @@ public class CloudFilesAsyncBlobStore extends SwiftAsyncBlobStore { @Inject protected CloudFilesAsyncBlobStore(BlobStoreContext context, BlobUtils blobUtils, - @Named(Constants.PROPERTY_USER_THREADS) ExecutorService service, Supplier defaultLocation, + @Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor, Supplier defaultLocation, @Memoized Supplier> locations, CloudFilesClient sync, CloudFilesAsyncClient async, ContainerToResourceMetadata container2ResourceMd, BlobStoreListContainerOptionsToListContainerOptions container2ContainerListOptions, @@ -69,7 +70,7 @@ public class CloudFilesAsyncBlobStore extends SwiftAsyncBlobStore { ObjectToBlobMetadata object2BlobMd, BlobToHttpGetOptions blob2ObjectGetOptions, Provider fetchBlobMetadataProvider, EnableCDNAndCache enableCDNAndCache, Provider multipartUploadStrategy) { - super(context, blobUtils, service, defaultLocation, locations, sync, async, container2ResourceMd, + super(context, blobUtils, userExecutor, defaultLocation, locations, sync, async, container2ResourceMd, container2ContainerListOptions, container2ResourceList, object2Blob, blob2Object, object2BlobMd, blob2ObjectGetOptions, fetchBlobMetadataProvider, multipartUploadStrategy); this.enableCDNAndCache = enableCDNAndCache; @@ -81,7 +82,7 @@ public class CloudFilesAsyncBlobStore extends SwiftAsyncBlobStore { ListenableFuture returnVal = createContainerInLocation(location, container); if (options.isPublicRead()) - return Futures.compose(createContainerInLocation(location, container), new Function() { + return transform(createContainerInLocation(location, container), new Function() { @Override public Boolean apply(Boolean input) { @@ -91,7 +92,7 @@ public class CloudFilesAsyncBlobStore extends SwiftAsyncBlobStore { return false; } - }, service); + }, userExecutor); return returnVal; } } diff --git a/apis/cloudservers/src/main/java/org/jclouds/cloudservers/compute/extensions/CloudServersImageExtension.java b/apis/cloudservers/src/main/java/org/jclouds/cloudservers/compute/extensions/CloudServersImageExtension.java index 24f4e4e873..603c2ab125 100644 --- a/apis/cloudservers/src/main/java/org/jclouds/cloudservers/compute/extensions/CloudServersImageExtension.java +++ b/apis/cloudservers/src/main/java/org/jclouds/cloudservers/compute/extensions/CloudServersImageExtension.java @@ -24,7 +24,6 @@ import static com.google.common.base.Preconditions.checkState; import java.util.NoSuchElementException; import java.util.concurrent.Callable; -import java.util.concurrent.ExecutorService; import java.util.concurrent.TimeUnit; import javax.annotation.Resource; @@ -41,12 +40,12 @@ import org.jclouds.compute.domain.ImageTemplate; import org.jclouds.compute.domain.ImageTemplateBuilder; import org.jclouds.compute.extensions.ImageExtension; import org.jclouds.compute.reference.ComputeServiceConstants; -import org.jclouds.concurrent.Futures; import org.jclouds.logging.Logger; import org.jclouds.predicates.PredicateWithResult; import org.jclouds.predicates.Retryables; import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.ListeningExecutorService; /** * CloudServers implementation of {@link ImageExtension} @@ -62,7 +61,7 @@ public class CloudServersImageExtension implements ImageExtension { protected Logger logger = Logger.NULL; private final CloudServersClient client; - private final ExecutorService executor; + private final ListeningExecutorService userExecutor; private final PredicateWithResult imageAvailablePredicate; @com.google.inject.Inject(optional = true) @Named("IMAGE_MAX_WAIT") @@ -73,11 +72,11 @@ public class CloudServersImageExtension implements ImageExtension { @Inject public CloudServersImageExtension(CloudServersClient client, - @Named(Constants.PROPERTY_USER_THREADS) ExecutorService userThreads, + @Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor, PredicateWithResult imageAvailablePredicate) { - this.client = checkNotNull(client); - this.executor = userThreads; - this.imageAvailablePredicate = imageAvailablePredicate; + this.client = checkNotNull(client, "client"); + this.userExecutor = checkNotNull(userExecutor, "userExecutor"); + this.imageAvailablePredicate = checkNotNull(imageAvailablePredicate, "imageAvailablePredicate"); } @Override @@ -96,14 +95,14 @@ public class CloudServersImageExtension implements ImageExtension { CloneImageTemplate cloneTemplate = (CloneImageTemplate) template; final org.jclouds.cloudservers.domain.Image image = client.createImageFromServer(cloneTemplate.getName(), Integer.parseInt(cloneTemplate.getSourceNodeId())); - return Futures.makeListenable(executor.submit(new Callable() { + return userExecutor.submit(new Callable() { @Override public Image call() throws Exception { return Retryables.retryGettingResultOrFailing(imageAvailablePredicate, image.getId(), maxWait, waitPeriod, TimeUnit.SECONDS, "Image was not created within the time limit, Giving up! [Limit: " + maxWait + " secs.]"); } - }), executor); + }); } diff --git a/apis/cloudsigma/src/main/java/org/jclouds/cloudsigma/compute/CloudSigmaComputeServiceAdapter.java b/apis/cloudsigma/src/main/java/org/jclouds/cloudsigma/compute/CloudSigmaComputeServiceAdapter.java index 846fa9aadf..ea4c1372a9 100644 --- a/apis/cloudsigma/src/main/java/org/jclouds/cloudsigma/compute/CloudSigmaComputeServiceAdapter.java +++ b/apis/cloudsigma/src/main/java/org/jclouds/cloudsigma/compute/CloudSigmaComputeServiceAdapter.java @@ -22,9 +22,6 @@ import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; import static org.jclouds.concurrent.FutureIterables.transformParallel; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Future; - import javax.annotation.Resource; import javax.inject.Inject; import javax.inject.Named; @@ -66,6 +63,8 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet.Builder; import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.ListeningExecutorService; import com.google.common.util.concurrent.UncheckedExecutionException; /** @@ -89,7 +88,7 @@ public class CloudSigmaComputeServiceAdapter implements private final Predicate driveNotClaimed; private final String defaultVncPassword; private final LoadingCache cache; - private final ExecutorService executor; + private final ListeningExecutorService userExecutor; @Resource @Named(ComputeServiceConstants.COMPUTE_LOGGER) @@ -98,13 +97,13 @@ public class CloudSigmaComputeServiceAdapter implements @Inject public CloudSigmaComputeServiceAdapter(CloudSigmaClient client, Predicate driveNotClaimed, @Named(CloudSigmaConstants.PROPERTY_VNC_PASSWORD) String defaultVncPassword, - LoadingCache cache, @Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor) { + LoadingCache cache, @Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor) { this.client = checkNotNull(client, "client"); this.driveNotClaimed = checkNotNull(driveNotClaimed, "driveNotClaimed"); this.defaultVncPassword = checkNotNull(defaultVncPassword, "defaultVncPassword"); checkArgument(defaultVncPassword.length() <= 8, "vnc passwords should be less that 8 characters!"); this.cache = checkNotNull(cache, "cache"); - this.executor = checkNotNull(executor, "executor"); + this.userExecutor = checkNotNull(userExecutor, "userExecutor"); } @Override @@ -171,10 +170,10 @@ public class CloudSigmaComputeServiceAdapter implements @Override public Iterable listImages() { return FluentIterable.from(transformParallel(client.listStandardDrives(), - new Function>() { + new Function>() { @Override - public Future apply(String input) { + public ListenableFuture apply(String input) { try { return Futures.immediateFuture(cache.getUnchecked(input)); } catch (CacheLoader.InvalidCacheLoadException e) { @@ -189,7 +188,7 @@ public class CloudSigmaComputeServiceAdapter implements public String toString() { return "seedDriveCache()"; } - }, executor, null, logger, "drives")).filter(PREINSTALLED_DISK); + }, userExecutor, null, logger, "drives")).filter(PREINSTALLED_DISK); } @SuppressWarnings("unchecked") diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/compute/EC2ComputeService.java b/apis/ec2/src/main/java/org/jclouds/ec2/compute/EC2ComputeService.java index d2fa117e09..2df07a9f4a 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/compute/EC2ComputeService.java +++ b/apis/ec2/src/main/java/org/jclouds/ec2/compute/EC2ComputeService.java @@ -35,7 +35,6 @@ import java.util.Map; import java.util.Map.Entry; import java.util.Set; import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.ExecutorService; import java.util.concurrent.atomic.AtomicReference; import javax.inject.Named; @@ -96,6 +95,7 @@ import com.google.common.collect.ImmutableMultimap.Builder; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Maps; import com.google.common.collect.Multimap; +import com.google.common.util.concurrent.ListeningExecutorService; import com.google.inject.Inject; /** @@ -124,7 +124,7 @@ public class EC2ComputeService extends BaseComputeService { InitializeRunScriptOnNodeOrPlaceInBadMap.Factory initScriptRunnerFactory, RunScriptOnNode.Factory runScriptOnNodeFactory, InitAdminAccess initAdminAccess, PersistNodeCredentials persistNodeCredentials, Timeouts timeouts, - @Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor, EC2Client client, + @Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor, EC2Client client, ConcurrentMap credentialsMap, @Named("SECURITY") LoadingCache securityGroupMap, Optional imageExtension, GroupNamingConvention.Factory namingConvention, @@ -133,7 +133,7 @@ public class EC2ComputeService extends BaseComputeService { getNodeMetadataStrategy, runNodesAndAddToSetStrategy, rebootNodeStrategy, destroyNodeStrategy, startNodeStrategy, stopNodeStrategy, templateBuilderProvider, templateOptionsProvider, nodeRunning, nodeTerminated, nodeSuspended, initScriptRunnerFactory, initAdminAccess, runScriptOnNodeFactory, - persistNodeCredentials, timeouts, executor, imageExtension); + persistNodeCredentials, timeouts, userExecutor, imageExtension); this.client = client; this.credentialsMap = credentialsMap; this.securityGroupMap = securityGroupMap; diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/compute/extensions/EC2ImageExtension.java b/apis/ec2/src/main/java/org/jclouds/ec2/compute/extensions/EC2ImageExtension.java index 00beefeea7..5f832a7522 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/compute/extensions/EC2ImageExtension.java +++ b/apis/ec2/src/main/java/org/jclouds/ec2/compute/extensions/EC2ImageExtension.java @@ -24,7 +24,6 @@ import static com.google.common.base.Preconditions.checkState; import java.util.NoSuchElementException; import java.util.concurrent.Callable; -import java.util.concurrent.ExecutorService; import java.util.concurrent.TimeUnit; import javax.annotation.Resource; @@ -39,7 +38,6 @@ import org.jclouds.compute.domain.ImageTemplate; import org.jclouds.compute.domain.ImageTemplateBuilder; import org.jclouds.compute.extensions.ImageExtension; import org.jclouds.compute.reference.ComputeServiceConstants; -import org.jclouds.concurrent.Futures; import org.jclouds.ec2.EC2Client; import org.jclouds.ec2.domain.Reservation; import org.jclouds.ec2.domain.RunningInstance; @@ -50,6 +48,7 @@ import org.jclouds.predicates.Retryables; import com.google.common.collect.Iterables; import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.ListeningExecutorService; /** * EC2 implementation of {@link ImageExtension} please note that {@link #createImage(ImageTemplate)} @@ -64,7 +63,7 @@ public class EC2ImageExtension implements ImageExtension { @Named(ComputeServiceConstants.COMPUTE_LOGGER) protected Logger logger = Logger.NULL; private final EC2Client ec2Client; - private final ExecutorService executor; + private final ListeningExecutorService userExecutor; private final PredicateWithResult imageReadyPredicate; @com.google.inject.Inject(optional = true) @Named("IMAGE_MAX_WAIT") @@ -74,10 +73,10 @@ public class EC2ImageExtension implements ImageExtension { private long waitPeriod = 1; @Inject - public EC2ImageExtension(EC2Client ec2Client, @Named(Constants.PROPERTY_USER_THREADS) ExecutorService userThreads, + public EC2ImageExtension(EC2Client ec2Client, @Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor, PredicateWithResult imageReadyPredicate) { this.ec2Client = checkNotNull(ec2Client); - this.executor = checkNotNull(userThreads); + this.userExecutor = checkNotNull(userExecutor); this.imageReadyPredicate = imageReadyPredicate; } @@ -105,14 +104,14 @@ public class EC2ImageExtension implements ImageExtension { final String imageId = ec2Client.getAMIServices().createImageInRegion(region, cloneTemplate.getName(), instanceId, CreateImageOptions.NONE); - return Futures.makeListenable(executor.submit(new Callable() { + return userExecutor.submit(new Callable() { @Override public Image call() throws Exception { return Retryables.retryGettingResultOrFailing(imageReadyPredicate, region + "/" + imageId, maxWait, waitPeriod, TimeUnit.SECONDS, "Image was not created within the time limit, Giving up! [Limit: " + maxWait + " secs.]"); } - }), executor); + }); } @Override diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/compute/strategy/DescribeImagesParallel.java b/apis/ec2/src/main/java/org/jclouds/ec2/compute/strategy/DescribeImagesParallel.java index f080408875..1ce02fe33e 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/compute/strategy/DescribeImagesParallel.java +++ b/apis/ec2/src/main/java/org/jclouds/ec2/compute/strategy/DescribeImagesParallel.java @@ -23,8 +23,6 @@ import static org.jclouds.concurrent.FutureIterables.transformParallel; import java.util.Map.Entry; import java.util.Set; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Future; import javax.annotation.Resource; import javax.inject.Inject; @@ -38,6 +36,8 @@ import org.jclouds.ec2.options.DescribeImagesOptions; import org.jclouds.logging.Logger; import com.google.common.base.Function; +import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.ListeningExecutorService; /** * @@ -51,13 +51,12 @@ public class DescribeImagesParallel implements protected Logger logger = Logger.NULL; protected final EC2AsyncClient async; - final ExecutorService executor; + final ListeningExecutorService userExecutor; @Inject - public DescribeImagesParallel(EC2AsyncClient async, @Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor) { - super(); + public DescribeImagesParallel(EC2AsyncClient async, @Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor) { this.async = async; - this.executor = executor; + this.userExecutor = userExecutor; } @Override @@ -65,15 +64,11 @@ public class DescribeImagesParallel implements Iterable> queries) { return concat(transformParallel( queries, - new Function, Future>>() { - - @Override - public Future> apply( + new Function, ListenableFuture>>() { + public ListenableFuture> apply( Entry from) { return async.getAMIServices().describeImagesInRegion(from.getKey(), from.getValue()); } - - }, executor, null, logger, "amis")); + }, userExecutor, null, logger, "amis")); } - } diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/compute/strategy/EC2CreateNodesInGroupThenAddToSet.java b/apis/ec2/src/main/java/org/jclouds/ec2/compute/strategy/EC2CreateNodesInGroupThenAddToSet.java index fe9d2a08f2..804a148526 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/compute/strategy/EC2CreateNodesInGroupThenAddToSet.java +++ b/apis/ec2/src/main/java/org/jclouds/ec2/compute/strategy/EC2CreateNodesInGroupThenAddToSet.java @@ -30,7 +30,6 @@ import static org.jclouds.ec2.compute.util.EC2ComputeUtils.getZoneFromLocationOr import java.util.Map; import java.util.Set; -import java.util.concurrent.Future; import java.util.concurrent.atomic.AtomicReference; import javax.annotation.Resource; @@ -65,6 +64,7 @@ import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Maps; import com.google.common.collect.Multimap; +import com.google.common.util.concurrent.ListenableFuture; /** * creates futures that correlate to @@ -129,7 +129,7 @@ public class EC2CreateNodesInGroupThenAddToSet implements CreateNodesInGroupThen }; @Override - public Map> execute(String group, int count, Template template, Set goodNodes, + public Map> execute(String group, int count, Template template, Set goodNodes, Map badNodes, Multimap customizationResponses) { Template mutableTemplate = template.clone(); diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/compute/strategy/EC2ListNodesStrategy.java b/apis/ec2/src/main/java/org/jclouds/ec2/compute/strategy/EC2ListNodesStrategy.java index a805e47e3c..973eec8c47 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/compute/strategy/EC2ListNodesStrategy.java +++ b/apis/ec2/src/main/java/org/jclouds/ec2/compute/strategy/EC2ListNodesStrategy.java @@ -27,8 +27,6 @@ import static com.google.common.collect.Iterables.transform; import static org.jclouds.concurrent.FutureIterables.transformParallel; import java.util.Set; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Future; import javax.annotation.Resource; import javax.inject.Named; @@ -50,6 +48,8 @@ import com.google.common.base.Function; import com.google.common.base.Predicate; import com.google.common.base.Supplier; import com.google.common.collect.ImmutableSet; +import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.ListeningExecutorService; import com.google.inject.Inject; /** @@ -70,16 +70,16 @@ public class EC2ListNodesStrategy implements ListNodesStrategy { protected final EC2AsyncClient client; protected final Supplier> regions; protected final Function runningInstanceToNodeMetadata; - protected final ExecutorService executor; + protected final ListeningExecutorService userExecutor; @Inject protected EC2ListNodesStrategy(EC2AsyncClient client, @Region Supplier> regions, Function runningInstanceToNodeMetadata, - @Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor) { + @Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor) { this.client = checkNotNull(client, "client"); this.regions = checkNotNull(regions, "regions"); this.runningInstanceToNodeMetadata = checkNotNull(runningInstanceToNodeMetadata, "runningInstanceToNodeMetadata"); - this.executor = checkNotNull(executor, "executor"); + this.userExecutor = checkNotNull(userExecutor, "userExecutor"); } @Override @@ -97,21 +97,14 @@ public class EC2ListNodesStrategy implements ListNodesStrategy { protected Iterable pollRunningInstances() { Iterable>> reservations = transformParallel( - regions.get(), new Function>>>() { + regions.get(), new Function>>>() { @Override - public Future>> apply(String from) { - // see http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7126754 - return castToSpecificTypedFuture(client.getInstanceServices().describeInstancesInRegion(from)); + public ListenableFuture>> apply(String from) { + return client.getInstanceServices().describeInstancesInRegion(from); } - }, executor, maxTime, logger, "reservations"); - + }, userExecutor, maxTime, logger, "reservations"); return concat(concat(reservations)); } - - @SuppressWarnings("unchecked") - private static Future castToSpecificTypedFuture(Future input) { - return (Future) input; - } } diff --git a/apis/elasticstack/src/main/java/org/jclouds/elasticstack/compute/ElasticStackComputeServiceAdapter.java b/apis/elasticstack/src/main/java/org/jclouds/elasticstack/compute/ElasticStackComputeServiceAdapter.java index a3d57d328e..71283c3d76 100644 --- a/apis/elasticstack/src/main/java/org/jclouds/elasticstack/compute/ElasticStackComputeServiceAdapter.java +++ b/apis/elasticstack/src/main/java/org/jclouds/elasticstack/compute/ElasticStackComputeServiceAdapter.java @@ -25,8 +25,6 @@ import static org.jclouds.concurrent.FutureIterables.transformParallel; import static org.jclouds.elasticstack.util.Servers.small; import java.util.Map; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Future; import javax.annotation.Resource; import javax.inject.Inject; @@ -67,6 +65,8 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet.Builder; import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.ListeningExecutorService; import com.google.common.util.concurrent.UncheckedExecutionException; /** @@ -82,7 +82,7 @@ public class ElasticStackComputeServiceAdapter implements private final Map preinstalledImages; private final LoadingCache cache; private final String defaultVncPassword; - private final ExecutorService executor; + private final ListeningExecutorService userExecutor; @Resource @Named(ComputeServiceConstants.COMPUTE_LOGGER) @@ -92,14 +92,14 @@ public class ElasticStackComputeServiceAdapter implements public ElasticStackComputeServiceAdapter(ElasticStackClient client, Predicate driveNotClaimed, Map preinstalledImages, LoadingCache cache, @Named(ElasticStackConstants.PROPERTY_VNC_PASSWORD) String defaultVncPassword, - @Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor) { + @Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor) { this.client = checkNotNull(client, "client"); this.driveNotClaimed = checkNotNull(driveNotClaimed, "driveNotClaimed"); this.preinstalledImages = checkNotNull(preinstalledImages, "preinstalledImages"); this.cache = checkNotNull(cache, "cache"); this.defaultVncPassword = checkNotNull(defaultVncPassword, "defaultVncPassword"); checkArgument(defaultVncPassword.length() <= 8, "vnc passwords should be less that 8 characters!"); - this.executor = checkNotNull(executor, "executor"); + this.userExecutor = checkNotNull(userExecutor, "userExecutor"); } @Override @@ -164,10 +164,10 @@ public class ElasticStackComputeServiceAdapter implements @Override public Iterable listImages() { return FluentIterable.from(transformParallel(preinstalledImages.keySet(), - new Function>() { + new Function>() { @Override - public Future apply(String input) { + public ListenableFuture apply(String input) { try { return Futures.immediateFuture(cache.getUnchecked(input)); } catch (CacheLoader.InvalidCacheLoadException e) { @@ -183,7 +183,7 @@ public class ElasticStackComputeServiceAdapter implements return "seedDriveCache()"; } - }, executor, null, logger, "drives")).filter(notNull()); + }, userExecutor, null, logger, "drives")).filter(notNull()); } @SuppressWarnings("unchecked") diff --git a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/NovaComputeService.java b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/NovaComputeService.java index d219d728f8..c98c711b58 100644 --- a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/NovaComputeService.java +++ b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/NovaComputeService.java @@ -25,7 +25,6 @@ import static org.jclouds.openstack.nova.v2_0.predicates.KeyPairPredicates.nameM import java.util.Map; import java.util.Set; -import java.util.concurrent.ExecutorService; import java.util.concurrent.atomic.AtomicReference; import javax.inject.Inject; @@ -77,6 +76,7 @@ import com.google.common.cache.LoadingCache; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Iterables; import com.google.common.collect.Multimap; +import com.google.common.util.concurrent.ListeningExecutorService; /** * @author Adrian Cole @@ -104,7 +104,7 @@ public class NovaComputeService extends BaseComputeService { InitializeRunScriptOnNodeOrPlaceInBadMap.Factory initScriptRunnerFactory, RunScriptOnNode.Factory runScriptOnNodeFactory, InitAdminAccess initAdminAccess, PersistNodeCredentials persistNodeCredentials, Timeouts timeouts, - @Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor, NovaApi novaApi, + @Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor, NovaApi novaApi, LoadingCache securityGroupMap, LoadingCache keyPairCache, Function, Multimap> orphanedGroupsByZoneId, @@ -113,7 +113,7 @@ public class NovaComputeService extends BaseComputeService { getNodeMetadataStrategy, runNodesAndAddToSetStrategy, rebootNodeStrategy, destroyNodeStrategy, startNodeStrategy, stopNodeStrategy, templateBuilderProvider, templateOptionsProvider, nodeRunning, nodeTerminated, nodeSuspended, initScriptRunnerFactory, initAdminAccess, runScriptOnNodeFactory, - persistNodeCredentials, timeouts, executor, imageExtension); + persistNodeCredentials, timeouts, userExecutor, imageExtension); this.novaApi = checkNotNull(novaApi, "novaApi"); this.securityGroupMap = checkNotNull(securityGroupMap, "securityGroupMap"); this.keyPairCache = checkNotNull(keyPairCache, "keyPairCache"); diff --git a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/extensions/NovaImageExtension.java b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/extensions/NovaImageExtension.java index 7670d54925..69d1a38708 100644 --- a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/extensions/NovaImageExtension.java +++ b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/extensions/NovaImageExtension.java @@ -24,7 +24,6 @@ import static com.google.common.base.Preconditions.checkState; import java.util.NoSuchElementException; import java.util.concurrent.Callable; -import java.util.concurrent.ExecutorService; import java.util.concurrent.TimeUnit; import javax.annotation.Resource; @@ -39,7 +38,6 @@ import org.jclouds.compute.domain.ImageTemplate; import org.jclouds.compute.domain.ImageTemplateBuilder; import org.jclouds.compute.extensions.ImageExtension; import org.jclouds.compute.reference.ComputeServiceConstants; -import org.jclouds.concurrent.Futures; import org.jclouds.logging.Logger; import org.jclouds.openstack.nova.v2_0.NovaApi; import org.jclouds.openstack.nova.v2_0.domain.Server; @@ -48,6 +46,7 @@ import org.jclouds.predicates.PredicateWithResult; import org.jclouds.predicates.Retryables; import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.ListeningExecutorService; /** * Nova implementation of {@link ImageExtension} @@ -63,7 +62,7 @@ public class NovaImageExtension implements ImageExtension { protected Logger logger = Logger.NULL; private final NovaApi novaApi; - private final ExecutorService executor; + private final ListeningExecutorService userExecutor; @com.google.inject.Inject(optional = true) @Named("IMAGE_MAX_WAIT") private long maxWait = 3600; @@ -74,10 +73,10 @@ public class NovaImageExtension implements ImageExtension { @Inject public NovaImageExtension(NovaApi novaApi, - @Named(Constants.PROPERTY_USER_THREADS) ExecutorService userThreads, + @Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor, PredicateWithResult imageReadyPredicate) { this.novaApi = checkNotNull(novaApi); - this.executor = userThreads; + this.userExecutor = userExecutor; this.imageReadyPredicate = imageReadyPredicate; } @@ -105,14 +104,14 @@ public class NovaImageExtension implements ImageExtension { logger.info(">> Registered new Image %s, waiting for it to become available.", newImageId); - return Futures.makeListenable(executor.submit(new Callable() { + return userExecutor.submit(new Callable() { @Override public Image call() throws Exception { return Retryables.retryGettingResultOrFailing(imageReadyPredicate, targetImageZoneAndId, maxWait, waitPeriod, TimeUnit.SECONDS, "Image was not created within the time limit, Giving up! [Limit: " + maxWait + " secs.]"); } - }), executor); + }); } @Override diff --git a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/strategy/ApplyNovaTemplateOptionsCreateNodesWithGroupEncodedIntoNameThenAddToSet.java b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/strategy/ApplyNovaTemplateOptionsCreateNodesWithGroupEncodedIntoNameThenAddToSet.java index 85fd629f26..71024a7efc 100644 --- a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/strategy/ApplyNovaTemplateOptionsCreateNodesWithGroupEncodedIntoNameThenAddToSet.java +++ b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/strategy/ApplyNovaTemplateOptionsCreateNodesWithGroupEncodedIntoNameThenAddToSet.java @@ -26,8 +26,6 @@ import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.ExecutionException; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Future; import java.util.concurrent.atomic.AtomicReference; import javax.inject.Inject; @@ -43,7 +41,6 @@ import org.jclouds.compute.strategy.CreateNodeWithGroupEncodedIntoName; import org.jclouds.compute.strategy.CustomizeNodeAndAddToGoodMapOrPutExceptionIntoBadMap; import org.jclouds.compute.strategy.ListNodesStrategy; import org.jclouds.compute.strategy.impl.CreateNodesWithGroupEncodedIntoNameThenAddToSet; -import org.jclouds.concurrent.Futures; import org.jclouds.openstack.nova.v2_0.NovaApi; import org.jclouds.openstack.nova.v2_0.compute.functions.AllocateAndAddFloatingIpToNode; import org.jclouds.openstack.nova.v2_0.compute.options.NovaTemplateOptions; @@ -56,6 +53,9 @@ import com.google.common.base.Throwables; import com.google.common.cache.LoadingCache; import com.google.common.collect.Multimap; import com.google.common.primitives.Ints; +import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.ListeningExecutorService; /** * @@ -76,11 +76,11 @@ public class ApplyNovaTemplateOptionsCreateNodesWithGroupEncodedIntoNameThenAddT ListNodesStrategy listNodesStrategy, GroupNamingConvention.Factory namingConvention, CustomizeNodeAndAddToGoodMapOrPutExceptionIntoBadMap.Factory customizeNodeAndAddToGoodMapOrPutExceptionIntoBadMapFactory, - @Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor, + @Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor, AllocateAndAddFloatingIpToNode createAndAddFloatingIpToNode, LoadingCache securityGroupCache, LoadingCache keyPairCache, NovaApi novaApi) { - super(addNodeWithTagStrategy, listNodesStrategy, namingConvention, executor, + super(addNodeWithTagStrategy, listNodesStrategy, namingConvention, userExecutor, customizeNodeAndAddToGoodMapOrPutExceptionIntoBadMapFactory); this.securityGroupCache = checkNotNull(securityGroupCache, "securityGroupCache"); this.keyPairCache = checkNotNull(keyPairCache, "keyPairCache"); @@ -90,7 +90,7 @@ public class ApplyNovaTemplateOptionsCreateNodesWithGroupEncodedIntoNameThenAddT } @Override - public Map> execute(String group, int count, Template template, Set goodNodes, + public Map> execute(String group, int count, Template template, Set goodNodes, Map badNodes, Multimap customizationResponses) { Template mutableTemplate = template.clone(); @@ -149,14 +149,14 @@ public class ApplyNovaTemplateOptionsCreateNodesWithGroupEncodedIntoNameThenAddT } @Override - protected Future> createNodeInGroupWithNameAndTemplate(String group, + protected ListenableFuture> createNodeInGroupWithNameAndTemplate(String group, final String name, Template template) { - Future> future = super.createNodeInGroupWithNameAndTemplate(group, name, template); + ListenableFuture> future = super.createNodeInGroupWithNameAndTemplate(group, name, template); NovaTemplateOptions templateOptions = NovaTemplateOptions.class.cast(template.getOptions()); if (templateOptions.shouldAutoAssignFloatingIp()) { - return Futures.compose(future, createAndAddFloatingIpToNode, executor); + return Futures.transform(future, createAndAddFloatingIpToNode, userExecutor); } else { return future; } diff --git a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/loadbalancer/strategy/CloudLoadBalancersListLoadBalancersStrategy.java b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/loadbalancer/strategy/CloudLoadBalancersListLoadBalancersStrategy.java index 944d62b0a3..01b64d2127 100644 --- a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/loadbalancer/strategy/CloudLoadBalancersListLoadBalancersStrategy.java +++ b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/loadbalancer/strategy/CloudLoadBalancersListLoadBalancersStrategy.java @@ -21,26 +21,20 @@ package org.jclouds.rackspace.cloudloadbalancers.loadbalancer.strategy; import static com.google.common.base.Preconditions.checkNotNull; import java.util.Set; -import java.util.concurrent.ExecutorService; -import javax.annotation.Resource; import javax.inject.Inject; -import javax.inject.Named; import javax.inject.Singleton; -import org.jclouds.Constants; import org.jclouds.loadbalancer.domain.LoadBalancerMetadata; -import org.jclouds.loadbalancer.reference.LoadBalancerConstants; import org.jclouds.loadbalancer.strategy.ListLoadBalancersStrategy; import org.jclouds.location.Zone; -import org.jclouds.logging.Logger; import org.jclouds.rackspace.cloudloadbalancers.CloudLoadBalancersApi; import org.jclouds.rackspace.cloudloadbalancers.domain.LoadBalancer; import com.google.common.base.Function; import com.google.common.base.Supplier; -import com.google.common.collect.FluentIterable; -import com.google.common.collect.Sets; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.ImmutableSet.Builder; /** * @@ -48,38 +42,25 @@ import com.google.common.collect.Sets; */ @Singleton public class CloudLoadBalancersListLoadBalancersStrategy implements ListLoadBalancersStrategy { - @Resource - @Named(LoadBalancerConstants.LOADBALANCER_LOGGER) - protected Logger logger = Logger.NULL; private final CloudLoadBalancersApi aclient; private final Function converter; - private final ExecutorService executor; // leaving this here for possible future parallelization private final Supplier> zones; @Inject protected CloudLoadBalancersListLoadBalancersStrategy(CloudLoadBalancersApi aclient, - Function converter, - @Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor, @Zone Supplier> zones) { + Function converter, @Zone Supplier> zones) { this.aclient = checkNotNull(aclient, "aclient"); this.zones = checkNotNull(zones, "zones"); this.converter = checkNotNull(converter, "converter"); - this.executor = checkNotNull(executor, "executor"); } @Override public Iterable listLoadBalancers() { - Set loadBalancerMetadatas = Sets.newHashSet(); - - for (String zone: zones.get()) { - FluentIterable lbm = - aclient.getLoadBalancerApiForZone(zone).list().concat().transform(converter); - - for (LoadBalancerMetadata loadBalancerMetadata: lbm) { - loadBalancerMetadatas.add(loadBalancerMetadata); - } + Builder loadBalancers = ImmutableSet. builder(); + for (String zone : zones.get()) { // TODO: parallel + loadBalancers.addAll(aclient.getLoadBalancerApiForZone(zone).list().concat().transform(converter)); } - - return loadBalancerMetadatas; + return loadBalancers.build(); } } diff --git a/apis/s3/src/main/java/org/jclouds/s3/S3Client.java b/apis/s3/src/main/java/org/jclouds/s3/S3Client.java index 60d7c11769..5b388c1654 100644 --- a/apis/s3/src/main/java/org/jclouds/s3/S3Client.java +++ b/apis/s3/src/main/java/org/jclouds/s3/S3Client.java @@ -19,6 +19,9 @@ package org.jclouds.s3; import java.util.Set; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; + import org.jclouds.http.options.GetOptions; import org.jclouds.javax.annotation.Nullable; import org.jclouds.s3.domain.AccessControlList; diff --git a/apis/s3/src/main/java/org/jclouds/s3/blobstore/S3AsyncBlobStore.java b/apis/s3/src/main/java/org/jclouds/s3/blobstore/S3AsyncBlobStore.java index bf77d74e49..edcd4a2065 100644 --- a/apis/s3/src/main/java/org/jclouds/s3/blobstore/S3AsyncBlobStore.java +++ b/apis/s3/src/main/java/org/jclouds/s3/blobstore/S3AsyncBlobStore.java @@ -19,9 +19,9 @@ package org.jclouds.s3.blobstore; import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.util.concurrent.Futures.transform; import java.util.Set; -import java.util.concurrent.ExecutorService; import javax.inject.Inject; import javax.inject.Named; @@ -42,7 +42,6 @@ import org.jclouds.blobstore.options.PutOptions; import org.jclouds.blobstore.strategy.internal.FetchBlobMetadata; import org.jclouds.blobstore.util.BlobUtils; import org.jclouds.collect.Memoized; -import org.jclouds.concurrent.Futures; import org.jclouds.domain.Location; import org.jclouds.http.options.GetOptions; import org.jclouds.s3.S3AsyncClient; @@ -69,6 +68,7 @@ import com.google.common.base.Supplier; import com.google.common.cache.CacheLoader; import com.google.common.cache.LoadingCache; import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.ListeningExecutorService; /** * @@ -91,14 +91,14 @@ public class S3AsyncBlobStore extends BaseAsyncBlobStore { @Inject protected S3AsyncBlobStore(BlobStoreContext context, BlobUtils blobUtils, - @Named(Constants.PROPERTY_USER_THREADS) ExecutorService service, Supplier defaultLocation, + @Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor, Supplier defaultLocation, @Memoized Supplier> locations, S3AsyncClient async, S3Client sync, Function, PageSet> convertBucketsToStorageMetadata, ContainerToBucketListOptions container2BucketListOptions, BucketToResourceList bucket2ResourceList, ObjectToBlob object2Blob, BlobToHttpGetOptions blob2ObjectGetOptions, BlobToObject blob2Object, ObjectToBlobMetadata object2BlobMd, Provider fetchBlobMetadataProvider, LoadingCache bucketAcls) { - super(context, blobUtils, service, defaultLocation, locations); + super(context, blobUtils, userExecutor, defaultLocation, locations); this.blob2ObjectGetOptions = checkNotNull(blob2ObjectGetOptions, "blob2ObjectGetOptions"); this.async = checkNotNull(async, "async"); this.sync = checkNotNull(sync, "sync"); @@ -117,12 +117,12 @@ public class S3AsyncBlobStore extends BaseAsyncBlobStore { */ @Override public ListenableFuture> list() { - return Futures.compose(async.listOwnedBuckets(), + return transform(async.listOwnedBuckets(), new Function, org.jclouds.blobstore.domain.PageSet>() { public org.jclouds.blobstore.domain.PageSet apply(Set from) { return convertBucketsToStorageMetadata.apply(from); } - }, service); + }, userExecutor); } /** @@ -156,14 +156,14 @@ public class S3AsyncBlobStore extends BaseAsyncBlobStore { * bucket name */ @Override - // TODO get rid of compose, as it serializes async results when the executor is single-threaded. + // TODO get rid of transform, as it serializes async results when the executor is single-threaded. public ListenableFuture> list(String container, ListContainerOptions options) { ListBucketOptions httpOptions = container2BucketListOptions.apply(options); ListenableFuture returnVal = async.listBucket(container, httpOptions); - ListenableFuture> list = Futures.compose(returnVal, bucket2ResourceList, - service); - return (options.isDetailed()) ? Futures.compose(list, - fetchBlobMetadataProvider.get().setContainerName(container), service) : list; + ListenableFuture> list = transform(returnVal, bucket2ResourceList, + userExecutor); + return (options.isDetailed()) ? transform(list, + fetchBlobMetadataProvider.get().setContainerName(container), userExecutor) : list; } /** @@ -196,14 +196,14 @@ public class S3AsyncBlobStore extends BaseAsyncBlobStore { */ @Override public ListenableFuture blobMetadata(String container, String key) { - return Futures.compose(async.headObject(container, key), new Function() { + return transform(async.headObject(container, key), new Function() { @Override public BlobMetadata apply(ObjectMetadata from) { return object2BlobMd.apply(from); } - }, service); + }, userExecutor); } /** @@ -217,7 +217,7 @@ public class S3AsyncBlobStore extends BaseAsyncBlobStore { @Override public ListenableFuture getBlob(String container, String key, org.jclouds.blobstore.options.GetOptions options) { GetOptions httpOptions = blob2ObjectGetOptions.apply(options); - return Futures.compose(async.getObject(container, key, httpOptions), object2Blob, service); + return transform(async.getObject(container, key, httpOptions), object2Blob, userExecutor); } /** diff --git a/apis/s3/src/main/java/org/jclouds/s3/blobstore/functions/BucketsToStorageMetadata.java b/apis/s3/src/main/java/org/jclouds/s3/blobstore/functions/BucketsToStorageMetadata.java index 5cd9d2542d..17b3f6414b 100644 --- a/apis/s3/src/main/java/org/jclouds/s3/blobstore/functions/BucketsToStorageMetadata.java +++ b/apis/s3/src/main/java/org/jclouds/s3/blobstore/functions/BucketsToStorageMetadata.java @@ -22,8 +22,6 @@ import static com.google.common.base.Preconditions.checkNotNull; import java.util.Set; import java.util.concurrent.Callable; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Future; import javax.annotation.Resource; import javax.inject.Inject; @@ -39,6 +37,8 @@ import org.jclouds.logging.Logger; import org.jclouds.s3.domain.BucketMetadata; import com.google.common.base.Function; +import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.ListeningExecutorService; @Singleton public class BucketsToStorageMetadata implements @@ -47,11 +47,11 @@ public class BucketsToStorageMetadata implements @Resource protected Logger logger = Logger.NULL; - private final ExecutorService userExecutor; + private final ListeningExecutorService userExecutor; private final BucketToResourceMetadata bucket2ResourceMd; @Inject - public BucketsToStorageMetadata(@Named(Constants.PROPERTY_USER_THREADS) ExecutorService userExecutor, BucketToResourceMetadata bucket2ResourceMd) { + public BucketsToStorageMetadata(@Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor, BucketToResourceMetadata bucket2ResourceMd) { this.userExecutor = checkNotNull(userExecutor, "userExecutor"); this.bucket2ResourceMd = checkNotNull(bucket2ResourceMd, "bucket2ResourceMd"); } @@ -62,9 +62,9 @@ public class BucketsToStorageMetadata implements // parallel as listing buckets is slow when looking up regions Iterable buckets = FutureIterables . transformParallel(input, - new Function>() { + new Function>() { @Override - public Future apply(final BucketMetadata from) { + public ListenableFuture apply(final BucketMetadata from) { return userExecutor.submit(new Callable() { @Override diff --git a/apis/s3/src/main/java/org/jclouds/s3/handlers/ParseS3ErrorFromXmlContent.java b/apis/s3/src/main/java/org/jclouds/s3/handlers/ParseS3ErrorFromXmlContent.java index fc03338579..64487fa726 100644 --- a/apis/s3/src/main/java/org/jclouds/s3/handlers/ParseS3ErrorFromXmlContent.java +++ b/apis/s3/src/main/java/org/jclouds/s3/handlers/ParseS3ErrorFromXmlContent.java @@ -24,12 +24,11 @@ import static org.jclouds.s3.reference.S3Constants.PROPERTY_S3_VIRTUAL_HOST_BUCK import java.net.URI; import java.util.List; + import javax.inject.Inject; import javax.inject.Named; import javax.inject.Singleton; -import com.google.common.base.Joiner; -import com.google.common.base.Splitter; import org.jclouds.aws.domain.AWSError; import org.jclouds.aws.handlers.ParseAWSErrorFromXmlContent; import org.jclouds.aws.util.AWSUtils; @@ -40,6 +39,9 @@ import org.jclouds.http.HttpResponse; import org.jclouds.rest.ResourceNotFoundException; import org.jclouds.s3.S3ApiMetadata; +import com.google.common.base.Joiner; +import com.google.common.base.Splitter; + /** * @author Adrian Cole * diff --git a/apis/s3/src/main/java/org/jclouds/s3/xml/ListBucketHandler.java b/apis/s3/src/main/java/org/jclouds/s3/xml/ListBucketHandler.java index 193c64b70a..bb1f3ce3d2 100644 --- a/apis/s3/src/main/java/org/jclouds/s3/xml/ListBucketHandler.java +++ b/apis/s3/src/main/java/org/jclouds/s3/xml/ListBucketHandler.java @@ -23,6 +23,7 @@ import static org.jclouds.http.Uris.uriBuilder; import static org.jclouds.util.SaxUtils.currentOrNull; import java.util.regex.Pattern; + import javax.inject.Inject; import org.jclouds.date.DateService; diff --git a/apis/s3/src/test/java/org/jclouds/s3/S3AsyncClientTest.java b/apis/s3/src/test/java/org/jclouds/s3/S3AsyncClientTest.java index 411326cff9..debed7a9b7 100644 --- a/apis/s3/src/test/java/org/jclouds/s3/S3AsyncClientTest.java +++ b/apis/s3/src/test/java/org/jclouds/s3/S3AsyncClientTest.java @@ -36,7 +36,6 @@ import org.jclouds.http.functions.ParseSax; import org.jclouds.http.functions.ReleasePayloadAndReturn; import org.jclouds.http.functions.ReturnTrueIf2xx; import org.jclouds.http.options.GetOptions; -import com.google.common.reflect.Invokable; import org.jclouds.rest.ConfiguresRestClient; import org.jclouds.rest.internal.GeneratedHttpRequest; import org.jclouds.s3.S3Fallbacks.TrueOn404OrNotFoundFalseOnIllegalState; @@ -71,6 +70,7 @@ import com.google.common.base.Supplier; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Lists; +import com.google.common.reflect.Invokable; import com.google.inject.Module; /** diff --git a/apis/s3/src/test/java/org/jclouds/s3/S3ClientLiveTest.java b/apis/s3/src/test/java/org/jclouds/s3/S3ClientLiveTest.java index ba38b4eaa6..57f7530aa5 100644 --- a/apis/s3/src/test/java/org/jclouds/s3/S3ClientLiveTest.java +++ b/apis/s3/src/test/java/org/jclouds/s3/S3ClientLiveTest.java @@ -43,13 +43,13 @@ import java.util.concurrent.TimeoutException; import org.jclouds.blobstore.integration.internal.BaseBlobStoreIntegrationTest; import org.jclouds.http.HttpResponseException; import org.jclouds.s3.domain.AccessControlList; -import org.jclouds.s3.domain.CannedAccessPolicy; -import org.jclouds.s3.domain.ObjectMetadata; -import org.jclouds.s3.domain.S3Object; import org.jclouds.s3.domain.AccessControlList.CanonicalUserGrantee; import org.jclouds.s3.domain.AccessControlList.EmailAddressGrantee; import org.jclouds.s3.domain.AccessControlList.GroupGranteeURI; import org.jclouds.s3.domain.AccessControlList.Permission; +import org.jclouds.s3.domain.CannedAccessPolicy; +import org.jclouds.s3.domain.ObjectMetadata; +import org.jclouds.s3.domain.S3Object; import org.jclouds.s3.options.PutObjectOptions; import org.jclouds.util.Strings2; import org.testng.annotations.Test; diff --git a/apis/s3/src/test/java/org/jclouds/s3/internal/StubS3AsyncClient.java b/apis/s3/src/test/java/org/jclouds/s3/internal/StubS3AsyncClient.java index 85a59522d1..7c0c63fc6d 100644 --- a/apis/s3/src/test/java/org/jclouds/s3/internal/StubS3AsyncClient.java +++ b/apis/s3/src/test/java/org/jclouds/s3/internal/StubS3AsyncClient.java @@ -21,13 +21,13 @@ package org.jclouds.s3.internal; import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.util.concurrent.Futures.immediateFailedFuture; import static com.google.common.util.concurrent.Futures.immediateFuture; +import static com.google.common.util.concurrent.Futures.transform; import java.util.Date; import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.ExecutorService; import javax.inject.Inject; import javax.inject.Named; @@ -44,7 +44,6 @@ import org.jclouds.blobstore.domain.MutableBlobMetadata; import org.jclouds.blobstore.functions.HttpGetOptionsListToGetOptions; import org.jclouds.blobstore.options.ListContainerOptions; import org.jclouds.blobstore.util.BlobStoreUtils; -import org.jclouds.concurrent.Futures; import org.jclouds.date.DateService; import org.jclouds.domain.Location; import org.jclouds.domain.LocationBuilder; @@ -78,6 +77,7 @@ import com.google.common.base.Function; import com.google.common.collect.Iterables; import com.google.common.collect.Sets; import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.ListeningExecutorService; /** * Implementation of {@link S3AsyncBlobStore} which keeps all data in a local Map object. @@ -99,17 +99,17 @@ public class StubS3AsyncClient implements S3AsyncClient { private final ResourceToBucketList resource2BucketList; private final ConcurrentMap> containerToBlobs; private final ConcurrentMap containerToLocation; - private final ExecutorService service; + private final ListeningExecutorService userExecutor; @Inject - private StubS3AsyncClient(@Named(Constants.PROPERTY_USER_THREADS) ExecutorService service, + private StubS3AsyncClient(@Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor, LocalAsyncBlobStore blobStore, ConcurrentMap> containerToBlobs, ConcurrentMap containerToLocation, DateService dateService, S3Object.Factory objectProvider, Blob.Factory blobProvider, HttpGetOptionsListToGetOptions httpGetOptionsConverter, ObjectToBlob object2Blob, BlobToObject blob2Object, BlobToObjectMetadata blob2ObjectMetadata, BucketToContainerListOptions bucket2ContainerListOptions, ResourceToBucketList resource2BucketList) { - this.service = service; + this.userExecutor = userExecutor; this.containerToBlobs = containerToBlobs; this.containerToLocation = containerToLocation; this.blobStore = blobStore; @@ -146,7 +146,7 @@ public class StubS3AsyncClient implements S3AsyncClient { public ListenableFuture listBucket(final String name, ListBucketOptions... optionsList) { ListContainerOptions options = bucket2ContainerListOptions.apply(optionsList); - return Futures.compose(blobStore.list(name, options), resource2BucketList, service); + return transform(blobStore.list(name, options), resource2BucketList, userExecutor); } public ListenableFuture copyObject(final String sourceBucket, final String sourceObject, @@ -274,16 +274,15 @@ public class StubS3AsyncClient implements S3AsyncClient { public ListenableFuture getObject(final String bucketName, final String key, final GetOptions... options) { org.jclouds.blobstore.options.GetOptions getOptions = httpGetOptionsConverter.apply(options); - return Futures.compose(blobStore.getBlob(bucketName, key, getOptions), blob2Object, service); + return transform(blobStore.getBlob(bucketName, key, getOptions), blob2Object, userExecutor); } public ListenableFuture headObject(String bucketName, String key) { - return Futures.compose(blobStore.blobMetadata(bucketName, key), new Function() { - @Override + return transform(blobStore.blobMetadata(bucketName, key), new Function() { public ObjectMetadata apply(BlobMetadata from) { return blob2ObjectMetadata.apply(from); } - }, service); + }, userExecutor); } public ListenableFuture> listOwnedBuckets() { diff --git a/apis/swift/src/main/java/org/jclouds/openstack/swift/blobstore/SwiftAsyncBlobStore.java b/apis/swift/src/main/java/org/jclouds/openstack/swift/blobstore/SwiftAsyncBlobStore.java index 5ae25a4989..a235be58b6 100644 --- a/apis/swift/src/main/java/org/jclouds/openstack/swift/blobstore/SwiftAsyncBlobStore.java +++ b/apis/swift/src/main/java/org/jclouds/openstack/swift/blobstore/SwiftAsyncBlobStore.java @@ -19,10 +19,10 @@ package org.jclouds.openstack.swift.blobstore; import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.util.concurrent.Futures.transform; import static org.jclouds.blobstore.util.BlobStoreUtils.createParentIfNeededAsync; import java.util.Set; -import java.util.concurrent.ExecutorService; import javax.inject.Inject; import javax.inject.Named; @@ -44,7 +44,6 @@ import org.jclouds.blobstore.options.PutOptions; import org.jclouds.blobstore.strategy.internal.FetchBlobMetadata; import org.jclouds.blobstore.util.BlobUtils; import org.jclouds.collect.Memoized; -import org.jclouds.concurrent.Futures; import org.jclouds.domain.Location; import org.jclouds.http.options.GetOptions; import org.jclouds.openstack.swift.CommonSwiftAsyncClient; @@ -65,6 +64,7 @@ import com.google.common.base.Function; import com.google.common.base.Supplier; import com.google.common.collect.Iterables; import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.ListeningExecutorService; /** * @@ -86,7 +86,7 @@ public class SwiftAsyncBlobStore extends BaseAsyncBlobStore { @Inject protected SwiftAsyncBlobStore(BlobStoreContext context, BlobUtils blobUtils, - @Named(Constants.PROPERTY_USER_THREADS) ExecutorService service, Supplier defaultLocation, + @Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor, Supplier defaultLocation, @Memoized Supplier> locations, CommonSwiftClient sync, CommonSwiftAsyncClient async, ContainerToResourceMetadata container2ResourceMd, BlobStoreListContainerOptionsToListContainerOptions container2ContainerListOptions, @@ -94,7 +94,7 @@ public class SwiftAsyncBlobStore extends BaseAsyncBlobStore { ObjectToBlobMetadata object2BlobMd, BlobToHttpGetOptions blob2ObjectGetOptions, Provider fetchBlobMetadataProvider, Provider multipartUploadStrategy) { - super(context, blobUtils, service, defaultLocation, locations); + super(context, blobUtils, userExecutor, defaultLocation, locations); this.sync = sync; this.async = async; this.container2ResourceMd = container2ResourceMd; @@ -113,13 +113,13 @@ public class SwiftAsyncBlobStore extends BaseAsyncBlobStore { */ @Override public ListenableFuture> list() { - return Futures.compose(async.listContainers(), + return transform(async.listContainers(), new Function, org.jclouds.blobstore.domain.PageSet>() { public org.jclouds.blobstore.domain.PageSet apply( Set from) { return new PageSetImpl(Iterables.transform(from, container2ResourceMd), null); } - }, service); + }, userExecutor); } /** @@ -152,10 +152,10 @@ public class SwiftAsyncBlobStore extends BaseAsyncBlobStore { org.jclouds.openstack.swift.options.ListContainerOptions httpOptions = container2ContainerListOptions .apply(options); ListenableFuture> returnVal = async.listObjects(container, httpOptions); - ListenableFuture> list = Futures.compose(returnVal, container2ResourceList, - service); - return options.isDetailed() ? Futures.compose(list, fetchBlobMetadataProvider.get().setContainerName(container), - service) : list; + ListenableFuture> list = transform(returnVal, container2ResourceList, + userExecutor); + return options.isDetailed() ? transform(list, fetchBlobMetadataProvider.get().setContainerName(container), + userExecutor) : list; } /** @@ -181,7 +181,7 @@ public class SwiftAsyncBlobStore extends BaseAsyncBlobStore { */ @Override public ListenableFuture blobMetadata(String container, String key) { - return Futures.compose(async.getObjectInfo(container, key), + return transform(async.getObjectInfo(container, key), new Function() { @Override @@ -189,7 +189,7 @@ public class SwiftAsyncBlobStore extends BaseAsyncBlobStore { return object2BlobMd.apply(from); } - }, service); + }, userExecutor); } /** @@ -204,7 +204,7 @@ public class SwiftAsyncBlobStore extends BaseAsyncBlobStore { public ListenableFuture getBlob(String container, String key, org.jclouds.blobstore.options.GetOptions options) { GetOptions httpOptions = blob2ObjectGetOptions.apply(options); ListenableFuture returnVal = async.getObject(container, key, httpOptions); - return Futures.compose(returnVal, object2Blob, service); + return transform(returnVal, object2Blob, userExecutor); } /** diff --git a/apis/swift/src/main/java/org/jclouds/openstack/swift/blobstore/strategy/internal/ParallelMultipartUploadStrategy.java b/apis/swift/src/main/java/org/jclouds/openstack/swift/blobstore/strategy/internal/ParallelMultipartUploadStrategy.java index e0241d652d..37299a4430 100644 --- a/apis/swift/src/main/java/org/jclouds/openstack/swift/blobstore/strategy/internal/ParallelMultipartUploadStrategy.java +++ b/apis/swift/src/main/java/org/jclouds/openstack/swift/blobstore/strategy/internal/ParallelMultipartUploadStrategy.java @@ -1,27 +1,7 @@ package org.jclouds.openstack.swift.blobstore.strategy.internal; -import com.google.common.annotations.VisibleForTesting; -import com.google.common.collect.Maps; -import com.google.common.util.concurrent.ListenableFuture; -import com.google.inject.Inject; -import org.jclouds.Constants; -import org.jclouds.blobstore.domain.Blob; -import org.jclouds.blobstore.internal.BlobRuntimeException; -import org.jclouds.blobstore.options.PutOptions; -import org.jclouds.blobstore.reference.BlobStoreConstants; -import org.jclouds.concurrent.Futures; -import org.jclouds.io.Payload; -import org.jclouds.io.PayloadSlicer; -import org.jclouds.logging.Logger; -import org.jclouds.openstack.swift.CommonSwiftAsyncClient; -import org.jclouds.openstack.swift.CommonSwiftClient; -import org.jclouds.openstack.swift.SwiftApiMetadata; -import org.jclouds.openstack.swift.blobstore.SwiftAsyncBlobStore; -import org.jclouds.openstack.swift.blobstore.functions.BlobToObject; -import org.jclouds.util.Throwables2; +import static com.google.common.base.Preconditions.checkNotNull; -import javax.annotation.Resource; -import javax.inject.Named; import java.util.Map; import java.util.Queue; import java.util.SortedMap; @@ -33,11 +13,32 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.ConcurrentSkipListMap; import java.util.concurrent.CountDownLatch; -import java.util.concurrent.ExecutorService; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; -import static com.google.common.base.Preconditions.checkNotNull; +import javax.annotation.Resource; +import javax.inject.Named; + +import org.jclouds.Constants; +import org.jclouds.blobstore.domain.Blob; +import org.jclouds.blobstore.internal.BlobRuntimeException; +import org.jclouds.blobstore.options.PutOptions; +import org.jclouds.blobstore.reference.BlobStoreConstants; +import org.jclouds.io.Payload; +import org.jclouds.io.PayloadSlicer; +import org.jclouds.logging.Logger; +import org.jclouds.openstack.swift.CommonSwiftAsyncClient; +import org.jclouds.openstack.swift.CommonSwiftClient; +import org.jclouds.openstack.swift.SwiftApiMetadata; +import org.jclouds.openstack.swift.blobstore.SwiftAsyncBlobStore; +import org.jclouds.openstack.swift.blobstore.functions.BlobToObject; +import org.jclouds.util.Throwables2; + +import com.google.common.annotations.VisibleForTesting; +import com.google.common.collect.Maps; +import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.ListeningExecutorService; +import com.google.inject.Inject; public class ParallelMultipartUploadStrategy implements AsyncMultipartUploadStrategy { @Resource @@ -74,17 +75,17 @@ public class ParallelMultipartUploadStrategy implements AsyncMultipartUploadStra @Named(Constants.PROPERTY_REQUEST_TIMEOUT) protected Long maxTime; - private final ExecutorService ioWorkerExecutor; + private final ListeningExecutorService ioExecutor; protected final SwiftAsyncBlobStore ablobstore; protected final PayloadSlicer slicer; @Inject public ParallelMultipartUploadStrategy(SwiftAsyncBlobStore ablobstore, PayloadSlicer slicer, - @Named(Constants.PROPERTY_IO_WORKER_THREADS) ExecutorService ioWorkerExecutor) { + @Named(Constants.PROPERTY_IO_WORKER_THREADS) ListeningExecutorService ioExecutor) { this.ablobstore = checkNotNull(ablobstore, "ablobstore"); this.slicer = checkNotNull(slicer, "slicer"); - this.ioWorkerExecutor = checkNotNull(ioWorkerExecutor, "ioWorkerExecutor"); + this.ioExecutor = checkNotNull(ioExecutor, "ioExecutor"); } @@ -136,14 +137,13 @@ public class ParallelMultipartUploadStrategy implements AsyncMultipartUploadStra latch.countDown(); } } - }, ioWorkerExecutor); + }, ioExecutor); futureParts.put(part, futureETag); } @Override public ListenableFuture execute(final String container, final Blob blob, final PutOptions options, final BlobToObject blob2Object) { - return Futures.makeListenable( - ioWorkerExecutor.submit(new Callable() { + return ioExecutor.submit(new Callable() { @Override public String call() throws Exception { String key = blob.getMetadata().getName(); @@ -235,7 +235,7 @@ public class ParallelMultipartUploadStrategy implements AsyncMultipartUploadStra futureETag.get(maxTime, TimeUnit.SECONDS) : futureETag.get(); } } - }), ioWorkerExecutor); + }); } class Part { diff --git a/apis/swift/src/test/java/org/jclouds/openstack/swift/internal/StubSwiftAsyncClient.java b/apis/swift/src/test/java/org/jclouds/openstack/swift/internal/StubSwiftAsyncClient.java index 477c53628c..2e06138768 100644 --- a/apis/swift/src/test/java/org/jclouds/openstack/swift/internal/StubSwiftAsyncClient.java +++ b/apis/swift/src/test/java/org/jclouds/openstack/swift/internal/StubSwiftAsyncClient.java @@ -20,13 +20,13 @@ package org.jclouds.openstack.swift.internal; import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.util.concurrent.Futures.immediateFuture; +import static com.google.common.util.concurrent.Futures.transform; import java.net.URI; import java.util.HashMap; import java.util.Map; import java.util.Set; import java.util.concurrent.ExecutionException; -import java.util.concurrent.ExecutorService; import javax.inject.Inject; import javax.inject.Named; @@ -39,7 +39,6 @@ import org.jclouds.blobstore.domain.PageSet; import org.jclouds.blobstore.domain.StorageMetadata; import org.jclouds.blobstore.functions.HttpGetOptionsListToGetOptions; import org.jclouds.blobstore.options.ListContainerOptions; -import org.jclouds.concurrent.Futures; import org.jclouds.http.options.GetOptions; import org.jclouds.openstack.swift.CommonSwiftAsyncClient; import org.jclouds.openstack.swift.SwiftAsyncClient; @@ -60,6 +59,7 @@ import com.google.common.base.Throwables; import com.google.common.collect.Iterables; import com.google.common.collect.Sets; import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.ListeningExecutorService; /** * Implementation of {@link SwiftAsyncClient} which keeps all data in a local Map object. @@ -76,16 +76,16 @@ public class StubSwiftAsyncClient implements CommonSwiftAsyncClient { private final ResourceToObjectInfo blob2ObjectInfo; private final ListContainerOptionsToBlobStoreListContainerOptions container2ContainerListOptions; private final ResourceToObjectList resource2ObjectList; - private final ExecutorService service; + private final ListeningExecutorService userExecutor; @Inject - private StubSwiftAsyncClient(@Named(Constants.PROPERTY_USER_THREADS) ExecutorService service, + private StubSwiftAsyncClient(@Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor, LocalAsyncBlobStore blobStore, SwiftObject.Factory objectProvider, HttpGetOptionsListToGetOptions httpGetOptionsConverter, ObjectToBlob object2Blob, BlobToObject blob2Object, ResourceToObjectInfo blob2ObjectInfo, ListContainerOptionsToBlobStoreListContainerOptions container2ContainerListOptions, ResourceToObjectList resource2ContainerList) { - this.service = service; + this.userExecutor = userExecutor; this.blobStore = blobStore; this.objectProvider = objectProvider; this.httpGetOptionsConverter = httpGetOptionsConverter; @@ -127,11 +127,11 @@ public class StubSwiftAsyncClient implements CommonSwiftAsyncClient { public ListenableFuture getObject(String container, String key, GetOptions... options) { org.jclouds.blobstore.options.GetOptions getOptions = httpGetOptionsConverter.apply(options); - return Futures.compose(blobStore.getBlob(container, key, getOptions), blob2Object, service); + return transform(blobStore.getBlob(container, key, getOptions), blob2Object, userExecutor); } public ListenableFuture getObjectInfo(String container, String key) { - return Futures.compose(blobStore.blobMetadata(container, key), + return transform(blobStore.blobMetadata(container, key), new Function() { @Override @@ -140,7 +140,7 @@ public class StubSwiftAsyncClient implements CommonSwiftAsyncClient { return blob2ObjectInfo.apply(from); } - }, service); + }, userExecutor); } public ListenableFuture> listContainers( @@ -181,7 +181,7 @@ public class StubSwiftAsyncClient implements CommonSwiftAsyncClient { public ListenableFuture> listObjects(String container, org.jclouds.openstack.swift.options.ListContainerOptions... optionsList) { ListContainerOptions options = container2ContainerListOptions.apply(optionsList); - return Futures.compose(blobStore.list(container, options), resource2ObjectList, service); + return transform(blobStore.list(container, options), resource2ObjectList, userExecutor); } public ListenableFuture copyObject(String sourceContainer, String sourceObject, String destinationContainer, String destinationObject) { diff --git a/apis/vcloud/src/main/java/org/jclouds/vcloud/functions/CatalogItemsInCatalog.java b/apis/vcloud/src/main/java/org/jclouds/vcloud/functions/CatalogItemsInCatalog.java index cc398303f9..dbb4aa205d 100644 --- a/apis/vcloud/src/main/java/org/jclouds/vcloud/functions/CatalogItemsInCatalog.java +++ b/apis/vcloud/src/main/java/org/jclouds/vcloud/functions/CatalogItemsInCatalog.java @@ -21,9 +21,6 @@ package org.jclouds.vcloud.functions; import static com.google.common.collect.Iterables.filter; import static org.jclouds.concurrent.FutureIterables.transformParallel; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Future; - import javax.annotation.Resource; import javax.inject.Inject; import javax.inject.Named; @@ -39,6 +36,8 @@ import org.jclouds.vcloud.domain.ReferenceType; import com.google.common.base.Function; import com.google.common.base.Predicate; +import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.ListeningExecutorService; /** * @author Adrian Cole @@ -49,27 +48,25 @@ public class CatalogItemsInCatalog implements Function apply(Catalog from) { return transformParallel(filter(from.values(), new Predicate() { - @Override public boolean apply(ReferenceType input) { return input.getType().equals(VCloudMediaType.CATALOGITEM_XML); } - }), new Function>() { - @Override - public Future apply(ReferenceType from) { + }), new Function>() { + public ListenableFuture apply(ReferenceType from) { return aclient.getCatalogClient().getCatalogItem(from.getHref()); } - }, executor, null, logger, "catalogItems in " + from.getHref()); + }, userExecutor, null, logger, "catalogItems in " + from.getHref()); } } diff --git a/apis/vcloud/src/main/java/org/jclouds/vcloud/functions/CatalogsInOrg.java b/apis/vcloud/src/main/java/org/jclouds/vcloud/functions/CatalogsInOrg.java index 78793d8649..76bff6787b 100644 --- a/apis/vcloud/src/main/java/org/jclouds/vcloud/functions/CatalogsInOrg.java +++ b/apis/vcloud/src/main/java/org/jclouds/vcloud/functions/CatalogsInOrg.java @@ -20,9 +20,6 @@ package org.jclouds.vcloud.functions; import static org.jclouds.concurrent.FutureIterables.transformParallel; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Future; - import javax.annotation.Resource; import javax.inject.Inject; import javax.inject.Named; @@ -36,6 +33,8 @@ import org.jclouds.vcloud.domain.Org; import org.jclouds.vcloud.domain.ReferenceType; import com.google.common.base.Function; +import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.ListeningExecutorService; /** * @author Adrian Cole @@ -46,21 +45,20 @@ public class CatalogsInOrg implements Function> { public Logger logger = Logger.NULL; private final VCloudAsyncClient aclient; - private final ExecutorService executor; + private final ListeningExecutorService userExecutor; @Inject - CatalogsInOrg(VCloudAsyncClient aclient, @Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor) { + CatalogsInOrg(VCloudAsyncClient aclient, @Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor) { this.aclient = aclient; - this.executor = executor; + this.userExecutor = userExecutor; } @Override public Iterable apply(final Org org) { - return transformParallel(org.getCatalogs().values(), new Function>() { - @Override - public Future apply(ReferenceType from) { + return transformParallel(org.getCatalogs().values(), new Function>() { + public ListenableFuture apply(ReferenceType from) { return aclient.getCatalogClient().getCatalog(from.getHref()); } - }, executor, null, logger, "catalogs in " + org.getName()); + }, userExecutor, null, logger, "catalogs in " + org.getName()); } } diff --git a/apis/vcloud/src/main/java/org/jclouds/vcloud/functions/NetworksInOrg.java b/apis/vcloud/src/main/java/org/jclouds/vcloud/functions/NetworksInOrg.java index 4c943fae8a..e2bc1f20f3 100644 --- a/apis/vcloud/src/main/java/org/jclouds/vcloud/functions/NetworksInOrg.java +++ b/apis/vcloud/src/main/java/org/jclouds/vcloud/functions/NetworksInOrg.java @@ -20,9 +20,6 @@ package org.jclouds.vcloud.functions; import static org.jclouds.concurrent.FutureIterables.transformParallel; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Future; - import javax.annotation.Resource; import javax.inject.Inject; import javax.inject.Named; @@ -36,6 +33,8 @@ import org.jclouds.vcloud.domain.ReferenceType; import org.jclouds.vcloud.domain.network.OrgNetwork; import com.google.common.base.Function; +import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.ListeningExecutorService; /** * @author Adrian Cole @@ -46,22 +45,21 @@ public class NetworksInOrg implements Function> { public Logger logger = Logger.NULL; private final VCloudAsyncClient aclient; - private final ExecutorService executor; + private final ListeningExecutorService userExecutor; @Inject - NetworksInOrg(VCloudAsyncClient aclient, @Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor) { + NetworksInOrg(VCloudAsyncClient aclient, @Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor) { this.aclient = aclient; - this.executor = executor; + this.userExecutor = userExecutor; } @Override public Iterable apply(final Org org) { - return transformParallel(org.getNetworks().values(), new Function>() { - @Override - public Future apply(ReferenceType from) { + return transformParallel(org.getNetworks().values(), new Function>() { + public ListenableFuture apply(ReferenceType from) { return aclient.getNetworkClient().getNetwork(from.getHref()); } - }, executor, null, logger, "OrgNetworks in org " + org.getName()); + }, userExecutor, null, logger, "OrgNetworks in org " + org.getName()); } } diff --git a/apis/vcloud/src/main/java/org/jclouds/vcloud/functions/OrgsForLocations.java b/apis/vcloud/src/main/java/org/jclouds/vcloud/functions/OrgsForLocations.java index 880fa48da2..e8df218ed8 100644 --- a/apis/vcloud/src/main/java/org/jclouds/vcloud/functions/OrgsForLocations.java +++ b/apis/vcloud/src/main/java/org/jclouds/vcloud/functions/OrgsForLocations.java @@ -21,8 +21,6 @@ package org.jclouds.vcloud.functions; import static org.jclouds.concurrent.FutureIterables.transformParallel; import java.net.URI; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Future; import javax.annotation.Resource; import javax.inject.Inject; @@ -39,6 +37,8 @@ import org.jclouds.vcloud.domain.Org; import com.google.common.base.Function; import com.google.common.base.Predicate; import com.google.common.collect.FluentIterable; +import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.ListeningExecutorService; /** * @author Adrian Cole @@ -48,12 +48,12 @@ public class OrgsForLocations implements Function, Iterable, Iterable apply(Iterable from) { FluentIterable uris = FluentIterable.from(from).filter(new Predicate() { - @Override public boolean apply(Location input) { return input.getScope() == LocationScope.ZONE; } }).transform(new Function() { - @Override public URI apply(Location from) { return URI.create(from.getParent().getId()); } }); - return transformParallel(uris, new Function>() { - @Override - public Future apply(URI from) { + return transformParallel(uris, new Function>() { + public ListenableFuture apply(URI from) { return aclient.getOrgClient().getOrg(from); } - }, executor, null, logger, "organizations for uris"); + }, userExecutor, null, logger, "organizations for uris"); } } diff --git a/apis/vcloud/src/main/java/org/jclouds/vcloud/functions/OrgsForNames.java b/apis/vcloud/src/main/java/org/jclouds/vcloud/functions/OrgsForNames.java index 0774082467..2e0dacaa76 100644 --- a/apis/vcloud/src/main/java/org/jclouds/vcloud/functions/OrgsForNames.java +++ b/apis/vcloud/src/main/java/org/jclouds/vcloud/functions/OrgsForNames.java @@ -20,9 +20,6 @@ package org.jclouds.vcloud.functions; import static org.jclouds.concurrent.FutureIterables.transformParallel; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Future; - import javax.annotation.Resource; import javax.inject.Inject; import javax.inject.Named; @@ -36,6 +33,8 @@ import org.jclouds.vcloud.domain.Org; import com.google.common.base.Function; import com.google.common.base.Predicates; import com.google.common.collect.Iterables; +import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.ListeningExecutorService; /** * @author Adrian Cole @@ -45,24 +44,21 @@ public class OrgsForNames implements Function, Iterable> { @Resource public Logger logger = Logger.NULL; private final VCloudAsyncClient aclient; - private final ExecutorService executor; + private final ListeningExecutorService userExecutor; @Inject - OrgsForNames(VCloudAsyncClient aclient, @Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor) { + OrgsForNames(VCloudAsyncClient aclient, @Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor) { this.aclient = aclient; - this.executor = executor; + this.userExecutor = userExecutor; } @Override public Iterable apply(Iterable from) { - return Iterables.filter(transformParallel(from, new Function>() { - - @Override - public Future apply(String from) { + return Iterables.filter(transformParallel(from, new Function>() { + public ListenableFuture apply(String from) { return aclient.getOrgClient().findOrgNamed(from); } - - }, executor, null, logger, "organizations for names"), Predicates.notNull()); + }, userExecutor, null, logger, "organizations for names"), Predicates.notNull()); } } diff --git a/apis/vcloud/src/main/java/org/jclouds/vcloud/functions/VAppTemplatesForCatalogItems.java b/apis/vcloud/src/main/java/org/jclouds/vcloud/functions/VAppTemplatesForCatalogItems.java index 381afbcd95..a56cf3d717 100644 --- a/apis/vcloud/src/main/java/org/jclouds/vcloud/functions/VAppTemplatesForCatalogItems.java +++ b/apis/vcloud/src/main/java/org/jclouds/vcloud/functions/VAppTemplatesForCatalogItems.java @@ -22,9 +22,6 @@ import static com.google.common.collect.Iterables.filter; import static org.jclouds.Constants.PROPERTY_USER_THREADS; import static org.jclouds.concurrent.FutureIterables.transformParallel; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Future; - import javax.annotation.Resource; import javax.inject.Inject; import javax.inject.Named; @@ -40,6 +37,8 @@ import org.jclouds.vcloud.domain.VAppTemplate; import com.google.common.base.Function; import com.google.common.base.Predicate; import com.google.common.base.Predicates; +import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.ListeningExecutorService; /** * @author Adrian Cole @@ -50,32 +49,26 @@ public class VAppTemplatesForCatalogItems implements Function apply(Iterable from) { return filter(transformParallel(filter(from, new Predicate() { - - @Override public boolean apply(CatalogItem input) { return input.getEntity().getType().equals(VCloudMediaType.VAPPTEMPLATE_XML); } - - }), new Function>() { - - @Override - public Future apply(CatalogItem from) { + }), new Function>() { + public ListenableFuture apply(CatalogItem from) { return aclient.getVAppTemplateClient().getVAppTemplate(from.getEntity().getHref()); } - - }, executor, null, logger, "vappTemplates in"), Predicates.notNull()); + }, userExecutor, null, logger, "vappTemplates in"), Predicates.notNull()); } } diff --git a/apis/vcloud/src/main/java/org/jclouds/vcloud/functions/VDCsInOrg.java b/apis/vcloud/src/main/java/org/jclouds/vcloud/functions/VDCsInOrg.java index 76e77a6c62..4598d47a94 100644 --- a/apis/vcloud/src/main/java/org/jclouds/vcloud/functions/VDCsInOrg.java +++ b/apis/vcloud/src/main/java/org/jclouds/vcloud/functions/VDCsInOrg.java @@ -20,9 +20,6 @@ package org.jclouds.vcloud.functions; import static org.jclouds.concurrent.FutureIterables.transformParallel; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Future; - import javax.annotation.Resource; import javax.inject.Inject; import javax.inject.Named; @@ -36,6 +33,8 @@ import org.jclouds.vcloud.domain.ReferenceType; import org.jclouds.vcloud.domain.VDC; import com.google.common.base.Function; +import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.ListeningExecutorService; /** * @author Adrian Cole @@ -46,23 +45,21 @@ public class VDCsInOrg implements Function> { public Logger logger = Logger.NULL; private final VCloudAsyncClient aclient; - private final ExecutorService executor; + private final ListeningExecutorService userExecutor; @Inject - VDCsInOrg(VCloudAsyncClient aclient, @Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor) { + VDCsInOrg(VCloudAsyncClient aclient, @Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor) { this.aclient = aclient; - this.executor = executor; + this.userExecutor = userExecutor; } @Override public Iterable apply(final Org org) { - return transformParallel(org.getVDCs().values(), new Function>() { - @Override - public Future apply(ReferenceType from) { + return transformParallel(org.getVDCs().values(), new Function>() { + public ListenableFuture apply(ReferenceType from) { return aclient.getVDCClient().getVDC(from.getHref()); } - - }, executor, null, logger, "vdcs in org " + org.getName()); + }, userExecutor, null, logger, "vdcs in org " + org.getName()); } } diff --git a/apis/vcloud/src/main/java/org/jclouds/vcloud/suppliers/VAppTemplatesSupplier.java b/apis/vcloud/src/main/java/org/jclouds/vcloud/suppliers/VAppTemplatesSupplier.java index c62f785bc5..72373961d9 100644 --- a/apis/vcloud/src/main/java/org/jclouds/vcloud/suppliers/VAppTemplatesSupplier.java +++ b/apis/vcloud/src/main/java/org/jclouds/vcloud/suppliers/VAppTemplatesSupplier.java @@ -26,8 +26,6 @@ import static org.jclouds.concurrent.FutureIterables.transformParallel; import java.util.Map; import java.util.Set; import java.util.concurrent.Callable; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Future; import javax.annotation.Resource; import javax.inject.Inject; @@ -42,6 +40,8 @@ import org.jclouds.vcloud.domain.VAppTemplate; import com.google.common.base.Function; import com.google.common.base.Supplier; +import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.ListeningExecutorService; /** * @author Adrian Cole @@ -55,41 +55,34 @@ public class VAppTemplatesSupplier implements Supplier> { private final Supplier> orgMap; private final Function> imagesInOrg; - private final ExecutorService executor; + private final ListeningExecutorService userExecutor; @Inject VAppTemplatesSupplier(Supplier> orgMap, Function> imagesInOrg, - @Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor) { + @Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor) { this.orgMap = checkNotNull(orgMap, "orgMap"); this.imagesInOrg = checkNotNull(imagesInOrg, "imagesInOrg"); - this.executor = checkNotNull(executor, "executor"); + this.userExecutor = checkNotNull(userExecutor, "userExecutor"); } @Override public Set get() { Iterable orgs = checkNotNull(orgMap.get().values(), "orgs"); Iterable> images = transformParallel(orgs, - new Function>>() { - - @Override - public Future> apply(final Org from) { + new Function>>() { + public ListenableFuture> apply(final Org from) { checkNotNull(from, "org"); - return executor.submit(new Callable>() { - - @Override + return userExecutor.submit(new Callable>() { public Iterable call() throws Exception { return imagesInOrg.apply(from); } - - @Override public String toString() { return "imagesInOrg(" + from.getHref() + ")"; } }); } - - }, executor, null, logger, "images in " + orgs); + }, userExecutor, null, logger, "images in " + orgs); return newLinkedHashSet(concat(images)); } } diff --git a/blobstore/src/main/java/org/jclouds/blobstore/LocalAsyncBlobStore.java b/blobstore/src/main/java/org/jclouds/blobstore/LocalAsyncBlobStore.java index ca42a497e4..7f19adb299 100644 --- a/blobstore/src/main/java/org/jclouds/blobstore/LocalAsyncBlobStore.java +++ b/blobstore/src/main/java/org/jclouds/blobstore/LocalAsyncBlobStore.java @@ -36,7 +36,6 @@ import java.io.IOException; import java.util.Date; import java.util.Set; import java.util.SortedSet; -import java.util.concurrent.ExecutorService; import javax.annotation.Resource; import javax.inject.Inject; @@ -80,6 +79,7 @@ import com.google.common.base.Throwables; import com.google.common.collect.Iterables; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.ListeningExecutorService; /** * Implementation of {@link BaseAsyncBlobStore} which uses a pluggable @@ -103,13 +103,13 @@ public class LocalAsyncBlobStore extends BaseAsyncBlobStore { @Inject protected LocalAsyncBlobStore(BlobStoreContext context, BlobUtils blobUtils, - @Named(Constants.PROPERTY_USER_THREADS) ExecutorService service, + @Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor, Supplier defaultLocation, @Memoized Supplier> locations, ContentMetadataCodec contentMetadataCodec, IfDirectoryReturnNameStrategy ifDirectoryReturnName, Factory blobFactory, LocalStorageStrategy storageStrategy) { - super(context, blobUtils, service, defaultLocation, locations); + super(context, blobUtils, userExecutor, defaultLocation, locations); this.blobFactory = blobFactory; this.contentMetadataCodec = contentMetadataCodec; this.ifDirectoryReturnName = ifDirectoryReturnName; diff --git a/blobstore/src/main/java/org/jclouds/blobstore/internal/BaseAsyncBlobStore.java b/blobstore/src/main/java/org/jclouds/blobstore/internal/BaseAsyncBlobStore.java index a6bf83c17d..35388be2d6 100644 --- a/blobstore/src/main/java/org/jclouds/blobstore/internal/BaseAsyncBlobStore.java +++ b/blobstore/src/main/java/org/jclouds/blobstore/internal/BaseAsyncBlobStore.java @@ -24,7 +24,6 @@ import static org.jclouds.blobstore.options.ListContainerOptions.Builder.recursi import java.util.Set; import java.util.concurrent.Callable; -import java.util.concurrent.ExecutorService; import javax.inject.Inject; import javax.inject.Named; @@ -48,6 +47,7 @@ import com.google.common.base.Predicate; import com.google.common.base.Supplier; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.ListeningExecutorService; /** * @@ -57,17 +57,17 @@ public abstract class BaseAsyncBlobStore implements AsyncBlobStore { protected final BlobStoreContext context; protected final BlobUtils blobUtils; - protected final ExecutorService service; + protected final ListeningExecutorService userExecutor; protected final Supplier defaultLocation; protected final Supplier> locations; @Inject protected BaseAsyncBlobStore(BlobStoreContext context, BlobUtils blobUtils, - @Named(Constants.PROPERTY_USER_THREADS) ExecutorService service, Supplier defaultLocation, + @Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor, Supplier defaultLocation, @Memoized Supplier> locations) { this.context = checkNotNull(context, "context"); this.blobUtils = checkNotNull(blobUtils, "blobUtils"); - this.service = checkNotNull(service, "service"); + this.userExecutor = checkNotNull(userExecutor, "userExecutor"); this.defaultLocation = checkNotNull(defaultLocation, "defaultLocation"); this.locations = checkNotNull(locations, "locations"); } @@ -117,7 +117,7 @@ public abstract class BaseAsyncBlobStore implements AsyncBlobStore { */ @Override public ListenableFuture countBlobs(final String containerName, final ListContainerOptions options) { - return org.jclouds.concurrent.Futures.makeListenable(service.submit(new Callable() { + return userExecutor.submit(new Callable() { public Long call() throws Exception { return blobUtils.countBlobs(containerName, options); } @@ -126,7 +126,7 @@ public abstract class BaseAsyncBlobStore implements AsyncBlobStore { public String toString() { return "countBlobs(" + containerName + ")"; } - }), service); + }); } /** @@ -149,7 +149,7 @@ public abstract class BaseAsyncBlobStore implements AsyncBlobStore { */ @Override public ListenableFuture clearContainer(final String containerName, final ListContainerOptions options) { - return org.jclouds.concurrent.Futures.makeListenable(service.submit(new Callable() { + return userExecutor.submit(new Callable() { public Void call() throws Exception { blobUtils.clearContainer(containerName, options); @@ -160,7 +160,7 @@ public abstract class BaseAsyncBlobStore implements AsyncBlobStore { public String toString() { return "clearContainer(" + containerName + ")"; } - }), service); + }); } /** @@ -171,7 +171,7 @@ public abstract class BaseAsyncBlobStore implements AsyncBlobStore { */ @Override public ListenableFuture deleteDirectory(final String containerName, final String directory) { - return org.jclouds.concurrent.Futures.makeListenable(service.submit(new Callable() { + return userExecutor.submit(new Callable() { public Void call() throws Exception { blobUtils.deleteDirectory(containerName, directory); @@ -182,7 +182,7 @@ public abstract class BaseAsyncBlobStore implements AsyncBlobStore { public String toString() { return "deleteDirectory(" + containerName + "," + directory + ")"; } - }), service); + }); } /** @@ -194,7 +194,7 @@ public abstract class BaseAsyncBlobStore implements AsyncBlobStore { * virtual path */ public ListenableFuture directoryExists(final String containerName, final String directory) { - return org.jclouds.concurrent.Futures.makeListenable(service.submit(new Callable() { + return userExecutor.submit(new Callable() { public Boolean call() throws Exception { return blobUtils.directoryExists(containerName, directory); @@ -204,7 +204,7 @@ public abstract class BaseAsyncBlobStore implements AsyncBlobStore { public String toString() { return "directoryExists(" + containerName + "," + directory + ")"; } - }), service); + }); } /** @@ -217,9 +217,8 @@ public abstract class BaseAsyncBlobStore implements AsyncBlobStore { */ public ListenableFuture createDirectory(final String containerName, final String directory) { - return blobUtils.directoryExists(containerName, directory) ? Futures.immediateFuture((Void) null) - : org.jclouds.concurrent.Futures.makeListenable(service.submit(new Callable() { + : userExecutor.submit(new Callable() { public Void call() throws Exception { blobUtils.createDirectory(containerName, directory); return null; @@ -229,7 +228,7 @@ public abstract class BaseAsyncBlobStore implements AsyncBlobStore { public String toString() { return "createDirectory(" + containerName + "," + directory + ")"; } - }), service); + }); } /** @@ -254,7 +253,7 @@ public abstract class BaseAsyncBlobStore implements AsyncBlobStore { */ @Override public ListenableFuture deleteContainer(final String container) { - return org.jclouds.concurrent.Futures.makeListenable(service.submit(new Callable() { + return userExecutor.submit(new Callable() { public Void call() throws Exception { deletePathAndEnsureGone(container); @@ -265,7 +264,7 @@ public abstract class BaseAsyncBlobStore implements AsyncBlobStore { public String toString() { return "deleteContainer(" + container + ")"; } - }), service); + }); } protected void deletePathAndEnsureGone(String path) { diff --git a/blobstore/src/main/java/org/jclouds/blobstore/strategy/internal/DeleteAllKeysInList.java b/blobstore/src/main/java/org/jclouds/blobstore/strategy/internal/DeleteAllKeysInList.java index da8088d50a..52e02e346b 100644 --- a/blobstore/src/main/java/org/jclouds/blobstore/strategy/internal/DeleteAllKeysInList.java +++ b/blobstore/src/main/java/org/jclouds/blobstore/strategy/internal/DeleteAllKeysInList.java @@ -24,10 +24,8 @@ import static org.jclouds.concurrent.FutureIterables.awaitCompletion; import java.util.Map; import java.util.concurrent.ExecutionException; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Future; -import java.util.concurrent.TimeoutException; import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; import javax.annotation.Resource; import javax.inject.Named; @@ -46,6 +44,8 @@ import org.jclouds.http.handlers.BackoffLimitedRetryHandler; import org.jclouds.logging.Logger; import com.google.common.collect.Maps; +import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.ListeningExecutorService; import com.google.inject.Inject; /** @@ -60,7 +60,7 @@ public class DeleteAllKeysInList implements ClearListStrategy, ClearContainerStr protected Logger logger = Logger.NULL; protected final BackoffLimitedRetryHandler retryHandler; - private final ExecutorService userExecutor; + private final ListeningExecutorService userExecutor; protected final AsyncBlobStore connection; /** Maximum duration in milliseconds of a request. */ @@ -69,10 +69,8 @@ public class DeleteAllKeysInList implements ClearListStrategy, ClearContainerStr protected Long maxTime = Long.MAX_VALUE; @Inject - DeleteAllKeysInList(@Named(Constants.PROPERTY_USER_THREADS) ExecutorService userExecutor, - AsyncBlobStore connection, - BackoffLimitedRetryHandler retryHandler) { - + DeleteAllKeysInList(@Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor, + AsyncBlobStore connection, BackoffLimitedRetryHandler retryHandler) { this.userExecutor = userExecutor; this.connection = connection; this.retryHandler = retryHandler; @@ -95,7 +93,7 @@ public class DeleteAllKeysInList implements ClearListStrategy, ClearContainerStr for (int numErrors = 0; numErrors < maxErrors; ) { // fetch partial directory listing PageSet listing; - Future> listFuture = + ListenableFuture> listFuture = connection.list(containerName, options); try { listing = listFuture.get(maxTime, TimeUnit.MILLISECONDS); @@ -141,7 +139,7 @@ public class DeleteAllKeysInList implements ClearListStrategy, ClearContainerStr } // remove blobs and now-empty subdirectories - Map> responses = Maps.newHashMap(); + Map> responses = Maps.newHashMap(); for (StorageMetadata md : listing) { String fullPath = parentIsFolder(options, md) ? options.getDir() + "/" + md.getName() : md.getName(); @@ -174,7 +172,7 @@ public class DeleteAllKeysInList implements ClearListStrategy, ClearContainerStr retryHandler.imposeBackoffExponentialDelay(numErrors, message); continue; } finally { - for (Future future : responses.values()) { + for (ListenableFuture future : responses.values()) { future.cancel(true); } } diff --git a/blobstore/src/main/java/org/jclouds/blobstore/strategy/internal/FetchBlobMetadata.java b/blobstore/src/main/java/org/jclouds/blobstore/strategy/internal/FetchBlobMetadata.java index d99672a2ec..7e0b4f04e9 100644 --- a/blobstore/src/main/java/org/jclouds/blobstore/strategy/internal/FetchBlobMetadata.java +++ b/blobstore/src/main/java/org/jclouds/blobstore/strategy/internal/FetchBlobMetadata.java @@ -21,9 +21,6 @@ package org.jclouds.blobstore.strategy.internal; import static com.google.common.base.Preconditions.checkState; import static org.jclouds.concurrent.FutureIterables.transformParallel; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Future; - import javax.annotation.Resource; import javax.inject.Named; @@ -43,6 +40,8 @@ import com.google.common.base.Function; import com.google.common.base.Predicate; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; +import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.ListeningExecutorService; import com.google.inject.Inject; /** @@ -55,7 +54,7 @@ public class FetchBlobMetadata implements Function>() { + }), new Function>() { @Override - public Future apply(StorageMetadata from) { + public ListenableFuture apply(StorageMetadata from) { return ablobstore.blobMetadata(container, from.getName()); } diff --git a/blobstore/src/main/java/org/jclouds/blobstore/strategy/internal/GetAllBlobsInListAndRetryOnFailure.java b/blobstore/src/main/java/org/jclouds/blobstore/strategy/internal/GetAllBlobsInListAndRetryOnFailure.java index d60ec364d9..2ed50411f4 100644 --- a/blobstore/src/main/java/org/jclouds/blobstore/strategy/internal/GetAllBlobsInListAndRetryOnFailure.java +++ b/blobstore/src/main/java/org/jclouds/blobstore/strategy/internal/GetAllBlobsInListAndRetryOnFailure.java @@ -20,9 +20,6 @@ package org.jclouds.blobstore.strategy.internal; import static org.jclouds.concurrent.FutureIterables.transformParallel; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Future; - import javax.annotation.Resource; import javax.inject.Named; import javax.inject.Singleton; @@ -39,6 +36,8 @@ import org.jclouds.http.handlers.BackoffLimitedRetryHandler; import org.jclouds.logging.Logger; import com.google.common.base.Function; +import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.ListeningExecutorService; import com.google.inject.Inject; /** @@ -53,7 +52,7 @@ public class GetAllBlobsInListAndRetryOnFailure implements GetBlobsInListStrateg protected final ListBlobsInContainer getAllBlobMetadata; protected final BackoffLimitedRetryHandler retryHandler; protected final AsyncBlobStore ablobstore; - protected final ExecutorService userExecutor; + protected final ListeningExecutorService userExecutor; @Resource @Named(BlobStoreConstants.BLOBSTORE_LOGGER) protected Logger logger = Logger.NULL; @@ -65,7 +64,7 @@ public class GetAllBlobsInListAndRetryOnFailure implements GetBlobsInListStrateg protected Long maxTime; @Inject - GetAllBlobsInListAndRetryOnFailure(@Named(Constants.PROPERTY_USER_THREADS) ExecutorService userExecutor, + GetAllBlobsInListAndRetryOnFailure(@Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor, ListBlobsInContainer getAllBlobMetadata, AsyncBlobStore ablobstore, BackoffLimitedRetryHandler retryHandler) { this.userExecutor = userExecutor; this.ablobstore = ablobstore; @@ -75,10 +74,10 @@ public class GetAllBlobsInListAndRetryOnFailure implements GetBlobsInListStrateg public Iterable execute(final String container, ListContainerOptions options) { Iterable list = getAllBlobMetadata.execute(container, options); - return transformParallel(list, new Function>() { + return transformParallel(list, new Function>() { @Override - public Future apply(BlobMetadata from) { + public ListenableFuture apply(BlobMetadata from) { return ablobstore.getBlob(container, from.getName()); } diff --git a/blobstore/src/main/java/org/jclouds/blobstore/strategy/internal/MarkersDeleteDirectoryStrategy.java b/blobstore/src/main/java/org/jclouds/blobstore/strategy/internal/MarkersDeleteDirectoryStrategy.java index f6006f7ef9..30344f1c71 100644 --- a/blobstore/src/main/java/org/jclouds/blobstore/strategy/internal/MarkersDeleteDirectoryStrategy.java +++ b/blobstore/src/main/java/org/jclouds/blobstore/strategy/internal/MarkersDeleteDirectoryStrategy.java @@ -23,8 +23,6 @@ import static org.jclouds.concurrent.FutureIterables.awaitCompletion; import java.util.Map; import java.util.Set; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Future; import java.util.concurrent.TimeoutException; import javax.annotation.Resource; @@ -41,6 +39,8 @@ import org.jclouds.logging.Logger; import com.google.common.collect.Maps; import com.google.common.collect.Sets; +import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.ListeningExecutorService; import com.google.inject.Inject; /** @@ -68,7 +68,7 @@ public class MarkersDeleteDirectoryStrategy implements DeleteDirectoryStrategy { private final AsyncBlobStore ablobstore; private final BlobStore blobstore; - private final ExecutorService userExecutor; + private final ListeningExecutorService userExecutor; @Resource @Named(BlobStoreConstants.BLOBSTORE_LOGGER) protected Logger logger = Logger.NULL; @@ -81,7 +81,7 @@ public class MarkersDeleteDirectoryStrategy implements DeleteDirectoryStrategy { @Inject MarkersDeleteDirectoryStrategy( - @Named(Constants.PROPERTY_USER_THREADS) ExecutorService userExecutor, + @Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor, AsyncBlobStore ablobstore, BlobStore blobstore) { this.userExecutor = userExecutor; this.ablobstore = ablobstore; @@ -94,7 +94,7 @@ public class MarkersDeleteDirectoryStrategy implements DeleteDirectoryStrategy { for (String suffix : BlobStoreConstants.DIRECTORY_SUFFIXES) { names.add(directory + suffix); } - Map> responses = Maps.newHashMap(); + Map> responses = Maps.newHashMap(); for (String name : names) { responses.put(name, ablobstore.removeBlob(containerName, name)); } diff --git a/blobstore/src/main/java/org/jclouds/blobstore/strategy/internal/PutBlobsStrategyImpl.java b/blobstore/src/main/java/org/jclouds/blobstore/strategy/internal/PutBlobsStrategyImpl.java index 839bd4f710..74c03a1a28 100644 --- a/blobstore/src/main/java/org/jclouds/blobstore/strategy/internal/PutBlobsStrategyImpl.java +++ b/blobstore/src/main/java/org/jclouds/blobstore/strategy/internal/PutBlobsStrategyImpl.java @@ -22,8 +22,6 @@ import static com.google.common.base.Throwables.propagate; import static org.jclouds.concurrent.FutureIterables.awaitCompletion; import java.util.Map; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Future; import java.util.concurrent.TimeoutException; import javax.annotation.Resource; @@ -39,6 +37,8 @@ import org.jclouds.blobstore.strategy.PutBlobsStrategy; import org.jclouds.logging.Logger; import com.google.common.collect.Maps; +import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.ListeningExecutorService; import com.google.inject.Inject; /** @@ -49,7 +49,7 @@ import com.google.inject.Inject; public class PutBlobsStrategyImpl implements PutBlobsStrategy { private final AsyncBlobStore ablobstore; - private final ExecutorService userExecutor; + private final ListeningExecutorService userExecutor; @Resource @Named(BlobStoreConstants.BLOBSTORE_LOGGER) protected Logger logger = Logger.NULL; @@ -61,7 +61,7 @@ public class PutBlobsStrategyImpl implements PutBlobsStrategy { protected Long maxTime; @Inject - PutBlobsStrategyImpl(@Named(Constants.PROPERTY_USER_THREADS) ExecutorService userExecutor, + PutBlobsStrategyImpl(@Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor, AsyncBlobStore ablobstore) { this.userExecutor = userExecutor; this.ablobstore = ablobstore; @@ -69,7 +69,7 @@ public class PutBlobsStrategyImpl implements PutBlobsStrategy { @Override public void execute(String containerName, Iterable blobs) { - Map> responses = Maps.newLinkedHashMap(); + Map> responses = Maps.newLinkedHashMap(); for (Blob blob : blobs) { responses.put(blob, ablobstore.putBlob(containerName, blob)); } diff --git a/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseBlobIntegrationTest.java b/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseBlobIntegrationTest.java index ce4fdca825..692505fcb6 100644 --- a/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseBlobIntegrationTest.java +++ b/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseBlobIntegrationTest.java @@ -43,7 +43,6 @@ import java.util.Date; import java.util.Map; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; -import java.util.concurrent.Future; import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicInteger; import java.util.zip.GZIPInputStream; @@ -58,7 +57,6 @@ import org.jclouds.blobstore.domain.BlobMetadata; import org.jclouds.blobstore.domain.PageSet; import org.jclouds.blobstore.domain.StorageMetadata; import org.jclouds.blobstore.domain.StorageType; -import org.jclouds.concurrent.Futures; import org.jclouds.crypto.Crypto; import org.jclouds.encryption.internal.JCECrypto; import org.jclouds.http.BaseJettyTest; @@ -84,6 +82,8 @@ import com.google.common.collect.Maps; import com.google.common.io.ByteStreams; import com.google.common.io.Files; import com.google.common.io.InputSupplier; +import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.ListenableFuture; /** * @author Adrian Cole @@ -139,7 +139,7 @@ public class BaseBlobIntegrationTest extends BaseBlobStoreIntegrationTest { final AtomicInteger blobCount = new AtomicInteger(); final String container = getContainerName(); try { - Map> responses = Maps.newHashMap(); + Map> responses = Maps.newHashMap(); for (int i = 0; i < 10; i++) { responses.put(i, this.exec.submit(new Callable() { @@ -179,10 +179,10 @@ public class BaseBlobIntegrationTest extends BaseBlobStoreIntegrationTest { final String name = "constitution.txt"; uploadConstitution(container, name, expectedContentDisposition); - Map> responses = Maps.newHashMap(); + Map> responses = Maps.newHashMap(); for (int i = 0; i < 10; i++) { - responses.put(i, Futures.compose(view.getAsyncBlobStore().getBlob(container, name), + responses.put(i, Futures.transform(view.getAsyncBlobStore().getBlob(container, name), new Function() { @Override diff --git a/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseBlobStoreIntegrationTest.java b/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseBlobStoreIntegrationTest.java index e147f0dfeb..8666118854 100644 --- a/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseBlobStoreIntegrationTest.java +++ b/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseBlobStoreIntegrationTest.java @@ -32,7 +32,6 @@ import java.util.Set; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; import java.util.concurrent.CancellationException; -import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; @@ -63,6 +62,8 @@ import com.google.common.collect.ImmutableSet; import com.google.common.collect.Iterables; import com.google.common.collect.Sets; import com.google.common.reflect.TypeToken; +import com.google.common.util.concurrent.ListeningExecutorService; +import com.google.common.util.concurrent.MoreExecutors; import com.google.inject.Module; public class BaseBlobStoreIntegrationTest extends BaseViewLiveTest { @@ -106,7 +107,7 @@ public class BaseBlobStoreIntegrationTest extends BaseViewLiveTest of(getLoggingModule(), createHttpModule()); } - protected ExecutorService exec; + protected ListeningExecutorService exec; /** * we are doing this at a class level, as the context.getBlobStore() object is going to be shared @@ -116,7 +117,7 @@ public class BaseBlobStoreIntegrationTest extends BaseViewLiveTest imageExtension) { super(context, credentialStore, images, sizes, locations, listNodesStrategy, getImageStrategy, getNodeMetadataStrategy, runNodesAndAddToSetStrategy, rebootNodeStrategy, destroyNodeStrategy, resumeNodeStrategy, suspendNodeStrategy, templateBuilderProvider, templateOptionsProvider, nodeRunning, nodeTerminated, nodeSuspended, initScriptRunnerFactory, initAdminAccess, runScriptOnNodeFactory, - persistNodeCredentials, timeouts, executor, imageExtension); + persistNodeCredentials, timeouts, userExecutor, imageExtension); this.cleanupOrphanKeys = cleanupOrphanKeys; } diff --git a/common/trmk/src/main/java/org/jclouds/trmk/vcloud_0_8/compute/strategy/TerremarkEncodeTagIntoNameRunNodesAndAddToSetStrategy.java b/common/trmk/src/main/java/org/jclouds/trmk/vcloud_0_8/compute/strategy/TerremarkEncodeTagIntoNameRunNodesAndAddToSetStrategy.java index 37f2bdd09b..0a0976254b 100644 --- a/common/trmk/src/main/java/org/jclouds/trmk/vcloud_0_8/compute/strategy/TerremarkEncodeTagIntoNameRunNodesAndAddToSetStrategy.java +++ b/common/trmk/src/main/java/org/jclouds/trmk/vcloud_0_8/compute/strategy/TerremarkEncodeTagIntoNameRunNodesAndAddToSetStrategy.java @@ -21,8 +21,6 @@ package org.jclouds.trmk.vcloud_0_8.compute.strategy; import java.net.URI; import java.util.Map; import java.util.Set; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Future; import javax.inject.Inject; import javax.inject.Named; @@ -41,6 +39,8 @@ import org.jclouds.domain.LocationScope; import org.jclouds.trmk.vcloud_0_8.compute.options.TerremarkVCloudTemplateOptions; import com.google.common.collect.Multimap; +import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.ListeningExecutorService; /** * creates futures that correlate to @@ -58,15 +58,15 @@ public class TerremarkEncodeTagIntoNameRunNodesAndAddToSetStrategy extends Creat ListNodesStrategy listNodesStrategy, GroupNamingConvention.Factory namingConvention, CustomizeNodeAndAddToGoodMapOrPutExceptionIntoBadMap.Factory customizeNodeAndAddToGoodMapOrPutExceptionIntoBadMapFactory, - @Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor, + @Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor, CreateNewKeyPairUnlessUserSpecifiedOtherwise createNewKeyPairUnlessUserSpecifiedOtherwise) { - super(addNodeWithTagStrategy, listNodesStrategy, namingConvention, executor, + super(addNodeWithTagStrategy, listNodesStrategy, namingConvention, userExecutor, customizeNodeAndAddToGoodMapOrPutExceptionIntoBadMapFactory); this.createNewKeyPairUnlessUserSpecifiedOtherwise = createNewKeyPairUnlessUserSpecifiedOtherwise; } @Override - public Map> execute(String tag, int count, Template template, Set goodNodes, + public Map> execute(String tag, int count, Template template, Set goodNodes, Map badNodes, Multimap customizationResponses) { assert template.getLocation().getParent().getScope() == LocationScope.REGION : "template location should have a parent of org, which should be mapped to region: " + template.getLocation(); diff --git a/common/trmk/src/main/java/org/jclouds/trmk/vcloud_0_8/compute/suppliers/VCloudHardwareSupplier.java b/common/trmk/src/main/java/org/jclouds/trmk/vcloud_0_8/compute/suppliers/VCloudHardwareSupplier.java index d3e6c4fc55..2ad4913736 100644 --- a/common/trmk/src/main/java/org/jclouds/trmk/vcloud_0_8/compute/suppliers/VCloudHardwareSupplier.java +++ b/common/trmk/src/main/java/org/jclouds/trmk/vcloud_0_8/compute/suppliers/VCloudHardwareSupplier.java @@ -26,8 +26,6 @@ import static org.jclouds.concurrent.FutureIterables.transformParallel; import java.util.Map; import java.util.Set; import java.util.concurrent.Callable; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Future; import javax.annotation.Resource; import javax.inject.Inject; @@ -42,6 +40,8 @@ import org.jclouds.trmk.vcloud_0_8.domain.Org; import com.google.common.base.Function; import com.google.common.base.Supplier; +import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.ListeningExecutorService; /** * @author Adrian Cole @@ -55,27 +55,27 @@ public class VCloudHardwareSupplier implements Supplier> private final Supplier> orgMap; private final Function> sizesInOrg; - private final ExecutorService executor; + private final ListeningExecutorService userExecutor; @Inject VCloudHardwareSupplier(Supplier> orgMap, Function> sizesInOrg, - @Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor) { + @Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor) { this.orgMap = checkNotNull(orgMap, "orgMap"); this.sizesInOrg = checkNotNull(sizesInOrg, "sizesInOrg"); - this.executor = checkNotNull(executor, "executor"); + this.userExecutor = checkNotNull(userExecutor, "userExecutor"); } @Override public Set get() { Iterable orgs = checkNotNull(orgMap.get().values(), "orgs"); Iterable> sizes = transformParallel(orgs, - new Function>>() { + new Function>>() { @Override - public Future> apply(final Org from) { + public ListenableFuture> apply(final Org from) { checkNotNull(from, "org"); - return executor.submit(new Callable>() { + return userExecutor.submit(new Callable>() { @Override public Iterable call() throws Exception { @@ -89,7 +89,7 @@ public class VCloudHardwareSupplier implements Supplier> }); } - }, executor, null, logger, "sizes in " + orgs); + }, userExecutor, null, logger, "sizes in " + orgs); return newLinkedHashSet(concat(sizes)); } } diff --git a/common/trmk/src/main/java/org/jclouds/trmk/vcloud_0_8/compute/suppliers/VCloudImageSupplier.java b/common/trmk/src/main/java/org/jclouds/trmk/vcloud_0_8/compute/suppliers/VCloudImageSupplier.java index 23158e922b..61816cab16 100644 --- a/common/trmk/src/main/java/org/jclouds/trmk/vcloud_0_8/compute/suppliers/VCloudImageSupplier.java +++ b/common/trmk/src/main/java/org/jclouds/trmk/vcloud_0_8/compute/suppliers/VCloudImageSupplier.java @@ -26,8 +26,6 @@ import static org.jclouds.concurrent.FutureIterables.transformParallel; import java.util.Map; import java.util.Set; import java.util.concurrent.Callable; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Future; import javax.annotation.Resource; import javax.inject.Inject; @@ -42,6 +40,8 @@ import org.jclouds.trmk.vcloud_0_8.domain.Org; import com.google.common.base.Function; import com.google.common.base.Supplier; +import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.ListeningExecutorService; /** * @author Adrian Cole @@ -55,27 +55,27 @@ public class VCloudImageSupplier implements Supplier> { private final Supplier> orgMap; private final Function> imagesInOrg; - private final ExecutorService executor; + private final ListeningExecutorService userExecutor; @Inject VCloudImageSupplier(Supplier> orgMap, Function> imagesInOrg, - @Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor) { + @Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor) { this.orgMap = checkNotNull(orgMap, "orgMap"); this.imagesInOrg = checkNotNull(imagesInOrg, "imagesInOrg"); - this.executor = checkNotNull(executor, "executor"); + this.userExecutor = checkNotNull(userExecutor, "userExecutor"); } @Override public Set get() { Iterable orgs = checkNotNull(orgMap.get().values(), "orgs"); Iterable> images = transformParallel(orgs, - new Function>>() { + new Function>>() { @Override - public Future> apply(final Org from) { + public ListenableFuture> apply(final Org from) { checkNotNull(from, "org"); - return executor.submit(new Callable>() { + return userExecutor.submit(new Callable>() { @Override public Iterable call() throws Exception { @@ -89,7 +89,7 @@ public class VCloudImageSupplier implements Supplier> { }); } - }, executor, null, logger, "images in " + orgs); + }, userExecutor, null, logger, "images in " + orgs); return newLinkedHashSet(concat(images)); } } diff --git a/common/trmk/src/main/java/org/jclouds/trmk/vcloud_0_8/functions/AllCatalogItemsInCatalog.java b/common/trmk/src/main/java/org/jclouds/trmk/vcloud_0_8/functions/AllCatalogItemsInCatalog.java index 44f3a8bc53..0493c5f60f 100644 --- a/common/trmk/src/main/java/org/jclouds/trmk/vcloud_0_8/functions/AllCatalogItemsInCatalog.java +++ b/common/trmk/src/main/java/org/jclouds/trmk/vcloud_0_8/functions/AllCatalogItemsInCatalog.java @@ -21,9 +21,6 @@ package org.jclouds.trmk.vcloud_0_8.functions; import static com.google.common.collect.Iterables.filter; import static org.jclouds.concurrent.FutureIterables.transformParallel; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Future; - import javax.annotation.Resource; import javax.inject.Inject; import javax.inject.Named; @@ -39,6 +36,8 @@ import org.jclouds.trmk.vcloud_0_8.domain.ReferenceType; import com.google.common.base.Function; import com.google.common.base.Predicate; +import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.ListeningExecutorService; /** * @author Adrian Cole @@ -49,35 +48,26 @@ public class AllCatalogItemsInCatalog implements Function apply(Catalog from) { - - Iterable catalogItems = transformParallel(filter(from.values(), new Predicate() { - - @Override + return transformParallel(filter(from.values(), new Predicate() { public boolean apply(ReferenceType input) { return input.getType().equals(TerremarkVCloudMediaType.CATALOGITEM_XML); } - - }), new Function>() { - - @SuppressWarnings("unchecked") - @Override - public Future apply(ReferenceType from) { - return (Future) aclient.getCatalogItem(from.getHref()); + }), new Function>() { + public ListenableFuture apply(ReferenceType from) { + return aclient.getCatalogItem(from.getHref()); } - - }, executor, null, logger, "catalogItems in " + from.getHref()); - return catalogItems; + }, userExecutor, null, logger, "catalogItems in " + from.getHref()); } } diff --git a/common/trmk/src/main/java/org/jclouds/trmk/vcloud_0_8/functions/AllCatalogsInOrg.java b/common/trmk/src/main/java/org/jclouds/trmk/vcloud_0_8/functions/AllCatalogsInOrg.java index a140dfd604..91096eb949 100644 --- a/common/trmk/src/main/java/org/jclouds/trmk/vcloud_0_8/functions/AllCatalogsInOrg.java +++ b/common/trmk/src/main/java/org/jclouds/trmk/vcloud_0_8/functions/AllCatalogsInOrg.java @@ -20,9 +20,6 @@ package org.jclouds.trmk.vcloud_0_8.functions; import static org.jclouds.concurrent.FutureIterables.transformParallel; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Future; - import javax.annotation.Resource; import javax.inject.Inject; import javax.inject.Named; @@ -36,6 +33,8 @@ import org.jclouds.trmk.vcloud_0_8.domain.Org; import org.jclouds.trmk.vcloud_0_8.domain.ReferenceType; import com.google.common.base.Function; +import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.ListeningExecutorService; /** * @author Adrian Cole @@ -46,25 +45,21 @@ public class AllCatalogsInOrg implements Function apply(final Org org) { - Iterable catalogs = transformParallel(org.getCatalogs().values(), - new Function>() { - @SuppressWarnings("unchecked") - @Override - public Future apply(ReferenceType from) { - return (Future) aclient.getCatalog(from.getHref()); + return transformParallel(org.getCatalogs().values(), + new Function>() { + public ListenableFuture apply(ReferenceType from) { + return aclient.getCatalog(from.getHref()); } - - }, executor, null, logger, "catalogs in " + org.getName()); - return catalogs; + }, userExecutor, null, logger, "catalogs in " + org.getName()); } } diff --git a/common/trmk/src/main/java/org/jclouds/trmk/vcloud_0_8/functions/AllVDCsInOrg.java b/common/trmk/src/main/java/org/jclouds/trmk/vcloud_0_8/functions/AllVDCsInOrg.java index 97a4d6b672..0e6974c4d2 100644 --- a/common/trmk/src/main/java/org/jclouds/trmk/vcloud_0_8/functions/AllVDCsInOrg.java +++ b/common/trmk/src/main/java/org/jclouds/trmk/vcloud_0_8/functions/AllVDCsInOrg.java @@ -20,9 +20,6 @@ package org.jclouds.trmk.vcloud_0_8.functions; import static org.jclouds.concurrent.FutureIterables.transformParallel; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Future; - import javax.annotation.Resource; import javax.inject.Inject; import javax.inject.Named; @@ -35,6 +32,8 @@ import org.jclouds.trmk.vcloud_0_8.domain.Org; import org.jclouds.trmk.vcloud_0_8.domain.ReferenceType; import com.google.common.base.Function; +import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.ListeningExecutorService; /** * @author Adrian Cole @@ -45,26 +44,22 @@ public class AllVDCsInOrg implements Function apply(final Org org) { - - Iterable catalogItems = transformParallel(org.getVDCs().values(), - new Function>() { - @Override - public Future apply(ReferenceType from) { + return transformParallel(org.getVDCs().values(), + new Function>() { + public ListenableFuture apply(ReferenceType from) { return aclient.getVDC(from.getHref()); } - - }, executor, null, logger, "vdcs in org " + org.getName()); - return catalogItems; + }, userExecutor, null, logger, "vdcs in org " + org.getName()); } } diff --git a/common/trmk/src/main/java/org/jclouds/trmk/vcloud_0_8/functions/OrgsForLocations.java b/common/trmk/src/main/java/org/jclouds/trmk/vcloud_0_8/functions/OrgsForLocations.java index 3b33fcaf91..afd4c1a550 100644 --- a/common/trmk/src/main/java/org/jclouds/trmk/vcloud_0_8/functions/OrgsForLocations.java +++ b/common/trmk/src/main/java/org/jclouds/trmk/vcloud_0_8/functions/OrgsForLocations.java @@ -23,8 +23,6 @@ import static com.google.common.collect.Iterables.transform; import static org.jclouds.concurrent.FutureIterables.transformParallel; import java.net.URI; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Future; import javax.annotation.Resource; import javax.inject.Inject; @@ -41,6 +39,8 @@ import org.jclouds.trmk.vcloud_0_8.domain.Org; import com.google.common.base.Function; import com.google.common.base.Predicate; import com.google.common.collect.Sets; +import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.ListeningExecutorService; /** * @author Adrian Cole @@ -50,12 +50,12 @@ public class OrgsForLocations implements Function, @Resource public Logger logger = Logger.NULL; private final TerremarkVCloudAsyncClient aclient; - private final ExecutorService executor; + private final ListeningExecutorService userExecutor; @Inject - OrgsForLocations(TerremarkVCloudAsyncClient aclient, @Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor) { + OrgsForLocations(TerremarkVCloudAsyncClient aclient, @Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor) { this.aclient = aclient; - this.executor = executor; + this.userExecutor = userExecutor; } /** @@ -64,28 +64,18 @@ public class OrgsForLocations implements Function, */ @Override public Iterable apply(Iterable from) { - return transformParallel(Sets.newLinkedHashSet(transform(filter(from, new Predicate() { - - @Override public boolean apply(Location input) { return input.getScope() == LocationScope.ZONE; } - }), new Function() { - - @Override public URI apply(Location from) { return URI.create(from.getParent().getId()); } - - })), new Function>() { - @Override - public Future apply(URI from) { + })), new Function>() { + public ListenableFuture apply(URI from) { return aclient.getOrg(from); } - - }, executor, null, logger, "organizations for uris"); + }, userExecutor, null, logger, "organizations for uris"); } - } diff --git a/common/trmk/src/main/java/org/jclouds/trmk/vcloud_0_8/functions/OrgsForNames.java b/common/trmk/src/main/java/org/jclouds/trmk/vcloud_0_8/functions/OrgsForNames.java index 95b47ed134..69011fe50d 100644 --- a/common/trmk/src/main/java/org/jclouds/trmk/vcloud_0_8/functions/OrgsForNames.java +++ b/common/trmk/src/main/java/org/jclouds/trmk/vcloud_0_8/functions/OrgsForNames.java @@ -20,9 +20,6 @@ package org.jclouds.trmk.vcloud_0_8.functions; import static org.jclouds.concurrent.FutureIterables.transformParallel; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Future; - import javax.annotation.Resource; import javax.inject.Inject; import javax.inject.Named; @@ -34,6 +31,8 @@ import org.jclouds.trmk.vcloud_0_8.TerremarkVCloudAsyncClient; import org.jclouds.trmk.vcloud_0_8.domain.Org; import com.google.common.base.Function; +import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.ListeningExecutorService; /** * @author Adrian Cole @@ -43,23 +42,21 @@ public class OrgsForNames implements Function, Iterable apply(Iterable from) { - return transformParallel(from, new Function>() { - @Override - public Future apply(String from) { + return transformParallel(from, new Function>() { + public ListenableFuture apply(String from) { return aclient.findOrgNamed(from); } - - }, executor, null, logger, "organizations for names"); + }, userExecutor, null, logger, "organizations for names"); } } diff --git a/common/trmk/src/main/java/org/jclouds/trmk/vcloud_0_8/functions/VAppTemplatesForCatalogItems.java b/common/trmk/src/main/java/org/jclouds/trmk/vcloud_0_8/functions/VAppTemplatesForCatalogItems.java index 04eb27ffcd..0ab50bd981 100644 --- a/common/trmk/src/main/java/org/jclouds/trmk/vcloud_0_8/functions/VAppTemplatesForCatalogItems.java +++ b/common/trmk/src/main/java/org/jclouds/trmk/vcloud_0_8/functions/VAppTemplatesForCatalogItems.java @@ -21,9 +21,6 @@ package org.jclouds.trmk.vcloud_0_8.functions; import static com.google.common.collect.Iterables.filter; import static org.jclouds.concurrent.FutureIterables.transformParallel; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Future; - import javax.annotation.Resource; import javax.inject.Inject; import javax.inject.Named; @@ -39,6 +36,8 @@ import org.jclouds.trmk.vcloud_0_8.domain.VAppTemplate; import com.google.common.base.Function; import com.google.common.base.Predicate; +import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.ListeningExecutorService; /** * @author Adrian Cole @@ -50,31 +49,26 @@ public class VAppTemplatesForCatalogItems implements @Named(ComputeServiceConstants.COMPUTE_LOGGER) public Logger logger = Logger.NULL; private final TerremarkVCloudAsyncClient aclient; - private final ExecutorService executor; + private final ListeningExecutorService userExecutor; @Inject VAppTemplatesForCatalogItems(TerremarkVCloudAsyncClient aclient, - @Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor) { + @Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor) { this.aclient = aclient; - this.executor = executor; + this.userExecutor = userExecutor; } @Override public Iterable apply(Iterable from) { return transformParallel(filter(from, new Predicate() { - - @Override public boolean apply(CatalogItem input) { return input.getEntity().getType().equals(TerremarkVCloudMediaType.VAPPTEMPLATE_XML); } - - }), new Function>() { - @Override - public Future apply(CatalogItem from) { + }), new Function>() { + public ListenableFuture apply(CatalogItem from) { return aclient.getVAppTemplate(from.getEntity().getHref()); } - - }, executor, null, logger, "vappTemplates in"); + }, userExecutor, null, logger, "vappTemplates in"); } } diff --git a/common/trmk/src/main/java/org/jclouds/trmk/vcloud_0_8/functions/VAppTemplatesForResourceEntities.java b/common/trmk/src/main/java/org/jclouds/trmk/vcloud_0_8/functions/VAppTemplatesForResourceEntities.java index 7b52b0f0c5..ba3168c712 100644 --- a/common/trmk/src/main/java/org/jclouds/trmk/vcloud_0_8/functions/VAppTemplatesForResourceEntities.java +++ b/common/trmk/src/main/java/org/jclouds/trmk/vcloud_0_8/functions/VAppTemplatesForResourceEntities.java @@ -22,9 +22,6 @@ import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.collect.Iterables.filter; import static org.jclouds.concurrent.FutureIterables.transformParallel; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Future; - import javax.annotation.Resource; import javax.inject.Inject; import javax.inject.Named; @@ -40,6 +37,8 @@ import org.jclouds.trmk.vcloud_0_8.domain.VAppTemplate; import com.google.common.base.Function; import com.google.common.base.Predicate; +import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.ListeningExecutorService; /** * @author Adrian Cole @@ -51,31 +50,26 @@ public class VAppTemplatesForResourceEntities implements @Named(ComputeServiceConstants.COMPUTE_LOGGER) public Logger logger = Logger.NULL; private final TerremarkVCloudAsyncClient aclient; - private final ExecutorService executor; + private final ListeningExecutorService userExecutor; @Inject VAppTemplatesForResourceEntities(TerremarkVCloudAsyncClient aclient, - @Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor) { + @Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor) { this.aclient = aclient; - this.executor = executor; + this.userExecutor = userExecutor; } @Override public Iterable apply(Iterable from) { return transformParallel(filter(checkNotNull(from, "named resources"), new Predicate() { - - @Override public boolean apply(ReferenceType input) { return input.getType().equals(TerremarkVCloudMediaType.VAPPTEMPLATE_XML); } - - }), new Function>() { - @Override - public Future apply(ReferenceType from) { + }), new Function>() { + public ListenableFuture apply(ReferenceType from) { return aclient.getVAppTemplate(from.getHref()); } - - }, executor, null, logger, "vappTemplates in"); + }, userExecutor, null, logger, "vappTemplates in"); } } diff --git a/compute/src/main/java/org/jclouds/compute/callables/BlockUntilInitScriptStatusIsZeroThenReturnOutput.java b/compute/src/main/java/org/jclouds/compute/callables/BlockUntilInitScriptStatusIsZeroThenReturnOutput.java index 2f994b1057..dd385742bf 100644 --- a/compute/src/main/java/org/jclouds/compute/callables/BlockUntilInitScriptStatusIsZeroThenReturnOutput.java +++ b/compute/src/main/java/org/jclouds/compute/callables/BlockUntilInitScriptStatusIsZeroThenReturnOutput.java @@ -23,7 +23,6 @@ import static com.google.common.base.Preconditions.checkNotNull; import java.util.Date; import java.util.concurrent.CancellationException; import java.util.concurrent.ExecutionException; -import java.util.concurrent.ExecutorService; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; @@ -36,6 +35,7 @@ import org.jclouds.compute.events.StatementOnNodeFailure; import org.jclouds.compute.reference.ComputeServiceConstants; import org.jclouds.logging.Logger; import org.jclouds.predicates.RetryablePredicate; +import org.jclouds.scriptbuilder.InitScript; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Objects; @@ -44,6 +44,7 @@ import com.google.common.base.Predicates; import com.google.common.eventbus.EventBus; import com.google.common.primitives.Ints; import com.google.common.util.concurrent.AbstractFuture; +import com.google.common.util.concurrent.ListeningExecutorService; import com.google.inject.Inject; import com.google.inject.assistedinject.Assisted; import com.google.inject.name.Named; @@ -63,7 +64,7 @@ public class BlockUntilInitScriptStatusIsZeroThenReturnOutput extends AbstractFu @Named(ComputeServiceConstants.COMPUTE_LOGGER) protected Logger logger = Logger.NULL; - private final ExecutorService userThreads; + private final ListeningExecutorService userExecutor; private final EventBus eventBus; private final SudoAwareInitManager commandRunner; @@ -75,19 +76,19 @@ public class BlockUntilInitScriptStatusIsZeroThenReturnOutput extends AbstractFu @Inject public BlockUntilInitScriptStatusIsZeroThenReturnOutput( - @Named(Constants.PROPERTY_USER_THREADS) ExecutorService userThreads, EventBus eventBus, + @Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor, EventBus eventBus, ComputeServiceConstants.InitStatusProperties properties, @Assisted SudoAwareInitManager commandRunner) { - this(userThreads, eventBus, Predicates. alwaysTrue(), commandRunner); + this(userExecutor, eventBus, Predicates. alwaysTrue(), commandRunner); // this is mutable only until we can determine how to decouple "this" from here notRunningAnymore = new LoopUntilTrueOrThrowCancellationException(new ExitStatusOfCommandGreaterThanZero( commandRunner), properties.initStatusMaxPeriod, properties.initStatusInitialPeriod, this); } @VisibleForTesting - public BlockUntilInitScriptStatusIsZeroThenReturnOutput(ExecutorService userThreads, EventBus eventBus, + public BlockUntilInitScriptStatusIsZeroThenReturnOutput(ListeningExecutorService userExecutor, EventBus eventBus, Predicate notRunningAnymore, SudoAwareInitManager commandRunner) { this.commandRunner = checkNotNull(commandRunner, "commandRunner"); - this.userThreads = checkNotNull(userThreads, "userThreads"); + this.userExecutor = checkNotNull(userExecutor, "userExecutor"); this.eventBus = checkNotNull(eventBus, "eventBus"); this.notRunningAnymore = checkNotNull(notRunningAnymore, "notRunningAnymore"); } @@ -136,7 +137,7 @@ public class BlockUntilInitScriptStatusIsZeroThenReturnOutput extends AbstractFu * place */ public BlockUntilInitScriptStatusIsZeroThenReturnOutput init() { - userThreads.submit(this); + userExecutor.submit(this); return this; } diff --git a/compute/src/main/java/org/jclouds/compute/internal/BaseComputeService.java b/compute/src/main/java/org/jclouds/compute/internal/BaseComputeService.java index 5c4eedba47..57216ca446 100644 --- a/compute/src/main/java/org/jclouds/compute/internal/BaseComputeService.java +++ b/compute/src/main/java/org/jclouds/compute/internal/BaseComputeService.java @@ -24,7 +24,6 @@ import static com.google.common.base.Predicates.notNull; import static com.google.common.base.Throwables.propagate; import static com.google.common.collect.Iterables.filter; import static com.google.common.collect.Maps.newLinkedHashMap; -import static com.google.common.collect.Sets.filter; import static com.google.common.collect.Sets.newLinkedHashSet; import static com.google.common.util.concurrent.Futures.immediateFuture; import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_RUNNING; @@ -40,10 +39,8 @@ import java.util.Map; import java.util.NoSuchElementException; import java.util.Set; import java.util.concurrent.Callable; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Future; -import java.util.concurrent.TimeoutException; import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicReference; import javax.annotation.Resource; @@ -65,10 +62,10 @@ import org.jclouds.compute.domain.ExecResponse; import org.jclouds.compute.domain.Hardware; import org.jclouds.compute.domain.Image; import org.jclouds.compute.domain.NodeMetadata; +import org.jclouds.compute.domain.NodeMetadata.Status; import org.jclouds.compute.domain.NodeMetadataBuilder; import org.jclouds.compute.domain.Template; import org.jclouds.compute.domain.TemplateBuilder; -import org.jclouds.compute.domain.NodeMetadata.Status; import org.jclouds.compute.extensions.ImageExtension; import org.jclouds.compute.options.RunScriptOptions; import org.jclouds.compute.options.TemplateOptions; @@ -107,6 +104,7 @@ import com.google.common.collect.LinkedHashMultimap; import com.google.common.collect.Multimap; import com.google.common.util.concurrent.Atomics; import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.ListeningExecutorService; /** * @@ -143,7 +141,7 @@ public class BaseComputeService implements ComputeService { private final InitAdminAccess initAdminAccess; private final PersistNodeCredentials persistNodeCredentials; private final RunScriptOnNode.Factory runScriptOnNodeFactory; - private final ExecutorService executor; + private final ListeningExecutorService userExecutor; private final Optional imageExtension; @Inject @@ -161,7 +159,7 @@ public class BaseComputeService implements ComputeService { @Named(TIMEOUT_NODE_SUSPENDED) Predicate> nodeSuspended, InitializeRunScriptOnNodeOrPlaceInBadMap.Factory initScriptRunnerFactory, InitAdminAccess initAdminAccess, RunScriptOnNode.Factory runScriptOnNodeFactory, PersistNodeCredentials persistNodeCredentials, - Timeouts timeouts, @Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor, + Timeouts timeouts, @Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor, Optional imageExtension) { this.context = checkNotNull(context, "context"); this.credentialStore = checkNotNull(credentialStore, "credentialStore"); @@ -186,8 +184,8 @@ public class BaseComputeService implements ComputeService { this.initAdminAccess = checkNotNull(initAdminAccess, "initAdminAccess"); this.runScriptOnNodeFactory = checkNotNull(runScriptOnNodeFactory, "runScriptOnNodeFactory"); this.persistNodeCredentials = checkNotNull(persistNodeCredentials, "persistNodeCredentials"); - this.executor = checkNotNull(executor, "executor"); - this.imageExtension = imageExtension; + this.userExecutor = checkNotNull(userExecutor, "userExecutor"); + this.imageExtension = checkNotNull(imageExtension, "imageExtension"); } /** @@ -213,11 +211,11 @@ public class BaseComputeService implements ComputeService { if (template.getOptions().getRunScript() != null) initAdminAccess.visit(template.getOptions().getRunScript()); - Map> responses = runNodesAndAddToSetStrategy.execute(group, count, template, goodNodes, badNodes, + Map> responses = runNodesAndAddToSetStrategy.execute(group, count, template, goodNodes, badNodes, customizationResponses); Map executionExceptions; try { - executionExceptions = awaitCompletion(responses, executor, null, logger, "createNodesInGroup(" + group + ")"); + executionExceptions = awaitCompletion(responses, userExecutor, null, logger, "createNodesInGroup(" + group + ")"); } catch (TimeoutException te) { throw propagate(te); } @@ -257,29 +255,24 @@ public class BaseComputeService implements ComputeService { @Override public Set destroyNodesMatching(Predicate filter) { logger.debug(">> destroying nodes matching(%s)", filter); - Set set = newLinkedHashSet(filter(transformParallel(nodesMatchingFilterAndNotTerminated(filter), - new Function>() { + Set set = ImmutableSet.copyOf(transformParallel(nodesMatchingFilterAndNotTerminated(filter), + new Function>() { // TODO make an async interface instead of re-wrapping @Override - public Future apply(final NodeMetadata from) { - return executor.submit(new Callable() { - - @Nullable - @Override + public ListenableFuture apply(final NodeMetadata from) { + return userExecutor.submit(new Callable() { public NodeMetadata call() throws Exception { doDestroyNode(from.getId()); return from; } - - @Override public String toString() { return "destroyNode(" + from.getId() + ")"; } }); } - }, executor, null, logger, "destroyNodesMatching(" + filter + ")"), notNull())); + }, userExecutor, null, logger, "destroyNodesMatching(" + filter + ")")); logger.debug("<< destroyed(%d)", set.size()); cleanUpIncidentalResourcesOfDeadNodes(set); @@ -432,15 +425,15 @@ public class BaseComputeService implements ComputeService { public void rebootNodesMatching(Predicate filter) { logger.debug(">> rebooting nodes matching(%s)", filter); transformParallel(nodesMatchingFilterAndNotTerminatedExceptionIfNotFound(filter), - new Function>() { + new Function>() { // TODO use native async @Override - public Future apply(NodeMetadata from) { + public ListenableFuture apply(NodeMetadata from) { rebootNode(from.getId()); return immediateFuture(null); } - }, executor, null, logger, "rebootNodesMatching(" + filter + ")"); + }, userExecutor, null, logger, "rebootNodesMatching(" + filter + ")"); logger.debug("<< rebooted"); } @@ -463,15 +456,15 @@ public class BaseComputeService implements ComputeService { public void resumeNodesMatching(Predicate filter) { logger.debug(">> resuming nodes matching(%s)", filter); transformParallel(nodesMatchingFilterAndNotTerminatedExceptionIfNotFound(filter), - new Function>() { + new Function>() { // TODO use native async @Override - public Future apply(NodeMetadata from) { + public ListenableFuture apply(NodeMetadata from) { resumeNode(from.getId()); return immediateFuture(null); } - }, executor, null, logger, "resumeNodesMatching(" + filter + ")"); + }, userExecutor, null, logger, "resumeNodesMatching(" + filter + ")"); logger.debug("<< resumed"); } @@ -494,15 +487,15 @@ public class BaseComputeService implements ComputeService { public void suspendNodesMatching(Predicate filter) { logger.debug(">> suspending nodes matching(%s)", filter); transformParallel(nodesMatchingFilterAndNotTerminatedExceptionIfNotFound(filter), - new Function>() { + new Function>() { // TODO use native async @Override - public Future apply(NodeMetadata from) { + public ListenableFuture apply(NodeMetadata from) { suspendNode(from.getId()); return immediateFuture(null); } - }, executor, null, logger, "suspendNodesMatching(" + filter + ")"); + }, userExecutor, null, logger, "suspendNodesMatching(" + filter + ")"); logger.debug("<< suspended"); } @@ -543,7 +536,7 @@ public class BaseComputeService implements ComputeService { Map goodNodes = newLinkedHashMap(); Map badNodes = newLinkedHashMap(); - Map> responses = newLinkedHashMap(); + Map> responses = newLinkedHashMap(); Map exceptions = ImmutableMap. of(); initAdminAccess.visit(runScript); @@ -552,11 +545,11 @@ public class BaseComputeService implements ComputeService { nodesMatchingFilterAndNotTerminatedExceptionIfNotFound(filter), runScript, options, badNodes); if (Iterables.size(scriptRunners) > 0) { for (RunScriptOnNode runner : scriptRunners) { - responses.put(runner.getNode(), executor.submit(new RunScriptOnNodeAndAddToGoodMapOrPutExceptionIntoBadMap( + responses.put(runner.getNode(), userExecutor.submit(new RunScriptOnNodeAndAddToGoodMapOrPutExceptionIntoBadMap( runner, goodNodes, badNodes))); } try { - exceptions = awaitCompletion(responses, executor, null, logger, "runScriptOnNodesMatching(" + filter + ")"); + exceptions = awaitCompletion(responses, userExecutor, null, logger, "runScriptOnNodesMatching(" + filter + ")"); } catch (TimeoutException te) { throw propagate(te); } @@ -638,22 +631,18 @@ public class BaseComputeService implements ComputeService { final NodeMetadata node1 = updateNodeWithCredentialsIfPresent(node, options); ListenableFuture response = runScriptOnNodeFactory.submit(node1, runScript, options); response.addListener(new Runnable() { - - @Override public void run() { persistNodeCredentials.ifAdminAccess(runScript).apply(node1); } - - }, executor); + }, userExecutor); return response; } - private Iterable transformNodesIntoInitializedScriptRunners( + private Iterable transformNodesIntoInitializedScriptRunners( Iterable nodes, Statement script, RunScriptOptions options, Map badNodes) { - return filter( - transformParallel(nodes, new TransformNodesIntoInitializedScriptRunners(script, options, badNodes), - executor, null, logger, "initialize script runners"), notNull()); + return filter(transformParallel(nodes, new TransformNodesIntoInitializedScriptRunners(script, options, badNodes), + userExecutor, null, logger, "initialize script runners"), notNull()); } private Set detailsOnAllNodes() { @@ -690,7 +679,7 @@ public class BaseComputeService implements ComputeService { } private final class TransformNodesIntoInitializedScriptRunners implements - Function> { + Function> { private final Map badNodes; private final Statement script; private final RunScriptOptions options; @@ -703,9 +692,9 @@ public class BaseComputeService implements ComputeService { } @Override - public Future apply(NodeMetadata node) { + public ListenableFuture apply(NodeMetadata node) { node = updateNodeWithCredentialsIfPresent(node, options); - return executor.submit(initScriptRunnerFactory.create(node, script, options, badNodes)); + return userExecutor.submit(initScriptRunnerFactory.create(node, script, options, badNodes)); } } diff --git a/compute/src/main/java/org/jclouds/compute/internal/UtilsImpl.java b/compute/src/main/java/org/jclouds/compute/internal/UtilsImpl.java index 903c4dd880..9e1f00b977 100644 --- a/compute/src/main/java/org/jclouds/compute/internal/UtilsImpl.java +++ b/compute/src/main/java/org/jclouds/compute/internal/UtilsImpl.java @@ -19,7 +19,6 @@ package org.jclouds.compute.internal; import java.util.Map; -import java.util.concurrent.ExecutorService; import javax.inject.Named; import javax.inject.Singleton; @@ -40,6 +39,7 @@ import org.jclouds.xml.XMLParser; import com.google.common.base.Function; import com.google.common.eventbus.EventBus; +import com.google.common.util.concurrent.ListeningExecutorService; import com.google.inject.Inject; import com.google.inject.Injector; @@ -55,11 +55,11 @@ public class UtilsImpl extends org.jclouds.rest.internal.UtilsImpl implements Ut @Inject UtilsImpl(Injector injector, Json json, XMLParser xml, HttpClient simpleClient, HttpAsyncClient simpleAsyncClient, - Crypto encryption, DateService date, @Named(Constants.PROPERTY_USER_THREADS) ExecutorService userThreads, - @Named(Constants.PROPERTY_IO_WORKER_THREADS) ExecutorService ioThreads, EventBus eventBus, + Crypto encryption, DateService date, @Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor, + @Named(Constants.PROPERTY_IO_WORKER_THREADS) ListeningExecutorService ioExecutor, EventBus eventBus, Map credentialStore, LoggerFactory loggerFactory, Function sshForNode) { - super(injector, json, xml, simpleClient, simpleAsyncClient, encryption, date, userThreads, ioThreads, eventBus, + super(injector, json, xml, simpleClient, simpleAsyncClient, encryption, date, userExecutor, ioExecutor, eventBus, credentialStore, loggerFactory); this.sshForNode = sshForNode; } diff --git a/compute/src/main/java/org/jclouds/compute/strategy/CreateNodesInGroupThenAddToSet.java b/compute/src/main/java/org/jclouds/compute/strategy/CreateNodesInGroupThenAddToSet.java index c28ce66526..8e1f49445a 100644 --- a/compute/src/main/java/org/jclouds/compute/strategy/CreateNodesInGroupThenAddToSet.java +++ b/compute/src/main/java/org/jclouds/compute/strategy/CreateNodesInGroupThenAddToSet.java @@ -20,7 +20,6 @@ package org.jclouds.compute.strategy; import java.util.Map; import java.util.Set; -import java.util.concurrent.Future; import org.jclouds.compute.config.CustomizationResponse; import org.jclouds.compute.domain.NodeMetadata; @@ -28,6 +27,7 @@ import org.jclouds.compute.domain.Template; import org.jclouds.compute.strategy.impl.CreateNodesWithGroupEncodedIntoNameThenAddToSet; import com.google.common.collect.Multimap; +import com.google.common.util.concurrent.ListenableFuture; import com.google.inject.ImplementedBy; /** @@ -37,6 +37,6 @@ import com.google.inject.ImplementedBy; @ImplementedBy(CreateNodesWithGroupEncodedIntoNameThenAddToSet.class) public interface CreateNodesInGroupThenAddToSet { - Map> execute(String group, int count, Template template, Set goodNodes, + Map> execute(String group, int count, Template template, Set goodNodes, Map badNodes, Multimap customizationResponses); } diff --git a/compute/src/main/java/org/jclouds/compute/strategy/impl/CreateNodesWithGroupEncodedIntoNameThenAddToSet.java b/compute/src/main/java/org/jclouds/compute/strategy/impl/CreateNodesWithGroupEncodedIntoNameThenAddToSet.java index b13491f0d1..ead4c37319 100644 --- a/compute/src/main/java/org/jclouds/compute/strategy/impl/CreateNodesWithGroupEncodedIntoNameThenAddToSet.java +++ b/compute/src/main/java/org/jclouds/compute/strategy/impl/CreateNodesWithGroupEncodedIntoNameThenAddToSet.java @@ -24,13 +24,10 @@ import static com.google.common.collect.Iterables.any; import static com.google.common.collect.Maps.newLinkedHashMap; import static com.google.common.collect.Sets.newLinkedHashSet; import static org.jclouds.compute.util.ComputeServiceUtils.formatStatus; -import static org.jclouds.concurrent.Futures.compose; import java.util.Map; import java.util.Set; import java.util.concurrent.Callable; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Future; import java.util.concurrent.atomic.AtomicReference; import javax.annotation.Resource; @@ -42,6 +39,7 @@ import org.jclouds.Constants; import org.jclouds.compute.config.CustomizationResponse; import org.jclouds.compute.domain.ComputeMetadata; import org.jclouds.compute.domain.NodeMetadata; +import org.jclouds.compute.domain.NodeMetadata.Status; import org.jclouds.compute.domain.Template; import org.jclouds.compute.functions.GroupNamingConvention; import org.jclouds.compute.reference.ComputeServiceConstants; @@ -53,6 +51,9 @@ import org.jclouds.logging.Logger; import com.google.common.base.Predicate; import com.google.common.collect.Multimap; +import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.ListeningExecutorService; /** * creates futures that correlate to @@ -95,7 +96,7 @@ public class CreateNodesWithGroupEncodedIntoNameThenAddToSet implements CreateNo protected final CreateNodeWithGroupEncodedIntoName addNodeWithGroupStrategy; protected final ListNodesStrategy listNodesStrategy; protected final GroupNamingConvention.Factory namingConvention; - protected final ExecutorService executor; + protected final ListeningExecutorService userExecutor; protected final CustomizeNodeAndAddToGoodMapOrPutExceptionIntoBadMap.Factory customizeNodeAndAddToGoodMapOrPutExceptionIntoBadMapFactory; @Inject @@ -103,12 +104,12 @@ public class CreateNodesWithGroupEncodedIntoNameThenAddToSet implements CreateNo CreateNodeWithGroupEncodedIntoName addNodeWithGroupStrategy, ListNodesStrategy listNodesStrategy, GroupNamingConvention.Factory namingConvention, - @Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor, + @Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor, CustomizeNodeAndAddToGoodMapOrPutExceptionIntoBadMap.Factory customizeNodeAndAddToGoodMapOrPutExceptionIntoBadMapFactory) { this.addNodeWithGroupStrategy = addNodeWithGroupStrategy; this.listNodesStrategy = listNodesStrategy; this.namingConvention = namingConvention; - this.executor = executor; + this.userExecutor = userExecutor; this.customizeNodeAndAddToGoodMapOrPutExceptionIntoBadMapFactory = customizeNodeAndAddToGoodMapOrPutExceptionIntoBadMapFactory; } @@ -117,13 +118,13 @@ public class CreateNodesWithGroupEncodedIntoNameThenAddToSet implements CreateNo * simultaneously runs the nodes and applies options to them. */ @Override - public Map> execute(String group, int count, Template template, Set goodNodes, + public Map> execute(String group, int count, Template template, Set goodNodes, Map badNodes, Multimap customizationResponses) { - Map> responses = newLinkedHashMap(); + Map> responses = newLinkedHashMap(); for (String name : getNextNames(group, template, count)) { - responses.put(name, compose(createNodeInGroupWithNameAndTemplate(group, name, template), + responses.put(name, Futures.transform(createNodeInGroupWithNameAndTemplate(group, name, template), customizeNodeAndAddToGoodMapOrPutExceptionIntoBadMapFactory.create(template.getOptions(), goodNodes, - badNodes, customizationResponses), executor)); + badNodes, customizationResponses), userExecutor)); } return responses; } @@ -141,10 +142,10 @@ public class CreateNodesWithGroupEncodedIntoNameThenAddToSet implements CreateNo * *
     * @Override
-    * protected Future<AtomicReference<NodeMetadata>> createNodeInGroupWithNameAndTemplate(String group, String name,
+    * protected ListenableFuture<AtomicReference<NodeMetadata>> createNodeInGroupWithNameAndTemplate(String group, String name,
     *          Template template) {
     * 
-    *    Future<AtomicReference<NodeMetadata>> future = super.addNodeIntoGroupWithNameAndTemplate(group, name, template);
+    *    ListenableFuture<AtomicReference<NodeMetadata>> future = super.addNodeIntoGroupWithNameAndTemplate(group, name, template);
     *    return Futures.compose(future, new Function<AtomicReference<NodeMetadata>, AtomicReference<NodeMetadata>>() {
     * 
     *       @Override
@@ -164,9 +165,9 @@ public class CreateNodesWithGroupEncodedIntoNameThenAddToSet implements CreateNo
     * @param template user-specified template
     * @return node that is created, yet not necessarily in {@link Status#RUNNING}
     */
-   protected Future> createNodeInGroupWithNameAndTemplate(String group, String name,
+   protected ListenableFuture> createNodeInGroupWithNameAndTemplate(String group, String name,
             Template template) {
-      return executor.submit(new AddNode(name, group, template));
+      return userExecutor.submit(new AddNode(name, group, template));
    }
 
    /**
diff --git a/compute/src/main/java/org/jclouds/compute/stub/config/StubComputeServiceAdapter.java b/compute/src/main/java/org/jclouds/compute/stub/config/StubComputeServiceAdapter.java
index 8c35502ee6..c405bb2455 100644
--- a/compute/src/main/java/org/jclouds/compute/stub/config/StubComputeServiceAdapter.java
+++ b/compute/src/main/java/org/jclouds/compute/stub/config/StubComputeServiceAdapter.java
@@ -21,10 +21,9 @@ package org.jclouds.compute.stub.config;
 import static org.jclouds.compute.util.ComputeServiceUtils.formatStatus;
 
 import java.util.Map;
-import java.util.Set;
 import java.util.Map.Entry;
+import java.util.Set;
 import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.ExecutorService;
 
 import javax.inject.Inject;
 import javax.inject.Named;
@@ -37,11 +36,11 @@ import org.jclouds.compute.domain.Hardware;
 import org.jclouds.compute.domain.Image;
 import org.jclouds.compute.domain.ImageBuilder;
 import org.jclouds.compute.domain.NodeMetadata;
+import org.jclouds.compute.domain.NodeMetadata.Status;
 import org.jclouds.compute.domain.NodeMetadataBuilder;
 import org.jclouds.compute.domain.OperatingSystem;
 import org.jclouds.compute.domain.OsFamily;
 import org.jclouds.compute.domain.Template;
-import org.jclouds.compute.domain.NodeMetadata.Status;
 import org.jclouds.compute.predicates.ImagePredicates;
 import org.jclouds.domain.Location;
 import org.jclouds.domain.LoginCredentials;
@@ -51,9 +50,10 @@ import org.jclouds.rest.ResourceNotFoundException;
 import com.google.common.base.Supplier;
 import com.google.common.base.Throwables;
 import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableList.Builder;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Iterables;
-import com.google.common.collect.ImmutableList.Builder;
+import com.google.common.util.concurrent.ListeningExecutorService;
 
 /**
  * 
@@ -63,7 +63,7 @@ import com.google.common.collect.ImmutableList.Builder;
 public class StubComputeServiceAdapter implements JCloudsNativeComputeServiceAdapter {
    private final Supplier location;
    private final ConcurrentMap nodes;
-   private final ExecutorService ioThreads;
+   private final ListeningExecutorService ioExecutor;
    private final Provider idProvider;
    private final String publicIpPrefix;
    private final String privateIpPrefix;
@@ -73,12 +73,12 @@ public class StubComputeServiceAdapter implements JCloudsNativeComputeServiceAda
 
    @Inject
    public StubComputeServiceAdapter(ConcurrentMap nodes,
-            @Named(Constants.PROPERTY_IO_WORKER_THREADS) ExecutorService ioThreads, Supplier location,
+            @Named(Constants.PROPERTY_IO_WORKER_THREADS) ListeningExecutorService ioExecutor, Supplier location,
             @Named("NODE_ID") Provider idProvider, @Named("PUBLIC_IP_PREFIX") String publicIpPrefix,
             @Named("PRIVATE_IP_PREFIX") String privateIpPrefix, @Named("PASSWORD_PREFIX") String passwordPrefix,
             JustProvider locationSupplier, Map> osToVersionMap) {
       this.nodes = nodes;
-      this.ioThreads=ioThreads;
+      this.ioExecutor = ioExecutor;
       this.location = location;
       this.idProvider = idProvider;
       this.publicIpPrefix = publicIpPrefix;
@@ -96,7 +96,7 @@ public class StubComputeServiceAdapter implements JCloudsNativeComputeServiceAda
       if (millis == 0l)
          setStateOnNode(status, node);
       else
-         ioThreads.execute(new Runnable() {
+         ioExecutor.execute(new Runnable() {
 
             @Override
             public void run() {
@@ -187,7 +187,7 @@ public class StubComputeServiceAdapter implements JCloudsNativeComputeServiceAda
          return;
       setStateOnNodeAfterDelay(Status.PENDING, node, 0);
       setStateOnNodeAfterDelay(Status.TERMINATED, node, 50);
-      ioThreads.execute(new Runnable() {
+      ioExecutor.execute(new Runnable() {
 
          @Override
          public void run() {
diff --git a/compute/src/main/java/org/jclouds/compute/util/ComputeUtils.java b/compute/src/main/java/org/jclouds/compute/util/ComputeUtils.java
index 100c036c40..db9eabf589 100644
--- a/compute/src/main/java/org/jclouds/compute/util/ComputeUtils.java
+++ b/compute/src/main/java/org/jclouds/compute/util/ComputeUtils.java
@@ -22,8 +22,6 @@ import static com.google.common.collect.Maps.newLinkedHashMap;
 
 import java.util.Map;
 import java.util.Set;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Future;
 import java.util.concurrent.atomic.AtomicReference;
 
 import javax.inject.Inject;
@@ -37,6 +35,8 @@ import org.jclouds.compute.options.TemplateOptions;
 import org.jclouds.compute.strategy.CustomizeNodeAndAddToGoodMapOrPutExceptionIntoBadMap;
 
 import com.google.common.collect.Multimap;
+import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.ListeningExecutorService;
 
 /**
  * 
@@ -45,22 +45,22 @@ import com.google.common.collect.Multimap;
 @Singleton
 public class ComputeUtils {
    private final CustomizeNodeAndAddToGoodMapOrPutExceptionIntoBadMap.Factory customizeNodeAndAddToGoodMapOrPutExceptionIntoBadMapFactory;
-   private final ExecutorService executor;
+   private final ListeningExecutorService userExecutor;
 
    @Inject
    public ComputeUtils(
             CustomizeNodeAndAddToGoodMapOrPutExceptionIntoBadMap.Factory customizeNodeAndAddToGoodMapOrPutExceptionIntoBadMapFactory,
-            @Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor) {
+            @Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor) {
       this.customizeNodeAndAddToGoodMapOrPutExceptionIntoBadMapFactory = customizeNodeAndAddToGoodMapOrPutExceptionIntoBadMapFactory;
-      this.executor = executor;
+      this.userExecutor = userExecutor;
    }
 
-   public Map> customizeNodesAndAddToGoodMapOrPutExceptionIntoBadMap(TemplateOptions options,
+   public Map> customizeNodesAndAddToGoodMapOrPutExceptionIntoBadMap(TemplateOptions options,
             Iterable runningNodes, Set goodNodes, Map badNodes,
             Multimap customizationResponses) {
-      Map> responses = newLinkedHashMap();
+      Map> responses = newLinkedHashMap();
       for (NodeMetadata node : runningNodes) {
-         responses.put(node, executor.submit(customizeNodeAndAddToGoodMapOrPutExceptionIntoBadMapFactory.create(
+         responses.put(node, userExecutor.submit(customizeNodeAndAddToGoodMapOrPutExceptionIntoBadMapFactory.create(
                   options, new AtomicReference(node), goodNodes, badNodes, customizationResponses)));
       }
       return responses;
diff --git a/compute/src/main/java/org/jclouds/compute/util/ConcurrentOpenSocketFinder.java b/compute/src/main/java/org/jclouds/compute/util/ConcurrentOpenSocketFinder.java
index bd8d5ccfcd..b9ccd8d62d 100644
--- a/compute/src/main/java/org/jclouds/compute/util/ConcurrentOpenSocketFinder.java
+++ b/compute/src/main/java/org/jclouds/compute/util/ConcurrentOpenSocketFinder.java
@@ -18,7 +18,6 @@
  */
 package org.jclouds.compute.util;
 
-import static java.lang.String.format;
 import static com.google.common.base.Preconditions.checkNotNull;
 import static com.google.common.base.Preconditions.checkState;
 import static com.google.common.base.Predicates.or;
@@ -27,12 +26,12 @@ import static com.google.common.collect.Iterables.concat;
 import static com.google.common.collect.Iterables.size;
 import static com.google.common.util.concurrent.Atomics.newReference;
 import static com.google.common.util.concurrent.MoreExecutors.listeningDecorator;
+import static java.lang.String.format;
 import static org.jclouds.Constants.PROPERTY_USER_THREADS;
 import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_RUNNING;
 
 import java.util.NoSuchElementException;
 import java.util.concurrent.ExecutionException;
-import java.util.concurrent.ExecutorService;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicReference;
 
@@ -66,16 +65,16 @@ public class ConcurrentOpenSocketFinder implements OpenSocketFinder {
 
    private final SocketOpen socketTester;
    private final Predicate> nodeRunning;
-   private final ListeningExecutorService executor;
+   private final ListeningExecutorService userExecutor;
 
    @Inject
    @VisibleForTesting
    ConcurrentOpenSocketFinder(SocketOpen socketTester,
          @Named(TIMEOUT_NODE_RUNNING) Predicate> nodeRunning,
-         @Named(PROPERTY_USER_THREADS) ExecutorService userThreads) {
+         @Named(PROPERTY_USER_THREADS) ListeningExecutorService userExecutor) {
       this.socketTester = checkNotNull(socketTester, "socketTester");
       this.nodeRunning = checkNotNull(nodeRunning, "nodeRunning");
-      this.executor = listeningDecorator(checkNotNull(userThreads, "userThreads"));
+      this.userExecutor = listeningDecorator(checkNotNull(userExecutor, "userExecutor"));
    }
 
    @Override
@@ -123,7 +122,7 @@ public class ConcurrentOpenSocketFinder implements OpenSocketFinder {
 
             Builder> futures = ImmutableList.builder();
             for (final HostAndPort socket : input) {
-               futures.add(executor.submit(new Runnable() {
+               futures.add(userExecutor.submit(new Runnable() {
 
                   @Override
                   public void run() {
diff --git a/compute/src/test/java/org/jclouds/compute/callables/BlockUntilInitScriptStatusIsZeroThenReturnOutputTest.java b/compute/src/test/java/org/jclouds/compute/callables/BlockUntilInitScriptStatusIsZeroThenReturnOutputTest.java
index 62ba7fb95c..9abc068103 100644
--- a/compute/src/test/java/org/jclouds/compute/callables/BlockUntilInitScriptStatusIsZeroThenReturnOutputTest.java
+++ b/compute/src/test/java/org/jclouds/compute/callables/BlockUntilInitScriptStatusIsZeroThenReturnOutputTest.java
@@ -27,7 +27,6 @@ import static org.testng.Assert.fail;
 
 import java.util.concurrent.CancellationException;
 import java.util.concurrent.ExecutionException;
-import java.util.concurrent.ExecutorService;
 import java.util.concurrent.atomic.AtomicBoolean;
 
 import org.jclouds.compute.callables.BlockUntilInitScriptStatusIsZeroThenReturnOutput.ExitStatusOfCommandGreaterThanZero;
@@ -42,6 +41,7 @@ import com.google.common.base.Predicate;
 import com.google.common.base.Predicates;
 import com.google.common.eventbus.EventBus;
 import com.google.common.util.concurrent.AbstractFuture;
+import com.google.common.util.concurrent.ListeningExecutorService;
 import com.google.common.util.concurrent.MoreExecutors;
 
 /**
@@ -139,7 +139,7 @@ public class BlockUntilInitScriptStatusIsZeroThenReturnOutputTest {
    EventBus eventBus = new EventBus();
 
    public void testExitStatusZeroReturnsExecResponse() throws InterruptedException, ExecutionException {
-      ExecutorService userThreads = MoreExecutors.sameThreadExecutor();
+      ListeningExecutorService userExecutor = MoreExecutors.sameThreadExecutor();
       Predicate notRunningAnymore = Predicates.alwaysTrue();
       SudoAwareInitManager commandRunner = createMockBuilder(SudoAwareInitManager.class).addMockedMethod("runAction")
                .addMockedMethod("getStatement").addMockedMethod("getNode").addMockedMethod("toString")
@@ -155,7 +155,7 @@ public class BlockUntilInitScriptStatusIsZeroThenReturnOutputTest {
       replay(commandRunner, initScript);
 
       BlockUntilInitScriptStatusIsZeroThenReturnOutput future = new BlockUntilInitScriptStatusIsZeroThenReturnOutput(
-               userThreads, eventBus, notRunningAnymore, commandRunner);
+               userExecutor, eventBus, notRunningAnymore, commandRunner);
 
       future.run();
 
@@ -167,7 +167,7 @@ public class BlockUntilInitScriptStatusIsZeroThenReturnOutputTest {
 
    public void testFirstExitStatusOneButSecondExitStatusZeroReturnsExecResponse() throws InterruptedException,
             ExecutionException {
-      ExecutorService userThreads = MoreExecutors.sameThreadExecutor();
+      ListeningExecutorService userExecutor = MoreExecutors.sameThreadExecutor();
       Predicate notRunningAnymore = Predicates.alwaysTrue();
 
       SudoAwareInitManager commandRunner = createMockBuilder(SudoAwareInitManager.class).addMockedMethod("runAction")
@@ -190,7 +190,7 @@ public class BlockUntilInitScriptStatusIsZeroThenReturnOutputTest {
       replay(commandRunner, initScript);
 
       BlockUntilInitScriptStatusIsZeroThenReturnOutput future = new BlockUntilInitScriptStatusIsZeroThenReturnOutput(
-               userThreads, eventBus, notRunningAnymore, commandRunner);
+               userExecutor, eventBus, notRunningAnymore, commandRunner);
 
       future.run();
 
@@ -201,7 +201,7 @@ public class BlockUntilInitScriptStatusIsZeroThenReturnOutputTest {
    }
 
    public void testCancelInterruptStopsCommand() throws InterruptedException, ExecutionException {
-      ExecutorService userThreads = MoreExecutors.sameThreadExecutor();
+      ListeningExecutorService userExecutor = MoreExecutors.sameThreadExecutor();
       Predicate notRunningAnymore = Predicates.alwaysTrue();
       SudoAwareInitManager commandRunner = createMockBuilder(SudoAwareInitManager.class).addMockedMethod(
                "refreshAndRunAction").addMockedMethod("runAction").addMockedMethod("getStatement").addMockedMethod(
@@ -229,7 +229,7 @@ public class BlockUntilInitScriptStatusIsZeroThenReturnOutputTest {
       replay(commandRunner, initScript);
 
       BlockUntilInitScriptStatusIsZeroThenReturnOutput future = new BlockUntilInitScriptStatusIsZeroThenReturnOutput(
-               userThreads, eventBus, notRunningAnymore, commandRunner);
+               userExecutor, eventBus, notRunningAnymore, commandRunner);
 
       future.cancel(true);
 
@@ -246,7 +246,7 @@ public class BlockUntilInitScriptStatusIsZeroThenReturnOutputTest {
 
    public void testCancelDontInterruptLeavesCommandRunningAndReturnsLastStatus() throws InterruptedException,
             ExecutionException {
-      ExecutorService userThreads = MoreExecutors.sameThreadExecutor();
+      ListeningExecutorService userExecutor = MoreExecutors.sameThreadExecutor();
       Predicate notRunningAnymore = Predicates.alwaysTrue();
       SudoAwareInitManager commandRunner = createMockBuilder(SudoAwareInitManager.class).addMockedMethod("runAction")
                .addMockedMethod("getStatement").addMockedMethod("getNode").addMockedMethod("toString")
@@ -262,7 +262,7 @@ public class BlockUntilInitScriptStatusIsZeroThenReturnOutputTest {
       replay(commandRunner, initScript);
 
       BlockUntilInitScriptStatusIsZeroThenReturnOutput future = new BlockUntilInitScriptStatusIsZeroThenReturnOutput(
-               userThreads, eventBus, notRunningAnymore, commandRunner);
+               userExecutor, eventBus, notRunningAnymore, commandRunner);
 
       future.cancel(false);
 
diff --git a/compute/src/test/java/org/jclouds/compute/internal/BaseComputeServiceLiveTest.java b/compute/src/test/java/org/jclouds/compute/internal/BaseComputeServiceLiveTest.java
index 2386636e0f..8f0f0d4eef 100644
--- a/compute/src/test/java/org/jclouds/compute/internal/BaseComputeServiceLiveTest.java
+++ b/compute/src/test/java/org/jclouds/compute/internal/BaseComputeServiceLiveTest.java
@@ -423,7 +423,7 @@ public abstract class BaseComputeServiceLiveTest extends BaseComputeServiceConte
       final long timeoutMs = 20 * 60 * 1000;
       List groups = Lists.newArrayList();
       List> futures = Lists.newArrayList();
-      ListeningExecutorService executor = MoreExecutors.listeningDecorator(context.utils().userExecutor());
+      ListeningExecutorService userExecutor = MoreExecutors.listeningDecorator(context.utils().userExecutor());
 
       try {
          for (int i = 0; i < 2; i++) {
@@ -431,7 +431,7 @@ public abstract class BaseComputeServiceLiveTest extends BaseComputeServiceConte
             final String group = "twin" + groupNum;
             groups.add(group);
 
-            ListenableFuture future = executor.submit(new Callable() {
+            ListenableFuture future = userExecutor.submit(new Callable() {
                public NodeMetadata call() throws Exception {
                   NodeMetadata node = getOnlyElement(client.createNodesInGroup(group, 1, inboundPorts(22, 8080)
                            .blockOnPort(22, 300 + groupNum)));
diff --git a/compute/src/test/java/org/jclouds/compute/util/ConcurrentOpenSocketFinderTest.java b/compute/src/test/java/org/jclouds/compute/util/ConcurrentOpenSocketFinderTest.java
index dfdc4f6096..e8f6d11a92 100644
--- a/compute/src/test/java/org/jclouds/compute/util/ConcurrentOpenSocketFinderTest.java
+++ b/compute/src/test/java/org/jclouds/compute/util/ConcurrentOpenSocketFinderTest.java
@@ -30,7 +30,6 @@ import static org.testng.Assert.fail;
 import java.util.Map;
 import java.util.NoSuchElementException;
 import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicReference;
@@ -47,6 +46,8 @@ import com.google.common.base.Stopwatch;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.net.HostAndPort;
+import com.google.common.util.concurrent.ListeningExecutorService;
+import com.google.common.util.concurrent.MoreExecutors;
 
 @Test(singleThreaded = true)
 public class ConcurrentOpenSocketFinderTest {
@@ -67,24 +68,24 @@ public class ConcurrentOpenSocketFinderTest {
    private final Predicate> nodeRunning = alwaysTrue();
    private final Predicate> nodeNotRunning = alwaysFalse();
 
-   private ExecutorService threadPool;
+   private ListeningExecutorService userExecutor;
 
    @BeforeClass
    public void setUp() {
-      threadPool = Executors.newCachedThreadPool();
+      userExecutor = MoreExecutors.listeningDecorator(Executors.newCachedThreadPool());
    }
 
    @AfterClass(alwaysRun = true)
    public void tearDown() {
-      if (threadPool != null)
-         threadPool.shutdownNow();
+      if (userExecutor != null)
+         userExecutor.shutdownNow();
    }
 
    @Test
    public void testRespectsTimeout() throws Exception {
       final long timeoutMs = 1000;
 
-      OpenSocketFinder finder = new ConcurrentOpenSocketFinder(socketAlwaysClosed, nodeRunning, threadPool);
+      OpenSocketFinder finder = new ConcurrentOpenSocketFinder(socketAlwaysClosed, nodeRunning, userExecutor);
 
       Stopwatch stopwatch = new Stopwatch();
       stopwatch.start();
@@ -109,7 +110,7 @@ public class ConcurrentOpenSocketFinderTest {
          }
       };
 
-      OpenSocketFinder finder = new ConcurrentOpenSocketFinder(secondSocketOpen, nodeRunning, threadPool);
+      OpenSocketFinder finder = new ConcurrentOpenSocketFinder(secondSocketOpen, nodeRunning, userExecutor);
 
       HostAndPort result = finder.findOpenSocketOnNode(node, 22, 2000, MILLISECONDS);
       assertEquals(result, HostAndPort.fromParts("1.2.3.5", 22));
@@ -122,7 +123,7 @@ public class ConcurrentOpenSocketFinderTest {
             HostAndPort.fromParts("1.2.3.4", 22), new SlowCallable(true, 1500),
             HostAndPort.fromParts("1.2.3.5", 22), new SlowCallable(true, 1000)));
 
-      OpenSocketFinder finder = new ConcurrentOpenSocketFinder(socketTester, nodeRunning, threadPool);
+      OpenSocketFinder finder = new ConcurrentOpenSocketFinder(socketTester, nodeRunning, userExecutor);
 
       HostAndPort result = finder.findOpenSocketOnNode(node, 22, 2000, MILLISECONDS);
       assertEquals(result, HostAndPort.fromParts("1.2.3.5", 22));
@@ -131,7 +132,7 @@ public class ConcurrentOpenSocketFinderTest {
    @Test
    public void testAbortsWhenNodeNotRunning() throws Exception {
 
-      OpenSocketFinder finder = new ConcurrentOpenSocketFinder(socketAlwaysClosed, nodeNotRunning, threadPool) {
+      OpenSocketFinder finder = new ConcurrentOpenSocketFinder(socketAlwaysClosed, nodeNotRunning, userExecutor) {
          @Override
          protected  Predicate retryPredicate(final Predicate findOrBreak, long period, long timeoutValue,
                TimeUnit timeUnits) {
diff --git a/drivers/apachehc/src/main/java/org/jclouds/http/apachehc/ApacheHCHttpCommandExecutorService.java b/drivers/apachehc/src/main/java/org/jclouds/http/apachehc/ApacheHCHttpCommandExecutorService.java
index 4c0acfb9e7..77af9449fe 100644
--- a/drivers/apachehc/src/main/java/org/jclouds/http/apachehc/ApacheHCHttpCommandExecutorService.java
+++ b/drivers/apachehc/src/main/java/org/jclouds/http/apachehc/ApacheHCHttpCommandExecutorService.java
@@ -24,7 +24,6 @@ import static org.jclouds.io.ByteSources.asByteSource;
 
 import java.io.IOException;
 import java.net.URI;
-import java.util.concurrent.ExecutorService;
 
 import javax.inject.Named;
 
@@ -48,6 +47,7 @@ import org.jclouds.io.Payloads;
 
 import com.google.common.collect.LinkedHashMultimap;
 import com.google.common.collect.Multimap;
+import com.google.common.util.concurrent.ListeningExecutorService;
 import com.google.inject.Inject;
 
 /**
@@ -62,10 +62,10 @@ public class ApacheHCHttpCommandExecutorService extends BaseHttpCommandExecutorS
 
    @Inject
    ApacheHCHttpCommandExecutorService(HttpUtils utils, ContentMetadataCodec contentMetadataCodec,
-         @Named(Constants.PROPERTY_IO_WORKER_THREADS) ExecutorService ioWorkerExecutor,
+         @Named(Constants.PROPERTY_IO_WORKER_THREADS) ListeningExecutorService ioExecutor,
          DelegatingRetryHandler retryHandler, IOExceptionRetryHandler ioRetryHandler,
          DelegatingErrorHandler errorHandler, HttpWire wire, HttpClient client) {
-      super(utils, contentMetadataCodec, ioWorkerExecutor, retryHandler, ioRetryHandler, errorHandler, wire);
+      super(utils, contentMetadataCodec, ioExecutor, retryHandler, ioRetryHandler, errorHandler, wire);
       this.client = client;
       this.apacheHCUtils = new ApacheHCUtils(contentMetadataCodec);
    }
diff --git a/drivers/enterprise/src/main/java/org/jclouds/enterprise/config/EnterpriseConfigurationModule.java b/drivers/enterprise/src/main/java/org/jclouds/enterprise/config/EnterpriseConfigurationModule.java
index ab838381ef..a402497918 100644
--- a/drivers/enterprise/src/main/java/org/jclouds/enterprise/config/EnterpriseConfigurationModule.java
+++ b/drivers/enterprise/src/main/java/org/jclouds/enterprise/config/EnterpriseConfigurationModule.java
@@ -18,14 +18,14 @@
  */
 package org.jclouds.enterprise.config;
 
-import java.util.concurrent.ExecutorService;
-
 import org.jclouds.concurrent.config.ConfiguresExecutorService;
 import org.jclouds.concurrent.config.ExecutorServiceModule;
 import org.jclouds.date.joda.config.JodaDateServiceModule;
 import org.jclouds.encryption.bouncycastle.config.BouncyCastleCryptoModule;
 import org.jclouds.netty.config.NettyPayloadModule;
 
+import com.google.common.util.concurrent.ListeningExecutorService;
+
 /**
  * Configures Enterprise-grade components
  * 
@@ -35,8 +35,8 @@ import org.jclouds.netty.config.NettyPayloadModule;
 @ConfiguresExecutorService
 public class EnterpriseConfigurationModule extends ExecutorServiceModule {
 
-   public EnterpriseConfigurationModule(ExecutorService userThreads, ExecutorService ioThreads) {
-      super(userThreads, ioThreads);
+   public EnterpriseConfigurationModule(ListeningExecutorService userExecutor, ListeningExecutorService ioExecutor) {
+      super(userExecutor, ioExecutor);
    }
 
    public EnterpriseConfigurationModule() {
diff --git a/drivers/gae/src/main/java/org/jclouds/gae/AsyncGaeHttpCommandExecutorService.java b/drivers/gae/src/main/java/org/jclouds/gae/AsyncGaeHttpCommandExecutorService.java
index 966c94ae5f..c0284a4643 100644
--- a/drivers/gae/src/main/java/org/jclouds/gae/AsyncGaeHttpCommandExecutorService.java
+++ b/drivers/gae/src/main/java/org/jclouds/gae/AsyncGaeHttpCommandExecutorService.java
@@ -19,11 +19,12 @@
 package org.jclouds.gae;
 
 import static com.google.common.base.Throwables.propagate;
+import static com.google.common.util.concurrent.Futures.transform;
+import static com.google.common.util.concurrent.JdkFutureAdapters.listenInPoolThread;
 import static org.jclouds.http.HttpUtils.checkRequestHasContentLengthOrChunkedEncoding;
 import static org.jclouds.http.HttpUtils.wirePayloadIfEnabled;
 
 import java.io.IOException;
-import java.util.concurrent.ExecutorService;
 
 import javax.annotation.Resource;
 import javax.inject.Inject;
@@ -31,7 +32,6 @@ import javax.inject.Named;
 import javax.inject.Singleton;
 
 import org.jclouds.Constants;
-import org.jclouds.concurrent.Futures;
 import org.jclouds.http.HttpCommand;
 import org.jclouds.http.HttpCommandExecutorService;
 import org.jclouds.http.HttpRequest;
@@ -50,6 +50,7 @@ import com.google.appengine.api.urlfetch.HTTPRequest;
 import com.google.appengine.api.urlfetch.URLFetchService;
 import com.google.common.base.Function;
 import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.ListeningExecutorService;
 
 /**
  * Google App Engine version of {@link HttpCommandExecutorService} using their fetchAsync call
@@ -58,7 +59,7 @@ import com.google.common.util.concurrent.ListenableFuture;
  */
 @Singleton
 public class AsyncGaeHttpCommandExecutorService implements HttpCommandExecutorService {
-   private final ExecutorService service;
+   private final ListeningExecutorService ioExecutor;
    private final URLFetchService urlFetchService;
    private final ConvertToGaeRequest convertToGaeRequest;
    private final ConvertToJcloudsResponse convertToJcloudsResponse;
@@ -75,11 +76,12 @@ public class AsyncGaeHttpCommandExecutorService implements HttpCommandExecutorSe
    protected final HttpUtils utils;
 
    @Inject
-   public AsyncGaeHttpCommandExecutorService(@Named(Constants.PROPERTY_USER_THREADS) ExecutorService service,
+   public AsyncGaeHttpCommandExecutorService(
+         @Named(Constants.PROPERTY_IO_WORKER_THREADS) ListeningExecutorService ioExecutor,
          URLFetchService urlFetchService, ConvertToGaeRequest convertToGaeRequest,
          ConvertToJcloudsResponse convertToJcloudsResponse, DelegatingRetryHandler retryHandler,
          IOExceptionRetryHandler ioRetryHandler, DelegatingErrorHandler errorHandler, HttpUtils utils, HttpWire wire) {
-      this.service = service;
+      this.ioExecutor = ioExecutor;
       this.urlFetchService = urlFetchService;
       this.convertToGaeRequest = convertToGaeRequest;
       this.convertToJcloudsResponse = convertToJcloudsResponse;
@@ -109,10 +111,10 @@ public class AsyncGaeHttpCommandExecutorService implements HttpCommandExecutorSe
 
       HTTPRequest nativeRequest = filterLogAndConvertRe(command.getCurrentRequest());
 
-      ListenableFuture response = Futures.compose(urlFetchService.fetchAsync(nativeRequest),
-            convertToJcloudsResponse, service);
+      ListenableFuture response = transform(
+            listenInPoolThread(urlFetchService.fetchAsync(nativeRequest)), convertToJcloudsResponse);
 
-      return Futures.compose(response, new Function() {
+      return transform(response, new Function() {
 
          @Override
          public HttpResponse apply(HttpResponse response) {
@@ -159,7 +161,7 @@ public class AsyncGaeHttpCommandExecutorService implements HttpCommandExecutorSe
             }
             return shouldContinue;
          }
-      }, service);
+      }, ioExecutor);
 
    }
 
diff --git a/drivers/gae/src/main/java/org/jclouds/gae/GaeHttpCommandExecutorService.java b/drivers/gae/src/main/java/org/jclouds/gae/GaeHttpCommandExecutorService.java
index 341796c944..70ec07ef03 100644
--- a/drivers/gae/src/main/java/org/jclouds/gae/GaeHttpCommandExecutorService.java
+++ b/drivers/gae/src/main/java/org/jclouds/gae/GaeHttpCommandExecutorService.java
@@ -19,7 +19,6 @@
 package org.jclouds.gae;
 
 import java.io.IOException;
-import java.util.concurrent.ExecutorService;
 
 import javax.inject.Inject;
 import javax.inject.Named;
@@ -28,6 +27,7 @@ import javax.inject.Singleton;
 import org.jclouds.Constants;
 import org.jclouds.JcloudsVersion;
 import org.jclouds.concurrent.SingleThreaded;
+import org.jclouds.http.HttpCommandExecutorService;
 import org.jclouds.http.HttpRequest;
 import org.jclouds.http.HttpResponse;
 import org.jclouds.http.HttpUtils;
@@ -42,6 +42,7 @@ import com.google.appengine.api.urlfetch.HTTPRequest;
 import com.google.appengine.api.urlfetch.HTTPResponse;
 import com.google.appengine.api.urlfetch.URLFetchService;
 import com.google.common.annotations.VisibleForTesting;
+import com.google.common.util.concurrent.ListeningExecutorService;
 
 /**
  * Google App Engine version of {@link HttpCommandExecutorService}
@@ -61,7 +62,7 @@ public class GaeHttpCommandExecutorService extends BaseHttpCommandExecutorServic
    @Inject
    public GaeHttpCommandExecutorService(URLFetchService urlFetchService, HttpUtils utils,
             ContentMetadataCodec contentMetadataCodec,
-            @Named(Constants.PROPERTY_IO_WORKER_THREADS) ExecutorService ioExecutor,
+            @Named(Constants.PROPERTY_IO_WORKER_THREADS) ListeningExecutorService ioExecutor,
             IOExceptionRetryHandler ioRetryHandler, DelegatingRetryHandler retryHandler,
             DelegatingErrorHandler errorHandler, HttpWire wire, ConvertToGaeRequest convertToGaeRequest,
             ConvertToJcloudsResponse convertToJcloudsResponse) {
diff --git a/drivers/gae/src/main/java/org/jclouds/gae/config/AsyncGoogleAppEngineConfigurationModule.java b/drivers/gae/src/main/java/org/jclouds/gae/config/AsyncGoogleAppEngineConfigurationModule.java
index d30552fb11..634bf52bf9 100644
--- a/drivers/gae/src/main/java/org/jclouds/gae/config/AsyncGoogleAppEngineConfigurationModule.java
+++ b/drivers/gae/src/main/java/org/jclouds/gae/config/AsyncGoogleAppEngineConfigurationModule.java
@@ -41,8 +41,8 @@ public class AsyncGoogleAppEngineConfigurationModule extends GoogleAppEngineConf
       super();
    }
 
-   public AsyncGoogleAppEngineConfigurationModule(Module executorServiceModule) {
-      super(executorServiceModule);
+   public AsyncGoogleAppEngineConfigurationModule(Module userExecutorModule) {
+      super(userExecutorModule);
    }
 
    /**
diff --git a/drivers/gae/src/main/java/org/jclouds/gae/config/CurrentRequestExecutorServiceModule.java b/drivers/gae/src/main/java/org/jclouds/gae/config/CurrentRequestExecutorServiceModule.java
index 53cad02af1..9cc78605c1 100644
--- a/drivers/gae/src/main/java/org/jclouds/gae/config/CurrentRequestExecutorServiceModule.java
+++ b/drivers/gae/src/main/java/org/jclouds/gae/config/CurrentRequestExecutorServiceModule.java
@@ -29,7 +29,7 @@ import javax.inject.Singleton;
 
 import org.jclouds.Constants;
 import org.jclouds.concurrent.config.ConfiguresExecutorService;
-import org.jclouds.concurrent.config.DescribingExecutorService;
+import org.jclouds.concurrent.config.WithSubmissionTrace;
 
 import com.google.appengine.api.ThreadManager;
 import com.google.apphosting.api.ApiProxy;
@@ -99,20 +99,20 @@ public class CurrentRequestExecutorServiceModule extends AbstractModule {
       int maxThreads = 10;
       long keepAlive = ApiProxy.getCurrentEnvironment().getRemainingMillis();
       ExecutorService pool = newScalingThreadPool(0, maxThreads, keepAlive, factory);
-      return MoreExecutors.listeningDecorator(new DescribingExecutorService(pool));
+      return WithSubmissionTrace.wrap(MoreExecutors.listeningDecorator(pool));
    }
 
    @Provides
    @Singleton
    @Named(Constants.PROPERTY_USER_THREADS)
-   protected ExecutorService userThreads() {
+   protected ListeningExecutorService userExecutor() {
       return memoizedCurrentRequestExecutorService.get();
    }
 
    @Provides
    @Singleton
    @Named(Constants.PROPERTY_IO_WORKER_THREADS)
-   protected ExecutorService ioThreads() {
+   protected ListeningExecutorService ioExecutor() {
       return memoizedCurrentRequestExecutorService.get();
    }
 }
diff --git a/drivers/gae/src/main/java/org/jclouds/gae/config/GoogleAppEngineConfigurationModule.java b/drivers/gae/src/main/java/org/jclouds/gae/config/GoogleAppEngineConfigurationModule.java
index dac164519a..b625731479 100644
--- a/drivers/gae/src/main/java/org/jclouds/gae/config/GoogleAppEngineConfigurationModule.java
+++ b/drivers/gae/src/main/java/org/jclouds/gae/config/GoogleAppEngineConfigurationModule.java
@@ -47,7 +47,7 @@ import com.google.inject.Scopes;
 @ConfiguresExecutorService
 @SingleThreaded
 public class GoogleAppEngineConfigurationModule extends AbstractModule {
-   private final Module executorServiceModule;
+   private final Module userExecutorModule;
 
    public GoogleAppEngineConfigurationModule() {
       this(new ExecutorServiceModule(sameThreadExecutor(), sameThreadExecutor()));
@@ -59,8 +59,8 @@ public class GoogleAppEngineConfigurationModule extends AbstractModule {
     * @param currentRequestExecutorService
     * @see CurrentRequestExecutorServiceModule#currentRequestExecutorService
     */
-   public GoogleAppEngineConfigurationModule(Module executorServiceModule) {
-      this.executorServiceModule = executorServiceModule;
+   public GoogleAppEngineConfigurationModule(Module userExecutorModule) {
+      this.userExecutorModule = userExecutorModule;
    }
 
    /**
@@ -70,12 +70,12 @@ public class GoogleAppEngineConfigurationModule extends AbstractModule {
     * @see CurrentRequestExecutorServiceModule#memoizedCurrentRequestExecutorService
     */
    public GoogleAppEngineConfigurationModule(Supplier memoizedCurrentRequestExecutorService) {
-      this.executorServiceModule = new CurrentRequestExecutorServiceModule(memoizedCurrentRequestExecutorService);
+      this.userExecutorModule = new CurrentRequestExecutorServiceModule(memoizedCurrentRequestExecutorService);
    }
 
    @Override
    protected void configure() {
-      install(executorServiceModule);
+      install(userExecutorModule);
       bind(SocketOpen.class).to(SocketOpenUnsupported.class).in(Scopes.SINGLETON);
       bindHttpCommandExecutorService();
    }
diff --git a/drivers/jsch/src/test/java/org/jclouds/ssh/jsch/JschSshClientLiveTest.java b/drivers/jsch/src/test/java/org/jclouds/ssh/jsch/JschSshClientLiveTest.java
index 9b87cafa32..77b26d0a50 100644
--- a/drivers/jsch/src/test/java/org/jclouds/ssh/jsch/JschSshClientLiveTest.java
+++ b/drivers/jsch/src/test/java/org/jclouds/ssh/jsch/JschSshClientLiveTest.java
@@ -235,11 +235,11 @@ public class JschSshClientLiveTest {
    @Test
    public void testExecHostnameConcurrentlyWithSameSessions() throws Exception {
       final SshClient client = setupClient();
-      ListeningExecutorService executor = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(10));
+      ListeningExecutorService userExecutor = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(10));
       List> futures = Lists.newArrayList();
       try {
          for (int i = 0; i < 100; i++) {
-            futures.add(executor.submit(new Callable() {
+            futures.add(userExecutor.submit(new Callable() {
                @Override
                public ExecResponse call() {
                   ExecResponse response = client.exec("hostname");
@@ -256,7 +256,7 @@ public class JschSshClientLiveTest {
                      : sshHost);
          }
       } finally {
-         executor.shutdownNow();
+         userExecutor.shutdownNow();
          client.disconnect();
       }
    }
diff --git a/labs/abiquo/src/main/java/org/jclouds/abiquo/rest/internal/ExtendedUtils.java b/labs/abiquo/src/main/java/org/jclouds/abiquo/rest/internal/ExtendedUtils.java
index 6dc4bff595..c6358ec94c 100644
--- a/labs/abiquo/src/main/java/org/jclouds/abiquo/rest/internal/ExtendedUtils.java
+++ b/labs/abiquo/src/main/java/org/jclouds/abiquo/rest/internal/ExtendedUtils.java
@@ -22,7 +22,6 @@ package org.jclouds.abiquo.rest.internal;
 import static com.google.common.base.Preconditions.checkNotNull;
 
 import java.util.Map;
-import java.util.concurrent.ExecutorService;
 
 import javax.inject.Inject;
 import javax.inject.Named;
@@ -40,6 +39,7 @@ import org.jclouds.rest.internal.UtilsImpl;
 import org.jclouds.xml.XMLParser;
 
 import com.google.common.eventbus.EventBus;
+import com.google.common.util.concurrent.ListeningExecutorService;
 import com.google.inject.Injector;
 import com.google.inject.Singleton;
 
@@ -57,11 +57,11 @@ public class ExtendedUtils extends UtilsImpl implements Utils {
    @Inject
    public ExtendedUtils(final Injector injector, final Json json, final XMLParser xml, final HttpClient simpleApi,
          final HttpAsyncClient simpleAsyncApi, final Crypto encryption, final DateService date,
-         @Named(Constants.PROPERTY_USER_THREADS) final ExecutorService userThreads,
-         @Named(Constants.PROPERTY_IO_WORKER_THREADS) final ExecutorService ioThreads, final EventBus eventBus,
+         @Named(Constants.PROPERTY_USER_THREADS) final ListeningExecutorService userExecutor,
+         @Named(Constants.PROPERTY_IO_WORKER_THREADS) final ListeningExecutorService ioExecutor, final EventBus eventBus,
          final Map credentialStore, final LoggerFactory loggerFactory,
          final AbiquoHttpClient abiquoHttpClient, final AbiquoHttpAsyncClient abiquoHttpAsyncApi) {
-      super(injector, json, xml, simpleApi, simpleAsyncApi, encryption, date, userThreads, ioThreads, eventBus,
+      super(injector, json, xml, simpleApi, simpleAsyncApi, encryption, date, userExecutor, ioExecutor, eventBus,
             credentialStore, loggerFactory);
       this.abiquoHttpClient = checkNotNull(abiquoHttpClient, "abiquoHttpClient");
       this.abiquoHttpAsyncApi = checkNotNull(abiquoHttpAsyncApi, "abiquoHttpAsyncApi");
diff --git a/labs/abiquo/src/main/java/org/jclouds/abiquo/strategy/cloud/ListVirtualAppliances.java b/labs/abiquo/src/main/java/org/jclouds/abiquo/strategy/cloud/ListVirtualAppliances.java
index b571060311..e1d84207d8 100644
--- a/labs/abiquo/src/main/java/org/jclouds/abiquo/strategy/cloud/ListVirtualAppliances.java
+++ b/labs/abiquo/src/main/java/org/jclouds/abiquo/strategy/cloud/ListVirtualAppliances.java
@@ -24,9 +24,6 @@ import static com.google.common.collect.Iterables.filter;
 import static org.jclouds.abiquo.domain.DomainWrapper.wrap;
 import static org.jclouds.concurrent.FutureIterables.transformParallel;
 
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Future;
-
 import javax.annotation.Resource;
 import javax.inject.Named;
 
@@ -44,6 +41,8 @@ import com.abiquo.server.core.cloud.VirtualApplianceDto;
 import com.abiquo.server.core.cloud.VirtualAppliancesDto;
 import com.google.common.base.Function;
 import com.google.common.base.Predicate;
+import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.ListeningExecutorService;
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
 
@@ -58,7 +57,7 @@ public class ListVirtualAppliances implements ListRootEntities
 
    protected final ListVirtualDatacenters listVirtualDatacenters;
 
-   protected final ExecutorService userExecutor;
+   protected final ListeningExecutorService userExecutor;
 
    @Resource
    protected Logger logger = Logger.NULL;
@@ -69,7 +68,7 @@ public class ListVirtualAppliances implements ListRootEntities
 
    @Inject
    ListVirtualAppliances(final RestContext context,
-         @Named(Constants.PROPERTY_USER_THREADS) final ExecutorService userExecutor,
+         @Named(Constants.PROPERTY_USER_THREADS) final ListeningExecutorService userExecutor,
          final ListVirtualDatacenters listVirtualDatacenters) {
       this.context = checkNotNull(context, "context");
       this.listVirtualDatacenters = checkNotNull(listVirtualDatacenters, "listVirtualDatacenters");
@@ -92,9 +91,9 @@ public class ListVirtualAppliances implements ListRootEntities
 
    private Iterable listConcurrentVirtualAppliances(final Iterable vdcs) {
       Iterable vapps = transformParallel(vdcs,
-            new Function>() {
+            new Function>() {
                @Override
-               public Future apply(final VirtualDatacenter input) {
+               public ListenableFuture apply(final VirtualDatacenter input) {
                   return context.getAsyncApi().getCloudApi().listVirtualAppliances(input.unwrap());
                }
             }, userExecutor, maxTime, logger, "getting virtual appliances");
diff --git a/labs/abiquo/src/main/java/org/jclouds/abiquo/strategy/cloud/ListVirtualDatacenters.java b/labs/abiquo/src/main/java/org/jclouds/abiquo/strategy/cloud/ListVirtualDatacenters.java
index da280ae70c..d0dd08a2b7 100644
--- a/labs/abiquo/src/main/java/org/jclouds/abiquo/strategy/cloud/ListVirtualDatacenters.java
+++ b/labs/abiquo/src/main/java/org/jclouds/abiquo/strategy/cloud/ListVirtualDatacenters.java
@@ -25,8 +25,6 @@ import static org.jclouds.abiquo.domain.DomainWrapper.wrap;
 import static org.jclouds.concurrent.FutureIterables.transformParallel;
 
 import java.util.List;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Future;
 
 import javax.annotation.Resource;
 import javax.inject.Named;
@@ -46,6 +44,8 @@ import com.abiquo.server.core.cloud.VirtualDatacentersDto;
 import com.google.common.base.Function;
 import com.google.common.base.Predicate;
 import com.google.common.collect.Lists;
+import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.ListeningExecutorService;
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
 
@@ -58,7 +58,7 @@ import com.google.inject.Singleton;
 public class ListVirtualDatacenters implements ListRootEntities {
    protected final RestContext context;
 
-   protected final ExecutorService userExecutor;
+   protected final ListeningExecutorService userExecutor;
 
    @Resource
    protected Logger logger = Logger.NULL;
@@ -69,7 +69,7 @@ public class ListVirtualDatacenters implements ListRootEntities context,
-         @Named(Constants.PROPERTY_USER_THREADS) final ExecutorService userExecutor) {
+         @Named(Constants.PROPERTY_USER_THREADS) final ListeningExecutorService userExecutor) {
       this.context = checkNotNull(context, "context");
       this.userExecutor = checkNotNull(userExecutor, "userExecutor");
    }
@@ -103,9 +103,9 @@ public class ListVirtualDatacenters implements ListRootEntities listConcurrentVirtualDatacenters(final List ids) {
       Iterable vdcs = transformParallel(ids,
-            new Function>() {
+            new Function>() {
                @Override
-               public Future apply(final Integer input) {
+               public ListenableFuture apply(final Integer input) {
                   return context.getAsyncApi().getCloudApi().getVirtualDatacenter(input);
                }
             }, userExecutor, maxTime, logger, "getting virtual datacenters");
diff --git a/labs/abiquo/src/main/java/org/jclouds/abiquo/strategy/cloud/ListVirtualMachines.java b/labs/abiquo/src/main/java/org/jclouds/abiquo/strategy/cloud/ListVirtualMachines.java
index 245560252d..03687e4114 100644
--- a/labs/abiquo/src/main/java/org/jclouds/abiquo/strategy/cloud/ListVirtualMachines.java
+++ b/labs/abiquo/src/main/java/org/jclouds/abiquo/strategy/cloud/ListVirtualMachines.java
@@ -24,9 +24,6 @@ import static com.google.common.collect.Iterables.filter;
 import static org.jclouds.abiquo.domain.DomainWrapper.wrap;
 import static org.jclouds.concurrent.FutureIterables.transformParallel;
 
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Future;
-
 import javax.annotation.Resource;
 import javax.inject.Named;
 
@@ -45,6 +42,8 @@ import com.abiquo.server.core.cloud.VirtualMachineWithNodeExtendedDto;
 import com.abiquo.server.core.cloud.VirtualMachinesWithNodeExtendedDto;
 import com.google.common.base.Function;
 import com.google.common.base.Predicate;
+import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.ListeningExecutorService;
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
 
@@ -57,7 +56,7 @@ import com.google.inject.Singleton;
 public class ListVirtualMachines implements ListRootEntities {
    protected final RestContext context;
 
-   protected final ExecutorService userExecutor;
+   protected final ListeningExecutorService userExecutor;
 
    protected final ListVirtualAppliances listVirtualAppliances;
 
@@ -70,7 +69,7 @@ public class ListVirtualMachines implements ListRootEntities {
 
    @Inject
    ListVirtualMachines(final RestContext context,
-         @Named(Constants.PROPERTY_USER_THREADS) final ExecutorService userExecutor,
+         @Named(Constants.PROPERTY_USER_THREADS) final ListeningExecutorService userExecutor,
          final ListVirtualAppliances listVirtualAppliances) {
       super();
       this.context = checkNotNull(context, "context");
@@ -99,9 +98,9 @@ public class ListVirtualMachines implements ListRootEntities {
    private Iterable listConcurrentVirtualMachines(
          final Iterable vapps, final VirtualMachineOptions options) {
       Iterable vms = transformParallel(vapps,
-            new Function>() {
+            new Function>() {
                @Override
-               public Future apply(final VirtualAppliance input) {
+               public ListenableFuture apply(final VirtualAppliance input) {
                   return context.getAsyncApi().getCloudApi().listVirtualMachines(input.unwrap(), options);
                }
             }, userExecutor, maxTime, logger, "getting virtual machines");
diff --git a/labs/abiquo/src/main/java/org/jclouds/abiquo/strategy/enterprise/ListVirtualMachineTemplates.java b/labs/abiquo/src/main/java/org/jclouds/abiquo/strategy/enterprise/ListVirtualMachineTemplates.java
index 0d646f6d79..93780fa304 100644
--- a/labs/abiquo/src/main/java/org/jclouds/abiquo/strategy/enterprise/ListVirtualMachineTemplates.java
+++ b/labs/abiquo/src/main/java/org/jclouds/abiquo/strategy/enterprise/ListVirtualMachineTemplates.java
@@ -24,9 +24,6 @@ import static com.google.common.collect.Iterables.filter;
 import static org.jclouds.abiquo.domain.DomainWrapper.wrap;
 import static org.jclouds.concurrent.FutureIterables.transformParallel;
 
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Future;
-
 import javax.annotation.Resource;
 import javax.inject.Named;
 
@@ -45,6 +42,8 @@ import com.abiquo.server.core.appslibrary.VirtualMachineTemplateDto;
 import com.abiquo.server.core.appslibrary.VirtualMachineTemplatesDto;
 import com.google.common.base.Function;
 import com.google.common.base.Predicate;
+import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.ListeningExecutorService;
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
 
@@ -57,7 +56,7 @@ import com.google.inject.Singleton;
 public class ListVirtualMachineTemplates implements ListEntities {
    protected final RestContext context;
 
-   protected final ExecutorService userExecutor;
+   protected final ListeningExecutorService userExecutor;
 
    @Resource
    protected Logger logger = Logger.NULL;
@@ -68,7 +67,7 @@ public class ListVirtualMachineTemplates implements ListEntities context,
-         @Named(Constants.PROPERTY_USER_THREADS) final ExecutorService userExecutor) {
+         @Named(Constants.PROPERTY_USER_THREADS) final ListeningExecutorService userExecutor) {
       super();
       this.context = checkNotNull(context, "context");
       this.userExecutor = checkNotNull(userExecutor, "userExecutor");
@@ -92,9 +91,9 @@ public class ListVirtualMachineTemplates implements ListEntities listConcurrentTemplates(final Enterprise parent,
          final Iterable dcs) {
       Iterable templates = transformParallel(dcs,
-            new Function>() {
+            new Function>() {
                @Override
-               public Future apply(final Datacenter input) {
+               public ListenableFuture apply(final Datacenter input) {
                   return context.getAsyncApi().getVirtualMachineTemplateApi()
                         .listVirtualMachineTemplates(parent.getId(), input.getId());
                }
diff --git a/labs/abiquo/src/main/java/org/jclouds/abiquo/strategy/infrastructure/ListMachines.java b/labs/abiquo/src/main/java/org/jclouds/abiquo/strategy/infrastructure/ListMachines.java
index 0b7a887d30..275e1781b4 100644
--- a/labs/abiquo/src/main/java/org/jclouds/abiquo/strategy/infrastructure/ListMachines.java
+++ b/labs/abiquo/src/main/java/org/jclouds/abiquo/strategy/infrastructure/ListMachines.java
@@ -24,9 +24,6 @@ import static com.google.common.collect.Iterables.filter;
 import static org.jclouds.abiquo.domain.DomainWrapper.wrap;
 import static org.jclouds.concurrent.FutureIterables.transformParallel;
 
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Future;
-
 import javax.annotation.Resource;
 import javax.inject.Named;
 
@@ -47,6 +44,8 @@ import com.abiquo.server.core.infrastructure.RackDto;
 import com.abiquo.server.core.infrastructure.RacksDto;
 import com.google.common.base.Function;
 import com.google.common.base.Predicate;
+import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.ListeningExecutorService;
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
 
@@ -59,7 +58,7 @@ import com.google.inject.Singleton;
 public class ListMachines implements ListRootEntities {
    protected RestContext context;
 
-   protected final ExecutorService userExecutor;
+   protected final ListeningExecutorService userExecutor;
 
    @Resource
    protected Logger logger = Logger.NULL;
@@ -70,7 +69,7 @@ public class ListMachines implements ListRootEntities {
 
    @Inject
    ListMachines(final RestContext context,
-         @Named(Constants.PROPERTY_USER_THREADS) final ExecutorService userExecutor) {
+         @Named(Constants.PROPERTY_USER_THREADS) final ListeningExecutorService userExecutor) {
       super();
       this.context = checkNotNull(context, "context");
       this.userExecutor = checkNotNull(userExecutor, "userExecutor");
@@ -93,9 +92,9 @@ public class ListMachines implements ListRootEntities {
    }
 
    private Iterable listConcurrentRacks(final Iterable datacenters) {
-      Iterable racks = transformParallel(datacenters, new Function>() {
+      Iterable racks = transformParallel(datacenters, new Function>() {
          @Override
-         public Future apply(final Datacenter input) {
+         public ListenableFuture apply(final Datacenter input) {
             return context.getAsyncApi().getInfrastructureApi().listRacks(input.unwrap());
          }
       }, userExecutor, maxTime, logger, "getting racks");
@@ -104,9 +103,9 @@ public class ListMachines implements ListRootEntities {
    }
 
    private Iterable listConcurrentMachines(final Iterable racks) {
-      Iterable machines = transformParallel(racks, new Function>() {
+      Iterable machines = transformParallel(racks, new Function>() {
          @Override
-         public Future apply(final RackDto input) {
+         public ListenableFuture apply(final RackDto input) {
             return context.getAsyncApi().getInfrastructureApi().listMachines(input);
          }
       }, userExecutor, maxTime, logger, "getting machines");
diff --git a/labs/elb/src/main/java/org/jclouds/elb/loadbalancer/strategy/ELBListLoadBalancersStrategy.java b/labs/elb/src/main/java/org/jclouds/elb/loadbalancer/strategy/ELBListLoadBalancersStrategy.java
index 87ef4b6efa..4ec11b315b 100644
--- a/labs/elb/src/main/java/org/jclouds/elb/loadbalancer/strategy/ELBListLoadBalancersStrategy.java
+++ b/labs/elb/src/main/java/org/jclouds/elb/loadbalancer/strategy/ELBListLoadBalancersStrategy.java
@@ -21,11 +21,10 @@ package org.jclouds.elb.loadbalancer.strategy;
 import static com.google.common.base.Preconditions.checkNotNull;
 import static com.google.common.collect.Iterables.concat;
 import static com.google.common.collect.Iterables.transform;
+import static com.google.common.util.concurrent.Futures.transform;
 import static org.jclouds.concurrent.FutureIterables.transformParallel;
 
 import java.util.Set;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Future;
 
 import javax.annotation.Resource;
 import javax.inject.Inject;
@@ -34,7 +33,6 @@ import javax.inject.Singleton;
 
 import org.jclouds.Constants;
 import org.jclouds.collect.PagedIterable;
-import org.jclouds.concurrent.Futures;
 import org.jclouds.elb.ELBAsyncApi;
 import org.jclouds.elb.domain.LoadBalancer;
 import org.jclouds.elb.domain.regionscoped.LoadBalancerInRegion;
@@ -47,6 +45,7 @@ import org.jclouds.logging.Logger;
 import com.google.common.base.Function;
 import com.google.common.base.Supplier;
 import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.ListeningExecutorService;
 
 /**
  * 
@@ -60,29 +59,29 @@ public class ELBListLoadBalancersStrategy implements ListLoadBalancersStrategy {
 
    private final ELBAsyncApi aapi;
    private final Function converter;
-   private final ExecutorService executor;
+   private final ListeningExecutorService userExecutor;
    private final Supplier> regions;
 
    @Inject
    protected ELBListLoadBalancersStrategy(ELBAsyncApi aapi,
             Function converter,
-            @Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor, @Region Supplier> regions) {
+            @Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor, @Region Supplier> regions) {
       this.aapi = checkNotNull(aapi, "aapi");
       this.regions = checkNotNull(regions, "regions");
       this.converter = checkNotNull(converter, "converter");
-      this.executor = checkNotNull(executor, "executor");
+      this.userExecutor = checkNotNull(userExecutor, "userExecutor");
    }
 
    @Override
    public Iterable listLoadBalancers() {
 
       Iterable loadBalancers = concat(transformParallel(regions.get(),
-               new Function>>() {
+               new Function>>() {
 
                   @Override
                   public ListenableFuture> apply(final String from) {
                      // TODO: ELB.listLoadBalancers
-                     return Futures.compose(aapi.getLoadBalancerApiForRegion(from).list(),
+                     return transform(aapi.getLoadBalancerApiForRegion(from).list(),
                               new Function, Iterable>() {
 
                                  @Override
@@ -96,10 +95,10 @@ public class ELBListLoadBalancersStrategy implements ListLoadBalancersStrategy {
                                                  });
                                  }
 
-                              }, executor);
+                              }, userExecutor);
                   }
 
-               }, executor, null, logger, "loadbalancers"));
+               }, userExecutor, null, logger, "loadbalancers"));
       return transform(loadBalancers, converter);
    }
 }
diff --git a/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/compute/JoyentCloudComputeService.java b/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/compute/JoyentCloudComputeService.java
index d2979dba9f..9c1fb7e8e9 100644
--- a/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/compute/JoyentCloudComputeService.java
+++ b/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/compute/JoyentCloudComputeService.java
@@ -25,7 +25,6 @@ import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_T
 
 import java.util.Map;
 import java.util.Set;
-import java.util.concurrent.ExecutorService;
 import java.util.concurrent.atomic.AtomicReference;
 
 import javax.inject.Inject;
@@ -75,6 +74,7 @@ import com.google.common.cache.LoadingCache;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Iterables;
 import com.google.common.collect.Multimap;
+import com.google.common.util.concurrent.ListeningExecutorService;
 
 /**
  * @author Adrian Cole
@@ -101,7 +101,7 @@ public class JoyentCloudComputeService extends BaseComputeService {
          InitializeRunScriptOnNodeOrPlaceInBadMap.Factory initScriptRunnerFactory,
          RunScriptOnNode.Factory runScriptOnNodeFactory, InitAdminAccess initAdminAccess,
          PersistNodeCredentials persistNodeCredentials, Timeouts timeouts,
-         @Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor, JoyentCloudApi novaApi,
+         @Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor, JoyentCloudApi novaApi,
          LoadingCache keyCache,
          Function, Multimap> orphanedGroupsByDatacenterId,
          GroupNamingConvention.Factory namingConvention, Optional imageExtension) {
@@ -109,7 +109,7 @@ public class JoyentCloudComputeService extends BaseComputeService {
             getNodeMetadataStrategy, runNodesAndAddToSetStrategy, rebootNodeStrategy, destroyNodeStrategy,
             startNodeStrategy, stopNodeStrategy, templateBuilderProvider, templateOptionsProvider, nodeRunning,
             nodeTerminated, nodeSuspended, initScriptRunnerFactory, initAdminAccess, runScriptOnNodeFactory,
-            persistNodeCredentials, timeouts, executor, imageExtension);
+            persistNodeCredentials, timeouts, userExecutor, imageExtension);
       this.novaApi = checkNotNull(novaApi, "novaApi");
       this.keyCache = checkNotNull(keyCache, "keyCache");
       this.orphanedGroupsByDatacenterId = checkNotNull(orphanedGroupsByDatacenterId, "orphanedGroupsByDatacenterId");
diff --git a/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/compute/strategy/ApplyJoyentCloudTemplateOptionsCreateNodesWithGroupEncodedIntoNameThenAddToSet.java b/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/compute/strategy/ApplyJoyentCloudTemplateOptionsCreateNodesWithGroupEncodedIntoNameThenAddToSet.java
index e154b941e9..b0d7dfa076 100644
--- a/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/compute/strategy/ApplyJoyentCloudTemplateOptionsCreateNodesWithGroupEncodedIntoNameThenAddToSet.java
+++ b/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/compute/strategy/ApplyJoyentCloudTemplateOptionsCreateNodesWithGroupEncodedIntoNameThenAddToSet.java
@@ -24,8 +24,6 @@ import static org.jclouds.joyent.cloudapi.v6_5.config.JoyentCloudProperties.AUTO
 
 import java.util.Map;
 import java.util.Set;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Future;
 
 import javax.inject.Inject;
 import javax.inject.Named;
@@ -46,6 +44,8 @@ import org.jclouds.joyent.cloudapi.v6_5.domain.datacenterscoped.DatacenterAndNam
 
 import com.google.common.cache.LoadingCache;
 import com.google.common.collect.Multimap;
+import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.ListeningExecutorService;
 
 /**
  * 
@@ -64,17 +64,17 @@ public class ApplyJoyentCloudTemplateOptionsCreateNodesWithGroupEncodedIntoNameT
             ListNodesStrategy listNodesStrategy,
             GroupNamingConvention.Factory namingConvention,
             CustomizeNodeAndAddToGoodMapOrPutExceptionIntoBadMap.Factory customizeNodeAndAddToGoodMapOrPutExceptionIntoBadMapFactory,
-            @Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor,
+            @Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor,
             LoadingCache keyCache, 
             @Named(AUTOGENERATE_KEYS) boolean defaultToAutogenerateKeys) {
-      super(addNodeWithTagStrategy, listNodesStrategy, namingConvention, executor,
+      super(addNodeWithTagStrategy, listNodesStrategy, namingConvention, userExecutor,
                customizeNodeAndAddToGoodMapOrPutExceptionIntoBadMapFactory);
       this.keyCache = checkNotNull(keyCache, "keyCache");
       this.defaultToAutogenerateKeys = defaultToAutogenerateKeys;
    }
 
    @Override
-   public Map> execute(String group, int count, Template template, Set goodNodes,
+   public Map> execute(String group, int count, Template template, Set goodNodes,
          Map badNodes, Multimap customizationResponses) {
 
       Template mutableTemplate = template.clone();
diff --git a/labs/virtualbox/src/test/java/org/jclouds/virtualbox/BaseVirtualBoxClientLiveTest.java b/labs/virtualbox/src/test/java/org/jclouds/virtualbox/BaseVirtualBoxClientLiveTest.java
index 308ccdc923..6ada4c739d 100644
--- a/labs/virtualbox/src/test/java/org/jclouds/virtualbox/BaseVirtualBoxClientLiveTest.java
+++ b/labs/virtualbox/src/test/java/org/jclouds/virtualbox/BaseVirtualBoxClientLiveTest.java
@@ -25,7 +25,6 @@ import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_IMAGE
 import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_INSTALLATION_KEY_SEQUENCE;
 
 import java.io.File;
-import java.util.concurrent.ExecutorService;
 import java.util.concurrent.TimeUnit;
 
 import javax.inject.Inject;
@@ -127,14 +126,12 @@ public class BaseVirtualBoxClientLiveTest extends BaseComputeServiceContextLiveT
    protected PrioritizeCredentialsFromTemplate prioritizeCredentialsFromTemplate;
    @Inject
    protected LoadingCache mastersCache;
-
-   private final ExecutorService singleThreadExec = sameThreadExecutor();
    private String masterName;   
 
    @Override
    protected Iterable setupModules() {
       return ImmutableSet. of(getLoggingModule(), credentialStoreModule, getSshModule(),  new ExecutorServiceModule(
-            singleThreadExec, singleThreadExec));
+            sameThreadExecutor(), sameThreadExecutor()));
    }
    
    @Override
diff --git a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/AWSEC2ComputeService.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/AWSEC2ComputeService.java
index 367d4086cf..0745dafc67 100644
--- a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/AWSEC2ComputeService.java
+++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/AWSEC2ComputeService.java
@@ -29,7 +29,6 @@ import static org.jclouds.ec2.reference.EC2Constants.PROPERTY_EC2_GENERATE_INSTA
 import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.ExecutorService;
 import java.util.concurrent.atomic.AtomicReference;
 
 import javax.inject.Inject;
@@ -74,6 +73,7 @@ import com.google.common.base.Optional;
 import com.google.common.base.Predicate;
 import com.google.common.base.Supplier;
 import com.google.common.cache.LoadingCache;
+import com.google.common.util.concurrent.ListeningExecutorService;
 
 /**
  * @author Adrian Cole
@@ -100,7 +100,7 @@ public class AWSEC2ComputeService extends EC2ComputeService {
          InitializeRunScriptOnNodeOrPlaceInBadMap.Factory initScriptRunnerFactory,
          RunScriptOnNode.Factory runScriptOnNodeFactory, InitAdminAccess initAdminAccess,
          PersistNodeCredentials persistNodeCredentials, Timeouts timeouts,
-         @Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor, AWSEC2Client client,
+         @Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor, AWSEC2Client client,
          ConcurrentMap credentialsMap,
          @Named("SECURITY") LoadingCache securityGroupMap,
          @Named("PLACEMENT") LoadingCache placementGroupMap,
@@ -111,7 +111,7 @@ public class AWSEC2ComputeService extends EC2ComputeService {
             getNodeMetadataStrategy, runNodesAndAddToSetStrategy, rebootNodeStrategy, destroyNodeStrategy,
             startNodeStrategy, stopNodeStrategy, templateBuilderProvider, templateOptionsProvider, nodeRunning,
             nodeTerminated, nodeSuspended, initScriptRunnerFactory, runScriptOnNodeFactory, initAdminAccess,
-            persistNodeCredentials, timeouts, executor, client, credentialsMap, securityGroupMap, imageExtension,
+            persistNodeCredentials, timeouts, userExecutor, client, credentialsMap, securityGroupMap, imageExtension,
             namingConvention, generateInstanceNames);
       this.client = client;
       this.placementGroupMap = placementGroupMap;
diff --git a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/strategy/AWSEC2ListNodesStrategy.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/strategy/AWSEC2ListNodesStrategy.java
index 7316c750be..8030231abb 100644
--- a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/strategy/AWSEC2ListNodesStrategy.java
+++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/strategy/AWSEC2ListNodesStrategy.java
@@ -26,8 +26,6 @@ import static com.google.common.collect.Iterables.transform;
 import static org.jclouds.concurrent.FutureIterables.transformParallel;
 
 import java.util.Set;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Future;
 
 import javax.inject.Named;
 import javax.inject.Singleton;
@@ -44,6 +42,8 @@ import org.jclouds.location.Region;
 
 import com.google.common.base.Function;
 import com.google.common.base.Supplier;
+import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.ListeningExecutorService;
 import com.google.inject.Inject;
 
 /**
@@ -59,9 +59,9 @@ public class AWSEC2ListNodesStrategy extends EC2ListNodesStrategy {
    @Inject
    protected AWSEC2ListNodesStrategy(AWSEC2AsyncClient client, @Region Supplier> regions,
             Function runningInstanceToNodeMetadata,
-            @Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor,
+            @Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor,
             SpotInstanceRequestToAWSRunningInstance spotConverter) {
-      super(client, regions, runningInstanceToNodeMetadata, executor);
+      super(client, regions, runningInstanceToNodeMetadata, userExecutor);
       this.client = checkNotNull(client, "client");
       this.spotConverter = checkNotNull(spotConverter, "spotConverter");
    }
@@ -69,14 +69,13 @@ public class AWSEC2ListNodesStrategy extends EC2ListNodesStrategy {
    @Override
    protected Iterable pollRunningInstances() {
       Iterable spots = filter(transform(concat(transformParallel(regions.get(),
-               new Function>>() {
+               new Function>>() {
                   @Override
-                  public Future> apply(String from) {
-                     return client.getSpotInstanceServices()
-                              .describeSpotInstanceRequestsInRegion(from);
+                  public ListenableFuture> apply(String from) {
+                     return client.getSpotInstanceServices().describeSpotInstanceRequestsInRegion(from);
                   }
 
-               }, executor, maxTime, logger, "reservations")), spotConverter), notNull());
+               }, userExecutor, maxTime, logger, "reservations")), spotConverter), notNull());
 
       return concat(super.pollRunningInstances(), spots);
    }
diff --git a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/suppliers/AWSEC2ImageSupplier.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/suppliers/AWSEC2ImageSupplier.java
index 4f3945d1c5..fd51236d4d 100644
--- a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/suppliers/AWSEC2ImageSupplier.java
+++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/suppliers/AWSEC2ImageSupplier.java
@@ -26,8 +26,6 @@ import static org.jclouds.aws.ec2.reference.AWSEC2Constants.PROPERTY_EC2_CC_REGI
 
 import java.util.Map;
 import java.util.Set;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Future;
 
 import javax.annotation.Resource;
 import javax.inject.Inject;
@@ -55,6 +53,8 @@ import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Iterables;
 import com.google.common.collect.Multimap;
 import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.ListeningExecutorService;
 
 /**
  * 
@@ -71,7 +71,7 @@ public class AWSEC2ImageSupplier implements Supplier> {
    
    private final Set clusterComputeIds;
    private final CallForImages.Factory factory;
-   private final ExecutorService executor;
+   private final ListeningExecutorService userExecutor;
 
    private final Supplier> regions;
    private final Map queries;
@@ -83,14 +83,14 @@ public class AWSEC2ImageSupplier implements Supplier> {
             @ImageQuery Map queries, @Named(PROPERTY_EC2_CC_REGIONS) String clusterRegions,
             Supplier> cache,
             CallForImages.Factory factory, @ClusterCompute Set clusterComputeIds,
-            @Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor) {
+            @Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor) {
       this.factory = factory;
       this.regions = regions;
       this.queries = queries;
       this.clusterRegions = Splitter.on(',').split(clusterRegions);
       this.cache = cache;
       this.clusterComputeIds = clusterComputeIds;
-      this.executor = executor;
+      this.userExecutor = userExecutor;
    }
    
    @SuppressWarnings("unchecked")
@@ -99,7 +99,7 @@ public class AWSEC2ImageSupplier implements Supplier> {
       String amiQuery = queries.get(PROPERTY_EC2_AMI_QUERY);
       String ccAmiQuery = queries.get(PROPERTY_EC2_CC_AMI_QUERY);
 
-      Future> normalImages = images(regions.get(), amiQuery, PROPERTY_EC2_AMI_QUERY);
+      ListenableFuture> normalImages = images(regions.get(), amiQuery, PROPERTY_EC2_AMI_QUERY);
       ImmutableSet clusterImages;
       try {
          clusterImages = ImmutableSet.copyOf(images(clusterRegions, ccAmiQuery, PROPERTY_EC2_CC_AMI_QUERY).get());
@@ -136,12 +136,12 @@ public class AWSEC2ImageSupplier implements Supplier> {
       };
    }
    
-   private Future> images(Iterable regions, String query, String tag) {
+   private ListenableFuture> images(Iterable regions, String query, String tag) {
       if (query == null) {
          logger.debug(">> no %s specified, skipping image parsing", tag);
          return Futures.> immediateFuture(ImmutableSet. of());
       } else {
-         return executor.submit(factory.parseImagesFromRegionsUsingFilter(regions, QueryStringToMultimap.INSTANCE
+         return userExecutor.submit(factory.parseImagesFromRegionsUsingFilter(regions, QueryStringToMultimap.INSTANCE
                   .apply(query)));
       }
    }
diff --git a/providers/aws-s3/src/main/java/org/jclouds/aws/s3/blobstore/AWSS3AsyncBlobStore.java b/providers/aws-s3/src/main/java/org/jclouds/aws/s3/blobstore/AWSS3AsyncBlobStore.java
index 784d57ec0c..4405b0abe6 100644
--- a/providers/aws-s3/src/main/java/org/jclouds/aws/s3/blobstore/AWSS3AsyncBlobStore.java
+++ b/providers/aws-s3/src/main/java/org/jclouds/aws/s3/blobstore/AWSS3AsyncBlobStore.java
@@ -21,7 +21,6 @@ package org.jclouds.aws.s3.blobstore;
 import static org.jclouds.s3.domain.ObjectMetadata.StorageClass.REDUCED_REDUNDANCY;
 
 import java.util.Set;
-import java.util.concurrent.ExecutorService;
 
 import javax.inject.Inject;
 import javax.inject.Named;
@@ -60,6 +59,7 @@ import com.google.common.base.Supplier;
 import com.google.common.cache.CacheLoader;
 import com.google.common.cache.LoadingCache;
 import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.ListeningExecutorService;
 
 /**
  *
@@ -73,7 +73,7 @@ public class AWSS3AsyncBlobStore extends S3AsyncBlobStore {
 
    @Inject
    public AWSS3AsyncBlobStore(BlobStoreContext context, BlobUtils blobUtils,
-            @Named(Constants.PROPERTY_USER_THREADS) ExecutorService service, Supplier defaultLocation,
+            @Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor, Supplier defaultLocation,
             @Memoized Supplier> locations, AWSS3AsyncClient async, AWSS3Client sync,
             Function, PageSet> convertBucketsToStorageMetadata,
             ContainerToBucketListOptions container2BucketListOptions, BucketToResourceList bucket2ResourceList,
@@ -81,7 +81,7 @@ public class AWSS3AsyncBlobStore extends S3AsyncBlobStore {
             ObjectToBlobMetadata object2BlobMd, Provider fetchBlobMetadataProvider,
             LoadingCache bucketAcls,
             Provider multipartUploadStrategy) {
-      super(context, blobUtils, service, defaultLocation, locations, async, sync, convertBucketsToStorageMetadata,
+      super(context, blobUtils, userExecutor, defaultLocation, locations, async, sync, convertBucketsToStorageMetadata,
                container2BucketListOptions, bucket2ResourceList, object2Blob, blob2ObjectGetOptions, blob2Object,
                object2BlobMd, fetchBlobMetadataProvider, bucketAcls);
       this.multipartUploadStrategy = multipartUploadStrategy;
diff --git a/providers/aws-s3/src/main/java/org/jclouds/aws/s3/blobstore/strategy/internal/ParallelMultipartUploadStrategy.java b/providers/aws-s3/src/main/java/org/jclouds/aws/s3/blobstore/strategy/internal/ParallelMultipartUploadStrategy.java
index 0a7a29d6fa..b3181a75e6 100644
--- a/providers/aws-s3/src/main/java/org/jclouds/aws/s3/blobstore/strategy/internal/ParallelMultipartUploadStrategy.java
+++ b/providers/aws-s3/src/main/java/org/jclouds/aws/s3/blobstore/strategy/internal/ParallelMultipartUploadStrategy.java
@@ -31,7 +31,6 @@ import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentLinkedQueue;
 import java.util.concurrent.ConcurrentSkipListMap;
 import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.ExecutorService;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicInteger;
 
@@ -48,7 +47,6 @@ import org.jclouds.blobstore.domain.Blob;
 import org.jclouds.blobstore.internal.BlobRuntimeException;
 import org.jclouds.blobstore.options.PutOptions;
 import org.jclouds.blobstore.reference.BlobStoreConstants;
-import org.jclouds.concurrent.Futures;
 import org.jclouds.io.Payload;
 import org.jclouds.io.PayloadSlicer;
 import org.jclouds.logging.Logger;
@@ -58,6 +56,7 @@ import org.jclouds.util.Throwables2;
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.collect.Maps;
 import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.ListeningExecutorService;
 import com.google.inject.Inject;
 
 public class ParallelMultipartUploadStrategy implements AsyncMultipartUploadStrategy {
@@ -72,7 +71,7 @@ public class ParallelMultipartUploadStrategy implements AsyncMultipartUploadStra
    @VisibleForTesting
    static final int DEFAULT_MAX_PERCENT_RETRIES = 10;
    
-   private final ExecutorService ioWorkerExecutor;
+   private final ListeningExecutorService ioExecutor;
   
    @Inject(optional = true)
    @Named("jclouds.mpu.parallel.degree")
@@ -101,10 +100,10 @@ public class ParallelMultipartUploadStrategy implements AsyncMultipartUploadStra
 
    @Inject
    public ParallelMultipartUploadStrategy(AWSS3AsyncBlobStore ablobstore, PayloadSlicer slicer,
-         @Named(Constants.PROPERTY_IO_WORKER_THREADS) ExecutorService ioWorkerExecutor) {
+         @Named(Constants.PROPERTY_IO_WORKER_THREADS) ListeningExecutorService ioExecutor) {
       this.ablobstore = checkNotNull(ablobstore, "ablobstore");
       this.slicer = checkNotNull(slicer, "slicer");
-      this.ioWorkerExecutor = checkNotNull(ioWorkerExecutor, "ioWorkerExecutor");
+      this.ioExecutor = checkNotNull(ioExecutor, "ioExecutor");
    }
    
    protected void prepareUploadPart(final String container, final String key, 
@@ -149,14 +148,13 @@ public class ParallelMultipartUploadStrategy implements AsyncMultipartUploadStra
                latch.countDown();
             }
          }
-      }, ioWorkerExecutor);
+      }, ioExecutor);
       futureParts.put(part, futureETag);
    }   
    
    @Override
    public ListenableFuture execute(final String container, final Blob blob, final PutOptions options) {
-      return Futures.makeListenable(
-            ioWorkerExecutor.submit(new Callable() {
+      return ioExecutor.submit(new Callable() {
                @Override
                public String call() throws Exception {
                   String key = blob.getMetadata().getName();
@@ -250,7 +248,7 @@ public class ParallelMultipartUploadStrategy implements AsyncMultipartUploadStra
                            futureETag.get(maxTime,TimeUnit.SECONDS) : futureETag.get();
                   }
                }
-            }), ioWorkerExecutor);
+            });
    }
    
    class Part {
diff --git a/providers/azureblob/src/main/java/org/jclouds/azureblob/blobstore/AzureAsyncBlobStore.java b/providers/azureblob/src/main/java/org/jclouds/azureblob/blobstore/AzureAsyncBlobStore.java
index dc8980bae4..43b6fd8a6f 100644
--- a/providers/azureblob/src/main/java/org/jclouds/azureblob/blobstore/AzureAsyncBlobStore.java
+++ b/providers/azureblob/src/main/java/org/jclouds/azureblob/blobstore/AzureAsyncBlobStore.java
@@ -19,10 +19,10 @@
 package org.jclouds.azureblob.blobstore;
 
 import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.util.concurrent.Futures.transform;
 import static org.jclouds.azure.storage.options.ListOptions.Builder.includeMetadata;
 
 import java.util.Set;
-import java.util.concurrent.ExecutorService;
 
 import javax.inject.Inject;
 import javax.inject.Named;
@@ -56,7 +56,6 @@ import org.jclouds.blobstore.options.ListContainerOptions;
 import org.jclouds.blobstore.options.PutOptions;
 import org.jclouds.blobstore.util.BlobUtils;
 import org.jclouds.collect.Memoized;
-import org.jclouds.concurrent.Futures;
 import org.jclouds.domain.Location;
 import org.jclouds.http.options.GetOptions;
 
@@ -64,6 +63,7 @@ import com.google.common.base.Function;
 import com.google.common.base.Supplier;
 import com.google.common.collect.Iterables;
 import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.ListeningExecutorService;
 
 /**
  * @author Adrian Cole
@@ -81,14 +81,14 @@ public class AzureAsyncBlobStore extends BaseAsyncBlobStore {
 
    @Inject
    AzureAsyncBlobStore(BlobStoreContext context, BlobUtils blobUtils,
-            @Named(Constants.PROPERTY_USER_THREADS) ExecutorService service, Supplier defaultLocation,
+            @Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor, Supplier defaultLocation,
             @Memoized Supplier> locations, AzureBlobAsyncClient async,
             ContainerToResourceMetadata container2ResourceMd,
             ListOptionsToListBlobsOptions blobStore2AzureContainerListOptions,
             ListBlobsResponseToResourceList azure2BlobStoreResourceList, AzureBlobToBlob azureBlob2Blob,
             BlobToAzureBlob blob2AzureBlob, BlobPropertiesToBlobMetadata blob2BlobMd,
             BlobToHttpGetOptions blob2ObjectGetOptions) {
-      super(context, blobUtils, service, defaultLocation, locations);
+      super(context, blobUtils, userExecutor, defaultLocation, locations);
       this.async = checkNotNull(async, "async");
       this.container2ResourceMd = checkNotNull(container2ResourceMd, "container2ResourceMd");
       this.blobStore2AzureContainerListOptions = checkNotNull(blobStore2AzureContainerListOptions,
@@ -106,8 +106,7 @@ public class AzureAsyncBlobStore extends BaseAsyncBlobStore {
     */
    @Override
    public ListenableFuture> list() {
-      return Futures
-               .compose(
+      return transform(
                         async.listContainers(includeMetadata()),
                         new Function, org.jclouds.blobstore.domain.PageSet>() {
                            public org.jclouds.blobstore.domain.PageSet apply(
@@ -115,7 +114,7 @@ public class AzureAsyncBlobStore extends BaseAsyncBlobStore {
                               return new PageSetImpl(Iterables.transform(from, container2ResourceMd),
                                        from.getNextMarker());
                            }
-                        }, service);
+                        }, userExecutor);
    }
 
    /**
@@ -152,7 +151,7 @@ public class AzureAsyncBlobStore extends BaseAsyncBlobStore {
    public ListenableFuture> list(String container, ListContainerOptions options) {
       ListBlobsOptions azureOptions = blobStore2AzureContainerListOptions.apply(options);
       ListenableFuture returnVal = async.listBlobs(container, azureOptions.includeMetadata());
-      return Futures.compose(returnVal, azure2BlobStoreResourceList, service);
+      return transform(returnVal, azure2BlobStoreResourceList, userExecutor);
    }
 
    /**
@@ -178,7 +177,7 @@ public class AzureAsyncBlobStore extends BaseAsyncBlobStore {
    public ListenableFuture getBlob(String container, String key, org.jclouds.blobstore.options.GetOptions options) {
       GetOptions azureOptions = blob2ObjectGetOptions.apply(options);
       ListenableFuture returnVal = async.getBlob(container, key, azureOptions);
-      return Futures.compose(returnVal, azureBlob2Blob, service);
+      return transform(returnVal, azureBlob2Blob, userExecutor);
    }
 
    /**
@@ -230,14 +229,11 @@ public class AzureAsyncBlobStore extends BaseAsyncBlobStore {
     */
    @Override
    public ListenableFuture blobMetadata(String container, String key) {
-      return Futures.compose(async.getBlobProperties(container, key), new Function() {
-
-         @Override
+      return transform(async.getBlobProperties(container, key), new Function() {
          public BlobMetadata apply(BlobProperties from) {
             return blob2BlobMd.apply(from);
          }
-
-      }, service);
+      }, userExecutor);
    }
 
    @Override
diff --git a/providers/glesys/src/main/java/org/jclouds/glesys/compute/GleSYSComputeServiceAdapter.java b/providers/glesys/src/main/java/org/jclouds/glesys/compute/GleSYSComputeServiceAdapter.java
index 915bfdc269..b6b3f87cfb 100644
--- a/providers/glesys/src/main/java/org/jclouds/glesys/compute/GleSYSComputeServiceAdapter.java
+++ b/providers/glesys/src/main/java/org/jclouds/glesys/compute/GleSYSComputeServiceAdapter.java
@@ -29,8 +29,6 @@ import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Set;
 import java.util.UUID;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Future;
 
 import javax.annotation.Resource;
 import javax.inject.Inject;
@@ -74,6 +72,8 @@ import com.google.common.collect.FluentIterable;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Iterables;
+import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.ListeningExecutorService;
 
 /**
  * defines the connection between the {@link GleSYSApi} implementation and
@@ -89,17 +89,17 @@ public class GleSYSComputeServiceAdapter implements ComputeServiceAdapter> locations;
 
    @Inject
    public GleSYSComputeServiceAdapter(GleSYSApi api, GleSYSAsyncApi aapi,
-         @Named(Constants.PROPERTY_USER_THREADS) ExecutorService userThreads, Timeouts timeouts,
+         @Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor, Timeouts timeouts,
          @Memoized Supplier> locations) {
       this.api = checkNotNull(api, "api");
       this.aapi = checkNotNull(aapi, "aapi");
-      this.userThreads = checkNotNull(userThreads, "userThreads");
+      this.userExecutor = checkNotNull(userExecutor, "userExecutor");
       this.timeouts = checkNotNull(timeouts, "timeouts");
       this.locations = checkNotNull(locations, "locations");
    }
@@ -209,13 +209,11 @@ public class GleSYSComputeServiceAdapter implements ComputeServiceAdapter listNodes() {
-      return transformParallel(api.getServerApi().list(), new Function>() {
-         @Override
-         public Future apply(Server from) {
+      return transformParallel(api.getServerApi().list(), new Function>() {
+         public ListenableFuture apply(Server from) {
             return aapi.getServerApi().get(from.getId());
          }
-
-      }, userThreads, null, logger, "server details");
+      }, userExecutor, null, logger, "server details");
    }
 
    @Override
diff --git a/providers/gogrid/src/main/java/org/jclouds/gogrid/compute/GoGridComputeService.java b/providers/gogrid/src/main/java/org/jclouds/gogrid/compute/GoGridComputeService.java
index 9daa0b05c7..b454327782 100644
--- a/providers/gogrid/src/main/java/org/jclouds/gogrid/compute/GoGridComputeService.java
+++ b/providers/gogrid/src/main/java/org/jclouds/gogrid/compute/GoGridComputeService.java
@@ -23,7 +23,6 @@ import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_T
 
 import java.util.Map;
 import java.util.Set;
-import java.util.concurrent.ExecutorService;
 import java.util.concurrent.atomic.AtomicReference;
 
 import javax.inject.Inject;
@@ -61,6 +60,7 @@ import org.jclouds.scriptbuilder.functions.InitAdminAccess;
 import com.google.common.base.Optional;
 import com.google.common.base.Predicate;
 import com.google.common.base.Supplier;
+import com.google.common.util.concurrent.ListeningExecutorService;
 
 /**
  * @author Andrew Kennedy
@@ -82,13 +82,13 @@ public class GoGridComputeService extends BaseComputeService {
             @Named(TIMEOUT_NODE_SUSPENDED) Predicate> nodeSuspended,
             InitializeRunScriptOnNodeOrPlaceInBadMap.Factory initScriptRunnerFactory, InitAdminAccess initAdminAccess,
             RunScriptOnNode.Factory runScriptOnNodeFactory, PersistNodeCredentials persistNodeCredentials,
-            Timeouts timeouts, @Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor,
+            Timeouts timeouts, @Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor,
             Optional imageExtension) {
       super(context, credentialStore, images, hardwareProfiles, locations, listNodesStrategy, getImageStrategy,
                getNodeMetadataStrategy, runNodesAndAddToSetStrategy, rebootNodeStrategy, destroyNodeStrategy,
                resumeNodeStrategy, suspendNodeStrategy, templateBuilderProvider, templateOptionsProvider, nodeRunning,
                nodeTerminated, nodeSuspended, initScriptRunnerFactory, initAdminAccess, runScriptOnNodeFactory,
-               persistNodeCredentials, timeouts, executor, imageExtension);
+               persistNodeCredentials, timeouts, userExecutor, imageExtension);
    }
 
    /**
diff --git a/providers/hpcloud-objectstorage/src/main/java/org/jclouds/hpcloud/objectstorage/blobstore/HPCloudObjectStorageAsyncBlobStore.java b/providers/hpcloud-objectstorage/src/main/java/org/jclouds/hpcloud/objectstorage/blobstore/HPCloudObjectStorageAsyncBlobStore.java
index 15f95a099b..4813d5dd32 100644
--- a/providers/hpcloud-objectstorage/src/main/java/org/jclouds/hpcloud/objectstorage/blobstore/HPCloudObjectStorageAsyncBlobStore.java
+++ b/providers/hpcloud-objectstorage/src/main/java/org/jclouds/hpcloud/objectstorage/blobstore/HPCloudObjectStorageAsyncBlobStore.java
@@ -18,8 +18,9 @@
  */
 package org.jclouds.hpcloud.objectstorage.blobstore;
 
+import static com.google.common.util.concurrent.Futures.transform;
+
 import java.util.Set;
-import java.util.concurrent.ExecutorService;
 
 import javax.inject.Inject;
 import javax.inject.Named;
@@ -33,10 +34,9 @@ import org.jclouds.blobstore.options.CreateContainerOptions;
 import org.jclouds.blobstore.strategy.internal.FetchBlobMetadata;
 import org.jclouds.blobstore.util.BlobUtils;
 import org.jclouds.collect.Memoized;
-import org.jclouds.concurrent.Futures;
 import org.jclouds.domain.Location;
-import org.jclouds.hpcloud.objectstorage.HPCloudObjectStorageAsyncApi;
 import org.jclouds.hpcloud.objectstorage.HPCloudObjectStorageApi;
+import org.jclouds.hpcloud.objectstorage.HPCloudObjectStorageAsyncApi;
 import org.jclouds.hpcloud.objectstorage.blobstore.functions.EnableCDNAndCache;
 import org.jclouds.openstack.swift.blobstore.SwiftAsyncBlobStore;
 import org.jclouds.openstack.swift.blobstore.functions.BlobStoreListContainerOptionsToListContainerOptions;
@@ -50,6 +50,7 @@ import org.jclouds.openstack.swift.blobstore.strategy.internal.AsyncMultipartUpl
 import com.google.common.base.Function;
 import com.google.common.base.Supplier;
 import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.ListeningExecutorService;
 
 /**
  * 
@@ -61,7 +62,7 @@ public class HPCloudObjectStorageAsyncBlobStore extends SwiftAsyncBlobStore {
 
    @Inject
    protected HPCloudObjectStorageAsyncBlobStore(BlobStoreContext context, BlobUtils blobUtils,
-            @Named(Constants.PROPERTY_USER_THREADS) ExecutorService service, Supplier defaultLocation,
+            @Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor, Supplier defaultLocation,
             @Memoized Supplier> locations, HPCloudObjectStorageApi sync, HPCloudObjectStorageAsyncApi async,
             ContainerToResourceMetadata container2ResourceMd,
             BlobStoreListContainerOptionsToListContainerOptions container2ContainerListOptions,
@@ -69,7 +70,7 @@ public class HPCloudObjectStorageAsyncBlobStore extends SwiftAsyncBlobStore {
             ObjectToBlobMetadata object2BlobMd, BlobToHttpGetOptions blob2ObjectGetOptions,
             Provider fetchBlobMetadataProvider, EnableCDNAndCache enableAndCache,
             Provider multipartUploadStrategy) {
-      super(context, blobUtils, service, defaultLocation, locations, sync, async, container2ResourceMd,
+      super(context, blobUtils, userExecutor, defaultLocation, locations, sync, async, container2ResourceMd,
                container2ContainerListOptions, container2ResourceList, object2Blob, blob2Object, object2BlobMd,
                blob2ObjectGetOptions, fetchBlobMetadataProvider, multipartUploadStrategy);
       this.enableAndCache = enableAndCache;
@@ -81,7 +82,7 @@ public class HPCloudObjectStorageAsyncBlobStore extends SwiftAsyncBlobStore {
 
       ListenableFuture returnVal = createContainerInLocation(location, container);
       if (options.isPublicRead())
-         return Futures.compose(createContainerInLocation(location, container), new Function() {
+         return transform(createContainerInLocation(location, container), new Function() {
 
             @Override
             public Boolean apply(Boolean input) {
@@ -91,7 +92,7 @@ public class HPCloudObjectStorageAsyncBlobStore extends SwiftAsyncBlobStore {
                return false;
             }
 
-         }, service);
+         }, userExecutor);
       return returnVal;
    }
 }