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/core/src/main/java/org/jclouds/concurrent/FutureIterables.java b/core/src/main/java/org/jclouds/concurrent/FutureIterables.java
index 7ae67d415c..7a9331025c 100644
--- a/core/src/main/java/org/jclouds/concurrent/FutureIterables.java
+++ b/core/src/main/java/org/jclouds/concurrent/FutureIterables.java
@@ -27,16 +27,14 @@ import static org.jclouds.util.Throwables2.containsThrowable;
 import static org.jclouds.util.Throwables2.propagateAuthorizationOrOriginalException;
 
 import java.util.Map;
+import java.util.Map.Entry;
 import java.util.concurrent.ConcurrentMap;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.ExecutionException;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Future;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
 import java.util.concurrent.atomic.AtomicInteger;
 
-import javax.annotation.Resource;
 import javax.inject.Named;
 
 import org.jclouds.Constants;
@@ -47,6 +45,8 @@ import org.jclouds.rest.AuthorizationException;
 
 import com.google.common.annotations.Beta;
 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;
 
 /**
@@ -69,21 +69,21 @@ public class FutureIterables {
    private static BackoffLimitedRetryHandler retryHandler = BackoffLimitedRetryHandler.INSTANCE;
 
    public static  Iterable transformParallel(final Iterable fromIterable,
-         final Function> function, ExecutorService exec, @Nullable Long maxTime, Logger logger,
+         final Function> function, ListeningExecutorService exec, @Nullable Long maxTime, Logger logger,
                String logPrefix) {
       return transformParallel(fromIterable, function, exec, maxTime, logger, logPrefix, retryHandler, maxRetries);
    }
    
    @SuppressWarnings("unchecked")
    public static  Iterable transformParallel(Iterable fromIterable,
-         Function> function, ExecutorService exec, @Nullable Long maxTime, Logger logger,
+         Function> function, ListeningExecutorService exec, @Nullable Long maxTime, Logger logger,
                String logPrefix, BackoffLimitedRetryHandler retryHandler, int maxRetries) {
       Map exceptions = newHashMap();
-      Map> responses = newHashMap();
+      Map> responses = newHashMap();
       for (int i = 0; i < maxRetries; i++) {
          
          for (F from : fromIterable) {
-            Future to = function.apply(from);
+            ListenableFuture to = function.apply(from);
             responses.put(from, to);
          }
          try {
@@ -107,9 +107,10 @@ public class FutureIterables {
       return unwrap(responses.values());
    }
    
-   public static  Map awaitCompletion(Map> responses, ExecutorService exec,
-         @Nullable Long maxTime, final Logger logger, final String logPrefix) throws TimeoutException {
-      final ConcurrentMap errorMap = newConcurrentMap();
+   public static  Map awaitCompletion(Map> responses,
+         ListeningExecutorService exec, @Nullable Long maxTime, final Logger logger, final String logPrefix)
+         throws TimeoutException {
+      final ConcurrentMap errorMap = newConcurrentMap();
       if (responses.size() == 0)
          return errorMap;
       final int total = responses.size();
@@ -117,8 +118,8 @@ public class FutureIterables {
       final AtomicInteger complete = new AtomicInteger(0);
       final AtomicInteger errors = new AtomicInteger(0);
       final long start = System.currentTimeMillis();
-      for (final java.util.Map.Entry> future : responses.entrySet()) {
-         Futures.makeListenable(future.getValue(), exec).addListener(new Runnable() {
+      for (final Entry> future : responses.entrySet()) {
+         future.getValue().addListener(new Runnable() {
             
             @Override
             public void run() {
@@ -168,10 +169,10 @@ public class FutureIterables {
       return errorMap;
    }
    
-   private static  Iterable unwrap(Iterable> values) {
-      return transform(values, new Function, T>() {
+   private static  Iterable unwrap(Iterable> values) {
+      return transform(values, new Function, T>() {
          @Override
-         public T apply(Future from) {
+         public T apply(ListenableFuture from) {
             try {
                return from.get();
             } catch (InterruptedException e) {
diff --git a/core/src/main/java/org/jclouds/concurrent/Futures.java b/core/src/main/java/org/jclouds/concurrent/Futures.java
deleted file mode 100644
index 8f9ad14166..0000000000
--- a/core/src/main/java/org/jclouds/concurrent/Futures.java
+++ /dev/null
@@ -1,282 +0,0 @@
-/**
- * Licensed to jclouds, Inc. (jclouds) under one or more
- * contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  jclouds licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.jclouds.concurrent;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.Executor;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Future;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-import com.google.common.annotations.Beta;
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Function;
-import com.google.common.collect.ForwardingObject;
-import com.google.common.util.concurrent.ExecutionList;
-import com.google.common.util.concurrent.ForwardingFuture;
-import com.google.common.util.concurrent.ListenableFuture;
-
-/**
- * functions related to or replacing those in {@link com.google.common.util.concurrent.Futures}
- * 
- * @author Adrian Cole
- */
-@Beta
-public class Futures {
-   @VisibleForTesting
-   static class CallGetAndRunExecutionList implements Runnable {
-      private final Future delegate;
-      private final ExecutionList executionList;
-
-      CallGetAndRunExecutionList(Future delegate, ExecutionList executionList) {
-         this.delegate = checkNotNull(delegate, "delegate");
-         this.executionList = checkNotNull(executionList, "executionList");
-      }
-
-      @Override
-      public void run() {
-         try {
-            delegate.get();
-         } catch (InterruptedException e) {
-            // This thread was interrupted. This should never happen, so we
-            // throw an IllegalStateException.
-            Thread.currentThread().interrupt();
-            // TODO we cannot inspect the executionList at the moment to make a reasonable
-            // toString()
-            throw new IllegalStateException(String.format(
-                     "interrupted calling get() on [%s], so could not run listeners", delegate), e);
-         } catch (Throwable e) {
-            // ExecutionException / CancellationException / RuntimeException
-            // The task is done, run the listeners.
-         }
-         executionList.execute();
-      }
-
-      @Override
-      public String toString() {
-         return "[delegate=" + delegate + ", executionList=" + executionList + "]";
-      }
-   }
-
-   // Adapted from Guava
-   //
-   // * to allow us to enforce supply of an adapterExecutor
-   // note that this is done so that we can operate in Google AppEngine which
-   // restricts thread creation
-   // * to allow us to print debug info about what the delegate was doing
-   private static class FutureListener {
-
-      private final ExecutorService adapterExecutor;
-
-      // The execution list to hold our listeners.
-      private final ExecutionList executionList = new ExecutionList();
-
-      // This allows us to only start up a thread waiting on the delegate future
-      // when the first listener is added.
-      private final AtomicBoolean hasListeners = new AtomicBoolean(false);
-
-      // The delegate future.
-      private final Future delegate;
-
-      private static  FutureListener create(Future delegate, ExecutorService adapterExecutor) {
-         return new FutureListener(delegate, adapterExecutor);
-      }
-
-      private FutureListener(Future delegate, ExecutorService adapterExecutor) {
-         this.delegate = checkNotNull(delegate, "delegate");
-         this.adapterExecutor = checkNotNull(adapterExecutor, "adapterExecutor");
-      }
-
-      private void addListener(Runnable listener, Executor exec) {
-         executionList.add(listener, exec);
-
-         // When a listener is first added, we run a task that will wait for
-         // the delegate to finish, and when it is done will run the listeners.
-         if (hasListeners.compareAndSet(false, true)) {
-            if (delegate.isDone()) {
-               // If the delegate is already done, run the execution list
-               // immediately on the current thread.
-               executionList.execute();
-               return;
-            }
-            adapterExecutor.execute(new CallGetAndRunExecutionList(delegate, executionList));
-         }
-      }
-
-      private Future getFuture() {
-         return delegate;
-      }
-   }
-
-   private static class ListenableFutureAdapter extends ForwardingFuture implements ListenableFuture {
-      private final FutureListener futureListener;
-
-      private static  ListenableFutureAdapter create(Future future, ExecutorService executor) {
-         return new ListenableFutureAdapter(future, executor);
-      }
-
-      private ListenableFutureAdapter(Future future, ExecutorService executor) {
-         this.futureListener = FutureListener.create(future, executor);
-      }
-
-      @Override
-      protected Future delegate() {
-         return futureListener.getFuture();
-      }
-
-      @Override
-      public void addListener(Runnable listener, Executor exec) {
-         futureListener.addListener(listener, exec);
-      }
-   }
-
-   private static class LazyListenableFutureFunctionAdapter extends ForwardingObject implements
-            ListenableFuture {
-      private final FutureListener futureListener;
-      private final Function function;
-
-      private static  LazyListenableFutureFunctionAdapter create(Future future,
-               Function function, ExecutorService executor) {
-         return new LazyListenableFutureFunctionAdapter(future, function, executor);
-      }
-
-      private static  LazyListenableFutureFunctionAdapter create(FutureListener futureListener,
-               Function function) {
-         return new LazyListenableFutureFunctionAdapter(futureListener, function);
-      }
-
-      private LazyListenableFutureFunctionAdapter(Future future, Function function,
-               ExecutorService executor) {
-         this(FutureListener.create(future, executor), function);
-      }
-
-      private LazyListenableFutureFunctionAdapter(FutureListener futureListener,
-               Function function) {
-         this.futureListener = checkNotNull(futureListener, "futureListener");
-         this.function = checkNotNull(function, "function");
-      }
-
-      /*
-       * Concurrency detail:
-       * 
-       * 

To preserve the idempotency of calls to this.get(*) calls to the function are only - * applied once. A lock is required to prevent multiple applications of the function. The - * calls to future.get(*) are performed outside the lock, as is required to prevent calls to - * get(long, TimeUnit) to persist beyond their timeout. - * - *

Calls to future.get(*) on every call to this.get(*) also provide the cancellation - * behavior for this. - * - *

(Consider: in thread A, call get(), in thread B call get(long, TimeUnit). Thread B may - * have to wait for Thread A to finish, which would be unacceptable.) - * - *

Note that each call to Future.get(*) results in a call to Future.get(*), but the - * function is only applied once, so Future.get(*) is assumed to be idempotent. - */ - - private final Object lock = new Object(); - private boolean set = false; - private O value = null; - - @Override - public O get() throws InterruptedException, ExecutionException { - return apply(futureListener.getFuture().get()); - } - - @Override - public O get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException { - return apply(futureListener.getFuture().get(timeout, unit)); - } - - private O apply(I raw) { - synchronized (lock) { - if (!set) { - value = function.apply(raw); - set = true; - } - return value; - } - } - - @Override - public boolean cancel(boolean mayInterruptIfRunning) { - return futureListener.getFuture().cancel(mayInterruptIfRunning); - } - - @Override - public boolean isCancelled() { - return futureListener.getFuture().isCancelled(); - } - - @Override - public boolean isDone() { - return futureListener.getFuture().isDone(); - } - - @Override - public void addListener(Runnable listener, Executor exec) { - futureListener.addListener(listener, exec); - } - - @Override - protected Object delegate() { - return futureListener.getFuture(); - } - - } - - /** - * Just like {@code Futures#compose} except that we check the type of the executorService before - * creating the Future. If we are single threaded, invoke the function lazy as opposed to - * chaining, so that we don't invoke get() early. - */ - public static ListenableFuture compose(Future future, final Function function, - ExecutorService executorService) { - if (future instanceof Futures.ListenableFutureAdapter) { - Futures.ListenableFutureAdapter lf = (ListenableFutureAdapter) future; - if (lf.futureListener.adapterExecutor.getClass().isAnnotationPresent(SingleThreaded.class)) - return Futures.LazyListenableFutureFunctionAdapter.create( - ((org.jclouds.concurrent.Futures.ListenableFutureAdapter) future).futureListener, function); - else - return com.google.common.util.concurrent.Futures.transform(lf, function, executorService); - } else if (executorService.getClass().isAnnotationPresent(SingleThreaded.class)) { - return Futures.LazyListenableFutureFunctionAdapter.create(future, function, executorService); - } else { - return com.google.common.util.concurrent.Futures.transform(Futures.makeListenable(future, executorService), - function, executorService); - } - } - - /** - * Just like {@code Futures#makeListenable} except that we pass in an executorService. - *

- * Temporary hack until http://code.google.com/p/guava-libraries/issues/detail?id=317 is fixed. - */ - public static ListenableFuture makeListenable(Future future, ExecutorService executorService) { - if (future instanceof ListenableFuture) { - return (ListenableFuture) future; - } - return ListenableFutureAdapter.create(future, executorService); - } - -} diff --git a/core/src/main/java/org/jclouds/concurrent/config/DescribedFuture.java b/core/src/main/java/org/jclouds/concurrent/config/DescribedFuture.java deleted file mode 100644 index b7454b33f7..0000000000 --- a/core/src/main/java/org/jclouds/concurrent/config/DescribedFuture.java +++ /dev/null @@ -1,130 +0,0 @@ -/** - * Licensed to jclouds, Inc. (jclouds) under one or more - * contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. jclouds licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.jclouds.concurrent.config; - -import java.util.concurrent.ExecutionException; -import java.util.concurrent.Future; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; - -class DescribedFuture implements Future { - protected final Future delegate; - private final String description; - private StackTraceElement[] submissionTrace; - - DescribedFuture(Future delegate, String description, StackTraceElement[] submissionTrace) { - this.delegate = delegate; - this.description = description; - this.submissionTrace = submissionTrace; - } - - @Override - public boolean cancel(boolean arg0) { - return delegate.cancel(arg0); - } - - @Override - public T get() throws InterruptedException, ExecutionException { - try { - return delegate.get(); - } catch (ExecutionException e) { - throw ensureCauseHasSubmissionTrace(e); - } catch (InterruptedException e) { - throw ensureCauseHasSubmissionTrace(e); - } - } - - @Override - public T get(long arg0, TimeUnit arg1) throws InterruptedException, ExecutionException, TimeoutException { - try { - return delegate.get(arg0, arg1); - } catch (ExecutionException e) { - throw ensureCauseHasSubmissionTrace(e); - } catch (InterruptedException e) { - throw ensureCauseHasSubmissionTrace(e); - } catch (TimeoutException e) { - throw ensureCauseHasSubmissionTrace(e); - } - } - - /** This method does the work to ensure _if_ a submission stack trace was provided, - * it is included in the exception. most errors are thrown from the frame of the - * Future.get call, with a cause that took place in the executor's thread. - * We extend the stack trace of that cause with the submission stack trace. - * (An alternative would be to put the stack trace as a root cause, - * at the bottom of the stack, or appended to all traces, or inserted - * after the second cause, etc ... but since we can't change the "Caused by:" - * method in Throwable the compromise made here seems best.) - */ - private ET ensureCauseHasSubmissionTrace(ET e) { - if (submissionTrace==null) return e; - if (e.getCause()==null) { - ExecutionException ee = new ExecutionException("task submitted from the following trace", null); - e.initCause(ee); - return e; - } - Throwable cause = e.getCause(); - StackTraceElement[] causeTrace = cause.getStackTrace(); - boolean causeIncludesSubmissionTrace = submissionTrace.length >= causeTrace.length; - for (int i=0; causeIncludesSubmissionTrace && i List> invokeAll(Collection> tasks) throws InterruptedException { - return delegate.invokeAll(tasks); - } - - @Override - public List> invokeAll(Collection> tasks, long timeout, TimeUnit unit) - throws InterruptedException { - return delegate.invokeAll(tasks, timeout, unit); - } - - @Override - public T invokeAny(Collection> tasks) throws InterruptedException, ExecutionException { - return delegate.invokeAny(tasks); - } - - @Override - public T invokeAny(Collection> tasks, long timeout, TimeUnit unit) - throws InterruptedException, ExecutionException, TimeoutException { - return delegate.invokeAny(tasks, timeout, unit); - } - - @Override - public boolean isShutdown() { - return delegate.isShutdown(); - } - - @Override - public boolean isTerminated() { - return delegate.isTerminated(); - } - - @Override - public void shutdown() { - delegate.shutdown(); - } - - @Override - public List shutdownNow() { - return delegate.shutdownNow(); - } - - @Override - public Future submit(Callable task) { - return new DescribedFuture(delegate.submit(task), task.toString(), getStackTraceHere()); - } - - @SuppressWarnings({ "unchecked", "rawtypes" }) - @Override - public Future submit(Runnable task) { - return new DescribedFuture(delegate.submit(task), task.toString(), getStackTraceHere()); - } - - @Override - public Future submit(Runnable task, T result) { // NO_UCD - return new DescribedFuture(delegate.submit(task, result), task.toString(), getStackTraceHere()); - } - - @Override - public void execute(Runnable arg0) { - delegate.execute(arg0); - } - - @Override - public boolean equals(Object obj) { - return delegate.equals(obj); - } - - @Override - public int hashCode() { - return delegate.hashCode(); - } - - @Override - public String toString() { - return delegate.toString(); - } - -} diff --git a/core/src/main/java/org/jclouds/concurrent/config/ExecutorServiceModule.java b/core/src/main/java/org/jclouds/concurrent/config/ExecutorServiceModule.java index 9da955d925..3e908457f3 100644 --- a/core/src/main/java/org/jclouds/concurrent/config/ExecutorServiceModule.java +++ b/core/src/main/java/org/jclouds/concurrent/config/ExecutorServiceModule.java @@ -18,6 +18,7 @@ */ package org.jclouds.concurrent.config; +import static com.google.common.util.concurrent.MoreExecutors.listeningDecorator; import static org.jclouds.Constants.PROPERTY_IO_WORKER_THREADS; import static org.jclouds.Constants.PROPERTY_USER_THREADS; import static org.jclouds.concurrent.DynamicExecutors.newScalingThreadPool; @@ -30,19 +31,19 @@ import java.util.concurrent.Executors; import java.util.concurrent.ThreadFactory; import javax.annotation.Resource; -import javax.inject.Inject; import javax.inject.Named; import javax.inject.Singleton; import org.jclouds.lifecycle.Closer; import org.jclouds.logging.Logger; +import com.google.common.util.concurrent.ListeningExecutorService; import com.google.common.util.concurrent.ThreadFactoryBuilder; import com.google.inject.AbstractModule; import com.google.inject.Provides; /** - * Configures {@link ExecutorService}. + * Configures {@link ListeningExecutorService}. * * Note that this uses threads. * @@ -60,9 +61,9 @@ public class ExecutorServiceModule extends AbstractModule { @Resource private Logger logger = Logger.NULL; - private final ExecutorService service; + private final ListeningExecutorService service; - private ShutdownExecutorOnClose(ExecutorService service) { + private ShutdownExecutorOnClose(ListeningExecutorService service) { this.service = service; } @@ -74,26 +75,23 @@ public class ExecutorServiceModule extends AbstractModule { } } - final ExecutorService userExecutorFromConstructor; - - final ExecutorService ioExecutorFromConstructor; - - @Inject - public ExecutorServiceModule(@Named(PROPERTY_USER_THREADS) ExecutorService userThreads, - @Named(PROPERTY_IO_WORKER_THREADS) ExecutorService ioThreads) { - this.userExecutorFromConstructor = addToStringOnSubmit(userThreads); - this.ioExecutorFromConstructor = addToStringOnSubmit(ioThreads); - } - - private ExecutorService addToStringOnSubmit(ExecutorService executor) { - if (executor != null) { - return new DescribingExecutorService(executor); - } - return executor; - } + final ListeningExecutorService userExecutorFromConstructor; + final ListeningExecutorService ioExecutorFromConstructor; public ExecutorServiceModule() { - this(null, null); + this.userExecutorFromConstructor = null; + this.ioExecutorFromConstructor = null; + } + + public ExecutorServiceModule(@Named(PROPERTY_USER_THREADS) ExecutorService userExecutor, + @Named(PROPERTY_IO_WORKER_THREADS) ExecutorService ioExecutor) { + this(listeningDecorator(userExecutor), listeningDecorator(ioExecutor)); + } + + public ExecutorServiceModule(@Named(PROPERTY_USER_THREADS) ListeningExecutorService userExecutor, + @Named(PROPERTY_IO_WORKER_THREADS) ListeningExecutorService ioExecutor) { + this.userExecutorFromConstructor = WithSubmissionTrace.wrap(userExecutor); + this.ioExecutorFromConstructor = WithSubmissionTrace.wrap(ioExecutor); } @Override @@ -103,50 +101,55 @@ public class ExecutorServiceModule extends AbstractModule { @Provides @Singleton @Named(PROPERTY_USER_THREADS) - ExecutorService provideExecutorService(@Named(PROPERTY_USER_THREADS) int count, Closer closer) { // NO_UCD + ListeningExecutorService provideListeningUserExecutorService(@Named(PROPERTY_USER_THREADS) int count, Closer closer) { // NO_UCD if (userExecutorFromConstructor != null) return userExecutorFromConstructor; - return shutdownOnClose(addToStringOnSubmit(newThreadPoolNamed("user thread %d", count)), closer); + return shutdownOnClose(WithSubmissionTrace.wrap(newThreadPoolNamed("user thread %d", count)), closer); } @Provides @Singleton @Named(PROPERTY_IO_WORKER_THREADS) - ExecutorService provideIOExecutor(@Named(PROPERTY_IO_WORKER_THREADS) int count, Closer closer) { // NO_UCD + ListeningExecutorService provideListeningIOExecutorService(@Named(PROPERTY_IO_WORKER_THREADS) int count, + Closer closer) { // NO_UCD if (ioExecutorFromConstructor != null) return ioExecutorFromConstructor; - return shutdownOnClose(addToStringOnSubmit(newThreadPoolNamed("i/o thread %d", count)), closer); + return shutdownOnClose(WithSubmissionTrace.wrap(newThreadPoolNamed("i/o thread %d", count)), closer); } - static T shutdownOnClose(final T service, Closer closer) { + @Provides + @Singleton + @Named(PROPERTY_USER_THREADS) + ExecutorService provideUserExecutorService(@Named(PROPERTY_USER_THREADS) ListeningExecutorService in) { // NO_UCD + return in; + } + + @Provides + @Singleton + @Named(PROPERTY_IO_WORKER_THREADS) + ExecutorService provideIOExecutorService(@Named(PROPERTY_IO_WORKER_THREADS) ListeningExecutorService in) { // NO_UCD + return in; + } + + static T shutdownOnClose(final T service, Closer closer) { closer.addToClose(new ShutdownExecutorOnClose(service)); return service; } - private ExecutorService newCachedThreadPoolNamed(String name) { - return Executors.newCachedThreadPool(namedThreadFactory(name)); + private ListeningExecutorService newCachedThreadPoolNamed(String name) { + return listeningDecorator(Executors.newCachedThreadPool(namedThreadFactory(name))); } - private ExecutorService newThreadPoolNamed(String name, int maxCount) { + private ListeningExecutorService newThreadPoolNamed(String name, int maxCount) { return maxCount == 0 ? newCachedThreadPoolNamed(name) : newScalingThreadPoolNamed(name, maxCount); } - private ExecutorService newScalingThreadPoolNamed(String name, int maxCount) { - return newScalingThreadPool(1, maxCount, 60L * 1000, namedThreadFactory(name)); + private ListeningExecutorService newScalingThreadPoolNamed(String name, int maxCount) { + return listeningDecorator(newScalingThreadPool(1, maxCount, 60L * 1000, namedThreadFactory(name))); } private ThreadFactory namedThreadFactory(String name) { return new ThreadFactoryBuilder().setNameFormat(name).setThreadFactory(Executors.defaultThreadFactory()).build(); } - /** returns the stack trace at the caller */ - static StackTraceElement[] getStackTraceHere() { - // remove the first two items in the stack trace (because the first one refers to the call to - // Thread.getStackTrace, and the second one is us) - StackTraceElement[] fullSubmissionTrace = Thread.currentThread().getStackTrace(); - StackTraceElement[] cleanedSubmissionTrace = new StackTraceElement[fullSubmissionTrace.length - 2]; - System.arraycopy(fullSubmissionTrace, 2, cleanedSubmissionTrace, 0, cleanedSubmissionTrace.length); - return cleanedSubmissionTrace; - } - } diff --git a/core/src/main/java/org/jclouds/concurrent/config/ScheduledExecutorServiceModule.java b/core/src/main/java/org/jclouds/concurrent/config/ScheduledExecutorServiceModule.java index 11ab487d59..e0d3d46fc4 100644 --- a/core/src/main/java/org/jclouds/concurrent/config/ScheduledExecutorServiceModule.java +++ b/core/src/main/java/org/jclouds/concurrent/config/ScheduledExecutorServiceModule.java @@ -1,22 +1,21 @@ package org.jclouds.concurrent.config; +import static com.google.common.util.concurrent.MoreExecutors.listeningDecorator; +import static java.util.concurrent.Executors.defaultThreadFactory; +import static java.util.concurrent.Executors.newScheduledThreadPool; +import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor; import static org.jclouds.Constants.PROPERTY_SCHEDULER_THREADS; -import static org.jclouds.concurrent.config.ExecutorServiceModule.getStackTraceHere; import static org.jclouds.concurrent.config.ExecutorServiceModule.shutdownOnClose; -import java.util.concurrent.Callable; -import java.util.concurrent.Delayed; -import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.ScheduledFuture; import java.util.concurrent.ThreadFactory; -import java.util.concurrent.TimeUnit; import javax.inject.Named; import javax.inject.Singleton; import org.jclouds.lifecycle.Closer; +import com.google.common.util.concurrent.ListeningScheduledExecutorService; import com.google.common.util.concurrent.ThreadFactoryBuilder; import com.google.inject.AbstractModule; import com.google.inject.Provides; @@ -32,76 +31,28 @@ import com.google.inject.Provides; * */ public class ScheduledExecutorServiceModule extends AbstractModule { - - private static class DescribingScheduledExecutorService extends DescribingExecutorService implements - ScheduledExecutorService { - - private DescribingScheduledExecutorService(ScheduledExecutorService delegate) { - super(delegate); - } - - @SuppressWarnings({ "unchecked", "rawtypes" }) - @Override - public ScheduledFuture schedule(Runnable command, long delay, TimeUnit unit) { - return new DescribedScheduledFuture(((ScheduledExecutorService) delegate).schedule(command, delay, unit), - command.toString(), getStackTraceHere()); - } - - @Override - public ScheduledFuture schedule(Callable callable, long delay, TimeUnit unit) { - return new DescribedScheduledFuture(((ScheduledExecutorService) delegate).schedule(callable, delay, unit), - callable.toString(), getStackTraceHere()); - } - - @SuppressWarnings({ "unchecked", "rawtypes" }) - @Override - public ScheduledFuture scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit) { - return new DescribedScheduledFuture(((ScheduledExecutorService) delegate).scheduleAtFixedRate(command, - initialDelay, period, unit), command.toString(), getStackTraceHere()); - } - - @SuppressWarnings({ "unchecked", "rawtypes" }) - @Override - public ScheduledFuture scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit) { - return new DescribedScheduledFuture(((ScheduledExecutorService) delegate).scheduleWithFixedDelay(command, - initialDelay, delay, unit), command.toString(), getStackTraceHere()); - } - } - - private static class DescribedScheduledFuture extends DescribedFuture implements ScheduledFuture { - - private DescribedScheduledFuture(ScheduledFuture delegate, String description, - StackTraceElement[] submissionTrace) { - super(delegate, description, submissionTrace); - } - - @Override - public long getDelay(TimeUnit unit) { - return ((ScheduledFuture) delegate).getDelay(unit); - } - - @Override - public int compareTo(Delayed o) { - return ((ScheduledFuture) delegate).compareTo(o); - } - } - - private static ScheduledExecutorService addToStringOnSchedule(ScheduledExecutorService executor) { - return (executor != null) ? new DescribingScheduledExecutorService(executor) : executor; + @Provides + @Singleton + @Named(PROPERTY_SCHEDULER_THREADS) + ListeningScheduledExecutorService provideListeningScheduledExecutorService( + @Named(PROPERTY_SCHEDULER_THREADS) int count, Closer closer) { + return shutdownOnClose(WithSubmissionTrace.wrap(newScheduledThreadPoolNamed("scheduler thread %d", count)), + closer); } @Provides @Singleton @Named(PROPERTY_SCHEDULER_THREADS) - ScheduledExecutorService provideScheduledExecutor(@Named(PROPERTY_SCHEDULER_THREADS) int count, Closer closer) { - return shutdownOnClose(addToStringOnSchedule(newScheduledThreadPoolNamed("scheduler thread %d", count)), closer); + ScheduledExecutorService provideScheduledExecutor( + @Named(PROPERTY_SCHEDULER_THREADS) ListeningScheduledExecutorService in) { + return in; } - private static ScheduledExecutorService newScheduledThreadPoolNamed(String name, int maxCount) { - ThreadFactory factory = new ThreadFactoryBuilder().setNameFormat(name) - .setThreadFactory(Executors.defaultThreadFactory()).build(); - return maxCount == 0 ? Executors.newSingleThreadScheduledExecutor(factory) : Executors.newScheduledThreadPool( - maxCount, factory); + private static ListeningScheduledExecutorService newScheduledThreadPoolNamed(String name, int maxCount) { + ThreadFactory factory = new ThreadFactoryBuilder().setNameFormat(name).setThreadFactory(defaultThreadFactory()) + .build(); + return listeningDecorator(maxCount == 0 ? newSingleThreadScheduledExecutor(factory) : newScheduledThreadPool( + maxCount, factory)); } @Override diff --git a/core/src/main/java/org/jclouds/concurrent/config/WithSubmissionTrace.java b/core/src/main/java/org/jclouds/concurrent/config/WithSubmissionTrace.java new file mode 100644 index 0000000000..7f9ed35fff --- /dev/null +++ b/core/src/main/java/org/jclouds/concurrent/config/WithSubmissionTrace.java @@ -0,0 +1,255 @@ +/** + * Licensed to jclouds, Inc. (jclouds) under one or more + * contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. jclouds licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.jclouds.concurrent.config; + +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.collect.Iterables.filter; +import static com.google.common.collect.Iterables.toArray; +import static com.google.common.collect.ObjectArrays.concat; + +import java.util.Arrays; +import java.util.Set; +import java.util.concurrent.Callable; +import java.util.concurrent.Delayed; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +import com.google.common.base.Predicate; +import com.google.common.collect.ImmutableSet; +import com.google.common.util.concurrent.ForwardingFuture; +import com.google.common.util.concurrent.ForwardingListenableFuture; +import com.google.common.util.concurrent.ForwardingListeningExecutorService; + +/** + * + * @author Adrian Cole + */ +public class WithSubmissionTrace { + + private WithSubmissionTrace() { + } + + public static ListeningExecutorService wrap(com.google.common.util.concurrent.ListeningExecutorService delegate) { + return new ListeningExecutorService(delegate); + } + + private static class ListeningExecutorService extends ForwardingListeningExecutorService { + + private final com.google.common.util.concurrent.ListeningExecutorService delegate; + + private ListeningExecutorService(com.google.common.util.concurrent.ListeningExecutorService delegate) { + this.delegate = checkNotNull(delegate, "delegate"); + } + + @Override + protected com.google.common.util.concurrent.ListeningExecutorService delegate() { + return delegate; + } + + @Override + public com.google.common.util.concurrent.ListenableFuture submit(Callable task) { + return new ListenableFuture(delegate().submit(task)); + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Override + public com.google.common.util.concurrent.ListenableFuture submit(Runnable task) { + return new ListenableFuture(delegate().submit(task)); + } + + @Override + public com.google.common.util.concurrent.ListenableFuture submit(Runnable task, T result) { + return new ListenableFuture(delegate().submit(task, result)); + } + } + + private static class ListenableFuture extends ForwardingListenableFuture { + private final com.google.common.util.concurrent.ListenableFuture delegate; + private final StackTraceElement[] submissionTrace; + + ListenableFuture(com.google.common.util.concurrent.ListenableFuture delegate) { + this.delegate = checkNotNull(delegate, "delegate"); + this.submissionTrace = getStackTraceHere(); + } + + @Override + protected com.google.common.util.concurrent.ListenableFuture delegate() { + return delegate; + } + + @Override + public T get() throws InterruptedException, ExecutionException { + try { + return delegate().get(); + } catch (ExecutionException e) { + throw addSubmissionTrace(submissionTrace, e); + } + } + + @Override + public T get(long arg0, TimeUnit arg1) throws InterruptedException, ExecutionException, TimeoutException { + try { + return delegate().get(arg0, arg1); + } catch (ExecutionException e) { + throw addSubmissionTrace(submissionTrace, e); + } + } + } + + private final static Set stackTracesToTrim = ImmutableSet.of(WithSubmissionTrace.class.getName(), + ListeningExecutorService.class.getName(), ListenableFuture.class.getName(), + ListeningScheduledExecutorService.class.getName(), ScheduledFuture.class.getName()); + + /** returns the stack trace at the caller */ + private static StackTraceElement[] getStackTraceHere() { + StackTraceElement[] trace = Thread.currentThread().getStackTrace(); + return filterTrace(trace); + } + + private static StackTraceElement[] filterTrace(StackTraceElement[] trace) { + return toArray(filter(Arrays.asList(trace), new Predicate() { + public boolean apply(StackTraceElement input) { + String className = input.getClassName(); + return !stackTracesToTrim.contains(className); + } + }), StackTraceElement.class); + } + + private static ExecutionException addSubmissionTrace(StackTraceElement[] submissionTrace, ExecutionException e) { + if (e.getCause() == null) { + return filterTrace(e); + } + Throwable cause = e.getCause(); + StackTraceElement[] combined = filterTrace(concat(cause.getStackTrace(), submissionTrace, StackTraceElement.class)); + cause.setStackTrace(combined); + return filterTrace(e); + } + + private static ExecutionException filterTrace(ExecutionException e) { + StackTraceElement[] withoutHere = filterTrace(e.getStackTrace()); + e.setStackTrace(withoutHere); + return e; + } + + public static ListeningScheduledExecutorService wrap( + com.google.common.util.concurrent.ListeningScheduledExecutorService delegate) { + return new ListeningScheduledExecutorService(delegate); + } + + private static class ListeningScheduledExecutorService extends ListeningExecutorService implements + com.google.common.util.concurrent.ListeningScheduledExecutorService { + + private ListeningScheduledExecutorService( + com.google.common.util.concurrent.ListeningScheduledExecutorService delegate) { + super(delegate); + } + + @Override + protected com.google.common.util.concurrent.ListeningScheduledExecutorService delegate() { + return com.google.common.util.concurrent.ListeningScheduledExecutorService.class.cast(super.delegate()); + } + + @Override + public ListenableFuture submit(Callable task) { + return new ListenableFuture(delegate().submit(task)); + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Override + public ListenableFuture submit(Runnable task) { + return new ListenableFuture(delegate().submit(task)); + } + + @Override + public ListenableFuture submit(Runnable task, T result) { + return new ListenableFuture(delegate().submit(task, result)); + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + @Override + public ScheduledFuture schedule(Runnable command, long delay, TimeUnit unit) { + return new ScheduledFuture(delegate().schedule(command, delay, unit)); + } + + @Override + public ScheduledFuture schedule(Callable callable, long delay, TimeUnit unit) { + return new ScheduledFuture(delegate().schedule(callable, delay, unit)); + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + @Override + public ScheduledFuture scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit) { + return new ScheduledFuture(delegate().scheduleAtFixedRate(command, initialDelay, period, unit)); + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + @Override + public ScheduledFuture scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit) { + return new ScheduledFuture(delegate().scheduleWithFixedDelay(command, initialDelay, delay, unit)); + } + + } + + private static class ScheduledFuture extends ForwardingFuture implements + java.util.concurrent.ScheduledFuture { + + private final java.util.concurrent.ScheduledFuture delegate; + private final StackTraceElement[] submissionTrace; + + private ScheduledFuture(java.util.concurrent.ScheduledFuture delegate) { + this.delegate = checkNotNull(delegate, "delegate"); + this.submissionTrace = getStackTraceHere(); + } + + @Override + protected java.util.concurrent.ScheduledFuture delegate() { + return delegate; + } + + @Override + public long getDelay(TimeUnit arg0) { + return delegate().getDelay(arg0); + } + + @Override + public int compareTo(Delayed arg0) { + return delegate().compareTo(arg0); + } + + @Override + public T get() throws InterruptedException, ExecutionException { + try { + return delegate().get(); + } catch (ExecutionException e) { + throw addSubmissionTrace(submissionTrace, e); + } + } + + @Override + public T get(long arg0, TimeUnit arg1) throws InterruptedException, ExecutionException, TimeoutException { + try { + return delegate().get(arg0, arg1); + } catch (ExecutionException e) { + throw addSubmissionTrace(submissionTrace, e); + } + } + } + +} diff --git a/core/src/main/java/org/jclouds/events/config/EventBusModule.java b/core/src/main/java/org/jclouds/events/config/EventBusModule.java index 559e86492a..2bb2d942e3 100644 --- a/core/src/main/java/org/jclouds/events/config/EventBusModule.java +++ b/core/src/main/java/org/jclouds/events/config/EventBusModule.java @@ -22,8 +22,6 @@ package org.jclouds.events.config; import static com.google.inject.Scopes.SINGLETON; import static org.jclouds.Constants.PROPERTY_USER_THREADS; -import java.util.concurrent.ExecutorService; - import javax.inject.Named; import javax.inject.Singleton; @@ -33,6 +31,7 @@ import org.jclouds.events.handlers.DeadEventLoggingHandler; import com.google.common.eventbus.AsyncEventBus; import com.google.common.eventbus.EventBus; +import com.google.common.util.concurrent.ListeningExecutorService; import com.google.inject.AbstractModule; import com.google.inject.Provides; @@ -56,9 +55,9 @@ public class EventBusModule extends AbstractModule { */ @Provides @Singleton - AsyncEventBus provideAsyncEventBus(@Named(PROPERTY_USER_THREADS) ExecutorService executor, + AsyncEventBus provideAsyncEventBus(@Named(PROPERTY_USER_THREADS) ListeningExecutorService userExecutor, DeadEventLoggingHandler deadEventsHandler) {// NO_UCD - AsyncEventBus asyncBus = new AsyncEventBus("jclouds-async-event-bus", executor); + AsyncEventBus asyncBus = new AsyncEventBus("jclouds-async-event-bus", userExecutor); asyncBus.register(deadEventsHandler); return asyncBus; } diff --git a/core/src/main/java/org/jclouds/http/HttpCommandExecutorService.java b/core/src/main/java/org/jclouds/http/HttpCommandExecutorService.java index 805e61cc95..6408d9cc1e 100644 --- a/core/src/main/java/org/jclouds/http/HttpCommandExecutorService.java +++ b/core/src/main/java/org/jclouds/http/HttpCommandExecutorService.java @@ -20,6 +20,8 @@ package org.jclouds.http; import java.util.concurrent.Future; +import com.google.common.util.concurrent.ListenableFuture; + /** * Capable of invoking http commands. * @@ -35,5 +37,5 @@ public interface HttpCommandExecutorService { * that generates requests * @return {@link Future} containing the response from the {@code endpoint} */ - Future submit(HttpCommand command); + ListenableFuture submit(HttpCommand command); } diff --git a/core/src/main/java/org/jclouds/http/internal/BaseHttpCommandExecutorService.java b/core/src/main/java/org/jclouds/http/internal/BaseHttpCommandExecutorService.java index 814ee1e742..8264c4c707 100644 --- a/core/src/main/java/org/jclouds/http/internal/BaseHttpCommandExecutorService.java +++ b/core/src/main/java/org/jclouds/http/internal/BaseHttpCommandExecutorService.java @@ -27,8 +27,6 @@ import java.io.FilterInputStream; import java.io.IOException; import java.io.InputStream; import java.util.concurrent.Callable; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Future; import javax.annotation.Resource; import javax.inject.Inject; @@ -50,6 +48,8 @@ import org.jclouds.logging.Logger; import org.jclouds.util.Throwables2; import com.google.common.io.NullOutputStream; +import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.ListeningExecutorService; /** * @@ -62,7 +62,7 @@ public abstract class BaseHttpCommandExecutorService implements HttpCommandEx private final DelegatingRetryHandler retryHandler; private final IOExceptionRetryHandler ioRetryHandler; private final DelegatingErrorHandler errorHandler; - private final ExecutorService ioWorkerExecutor; + private final ListeningExecutorService ioExecutor; @Resource protected Logger logger = Logger.NULL; @@ -74,7 +74,7 @@ public abstract class BaseHttpCommandExecutorService implements HttpCommandEx @Inject protected BaseHttpCommandExecutorService(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) { this.utils = checkNotNull(utils, "utils"); @@ -82,7 +82,7 @@ public abstract class BaseHttpCommandExecutorService implements HttpCommandEx this.retryHandler = checkNotNull(retryHandler, "retryHandler"); this.ioRetryHandler = checkNotNull(ioRetryHandler, "ioRetryHandler"); this.errorHandler = checkNotNull(errorHandler, "errorHandler"); - this.ioWorkerExecutor = checkNotNull(ioWorkerExecutor, "ioWorkerExecutor"); + this.ioExecutor = checkNotNull(ioExecutor, "ioExecutor"); this.wire = checkNotNull(wire, "wire"); } @@ -124,12 +124,12 @@ public abstract class BaseHttpCommandExecutorService implements HttpCommandEx } @Override - public Future submit(HttpCommand command) { + public ListenableFuture submit(HttpCommand command) { HttpRequest request = command.getCurrentRequest(); checkRequestHasContentLengthOrChunkedEncoding(request, "if the request has a payload, it must be set to chunked encoding or specify a content length: " + request); - return ioWorkerExecutor.submit(new HttpResponseCallable(command)); + return ioExecutor.submit(new HttpResponseCallable(command)); } public class HttpResponseCallable implements Callable { diff --git a/core/src/main/java/org/jclouds/http/internal/JavaUrlHttpCommandExecutorService.java b/core/src/main/java/org/jclouds/http/internal/JavaUrlHttpCommandExecutorService.java index 2fff9d6238..7cba6f6afb 100644 --- a/core/src/main/java/org/jclouds/http/internal/JavaUrlHttpCommandExecutorService.java +++ b/core/src/main/java/org/jclouds/http/internal/JavaUrlHttpCommandExecutorService.java @@ -44,7 +44,6 @@ import java.net.SocketAddress; import java.net.URL; import java.util.List; import java.util.Map; -import java.util.concurrent.ExecutorService; import javax.inject.Named; import javax.inject.Singleton; @@ -69,6 +68,7 @@ import com.google.common.base.Supplier; import com.google.common.collect.ImmutableMultimap; import com.google.common.collect.ImmutableMultimap.Builder; import com.google.common.io.CountingOutputStream; +import com.google.common.util.concurrent.ListeningExecutorService; import com.google.inject.Inject; /** @@ -90,12 +90,12 @@ public class JavaUrlHttpCommandExecutorService extends BaseHttpCommandExecutorSe @Inject public JavaUrlHttpCommandExecutorService(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, @Named("untrusted") HostnameVerifier verifier, @Named("untrusted") Supplier untrustedSSLContextProvider) throws SecurityException, NoSuchFieldException { - super(utils, contentMetadataCodec, ioWorkerExecutor, retryHandler, ioRetryHandler, errorHandler, wire); + super(utils, contentMetadataCodec, ioExecutor, retryHandler, ioRetryHandler, errorHandler, wire); if (utils.getMaxConnections() > 0) System.setProperty("http.maxConnections", String.valueOf(checkNotNull(utils, "utils").getMaxConnections())); this.untrustedSSLContextProvider = checkNotNull(untrustedSSLContextProvider, "untrustedSSLContextProvider"); diff --git a/core/src/main/java/org/jclouds/lifecycle/BaseLifeCycle.java b/core/src/main/java/org/jclouds/lifecycle/BaseLifeCycle.java index 8859b36c78..6c9f47a345 100644 --- a/core/src/main/java/org/jclouds/lifecycle/BaseLifeCycle.java +++ b/core/src/main/java/org/jclouds/lifecycle/BaseLifeCycle.java @@ -20,17 +20,17 @@ package org.jclouds.lifecycle; import java.util.Arrays; import java.util.List; -import java.util.concurrent.ExecutorService; import java.util.concurrent.atomic.AtomicReference; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; import javax.annotation.Resource; +import org.jclouds.logging.Logger; + import com.google.common.collect.Lists; import com.google.common.util.concurrent.Atomics; - -import org.jclouds.logging.Logger; +import com.google.common.util.concurrent.ListeningExecutorService; /** * // TODO: Adrian: Document this! @@ -41,14 +41,14 @@ public abstract class BaseLifeCycle implements Runnable, LifeCycle { @Resource protected Logger logger = Logger.NULL; - protected final ExecutorService executorService; + protected final ListeningExecutorService userExecutor; protected final List dependencies; protected final Object statusLock; protected volatile Status status; protected AtomicReference exception = Atomics.newReference(); - public BaseLifeCycle(ExecutorService executor, LifeCycle... dependencies) { - this.executorService = executor; + public BaseLifeCycle(ListeningExecutorService userExecutor, LifeCycle... dependencies) { + this.userExecutor = userExecutor; this.dependencies = Lists.newArrayList(); this.dependencies.addAll(Arrays.asList(dependencies)); this.statusLock = new Object(); @@ -118,7 +118,7 @@ public abstract class BaseLifeCycle implements Runnable, LifeCycle { this.status = Status.ACTIVE; } - executorService.execute(this); + userExecutor.execute(this); } protected void exceptionIfDependenciesNotActive() { diff --git a/core/src/main/java/org/jclouds/lifecycle/config/LifeCycleModule.java b/core/src/main/java/org/jclouds/lifecycle/config/LifeCycleModule.java index 5f53f8031e..d5eff87de7 100644 --- a/core/src/main/java/org/jclouds/lifecycle/config/LifeCycleModule.java +++ b/core/src/main/java/org/jclouds/lifecycle/config/LifeCycleModule.java @@ -23,23 +23,25 @@ import static com.google.common.collect.Sets.newHashSet; import static com.google.common.util.concurrent.MoreExecutors.sameThreadExecutor; import static com.google.inject.matcher.Matchers.any; import static java.util.Arrays.asList; +import static org.jclouds.Constants.PROPERTY_IO_WORKER_THREADS; +import static org.jclouds.Constants.PROPERTY_SCHEDULER_THREADS; +import static org.jclouds.Constants.PROPERTY_USER_THREADS; import java.io.Closeable; import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Set; -import java.util.concurrent.ExecutorService; import java.util.concurrent.ScheduledExecutorService; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; import javax.inject.Named; -import org.jclouds.Constants; import org.jclouds.lifecycle.Closer; import com.google.common.util.concurrent.ExecutionList; +import com.google.common.util.concurrent.ListeningExecutorService; import com.google.inject.AbstractModule; import com.google.inject.Inject; import com.google.inject.Stage; @@ -70,14 +72,14 @@ public class LifeCycleModule extends AbstractModule { Closeable executorCloser = new Closeable() { @Inject - @Named(Constants.PROPERTY_USER_THREADS) - ExecutorService userExecutor; + @Named(PROPERTY_USER_THREADS) + ListeningExecutorService userExecutor; @Inject - @Named(Constants.PROPERTY_IO_WORKER_THREADS) - ExecutorService ioExecutor; + @Named(PROPERTY_IO_WORKER_THREADS) + ListeningExecutorService ioExecutor; // ScheduledExecutor is defined in an optional module @Inject(optional = true) - @Named(Constants.PROPERTY_SCHEDULER_THREADS) + @Named(PROPERTY_SCHEDULER_THREADS) ScheduledExecutorService scheduledExecutor; public void close() throws IOException { diff --git a/core/src/main/java/org/jclouds/rest/Utils.java b/core/src/main/java/org/jclouds/rest/Utils.java index 5f233df8af..c5bf450324 100644 --- a/core/src/main/java/org/jclouds/rest/Utils.java +++ b/core/src/main/java/org/jclouds/rest/Utils.java @@ -19,7 +19,6 @@ package org.jclouds.rest; import java.util.Map; -import java.util.concurrent.ExecutorService; import org.jclouds.crypto.Crypto; import org.jclouds.date.DateService; @@ -31,6 +30,7 @@ import org.jclouds.xml.XMLParser; import com.google.common.annotations.Beta; import com.google.common.eventbus.EventBus; +import com.google.common.util.concurrent.ListeningExecutorService; import com.google.inject.ImplementedBy; import com.google.inject.Injector; @@ -103,19 +103,19 @@ public interface Utils { */ DateService date(); - ExecutorService getUserExecutor(); + ListeningExecutorService getUserExecutor(); /** * #see #getUserExecutor */ - ExecutorService userExecutor(); + ListeningExecutorService userExecutor(); - ExecutorService getIoExecutor(); + ListeningExecutorService getIoExecutor(); /** * #see #getIoExecutor */ - ExecutorService ioExecutor(); + ListeningExecutorService ioExecutor(); @Beta EventBus getEventBus(); diff --git a/core/src/main/java/org/jclouds/rest/internal/InvokeHttpMethod.java b/core/src/main/java/org/jclouds/rest/internal/InvokeHttpMethod.java index 73f49e48fd..761b9f76dd 100644 --- a/core/src/main/java/org/jclouds/rest/internal/InvokeHttpMethod.java +++ b/core/src/main/java/org/jclouds/rest/internal/InvokeHttpMethod.java @@ -23,9 +23,6 @@ import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkState; import static com.google.common.util.concurrent.Futures.transform; import static com.google.common.util.concurrent.Futures.withFallback; -import static org.jclouds.concurrent.Futures.makeListenable; - -import java.util.concurrent.ExecutorService; import javax.annotation.Resource; import javax.inject.Inject; @@ -52,6 +49,7 @@ import com.google.common.reflect.Invokable; import com.google.common.reflect.TypeToken; import com.google.common.util.concurrent.FutureFallback; import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.ListeningExecutorService; import com.google.inject.Injector; import com.google.inject.TypeLiteral; @@ -66,7 +64,7 @@ public class InvokeHttpMethod implements Function { private final RestAnnotationProcessor annotationProcessor; private final HttpCommandExecutorService http; private final TransformerForRequest transformerForRequest; - private final ExecutorService userThreads; + private final ListeningExecutorService userExecutor; private final BlockOnFuture.Factory blocker; @SuppressWarnings("unchecked") @@ -74,13 +72,13 @@ public class InvokeHttpMethod implements Function { private InvokeHttpMethod(Injector injector, TypeLiteral enclosingType, Cache, Invokable> sync2AsyncInvokables, RestAnnotationProcessor annotationProcessor, HttpCommandExecutorService http, TransformerForRequest transformerForRequest, - @Named(Constants.PROPERTY_USER_THREADS) ExecutorService userThreads, BlockOnFuture.Factory blocker) { + @Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor, BlockOnFuture.Factory blocker) { this.injector = injector; this.enclosingType = (TypeToken) TypeToken.of(enclosingType.getType()); this.sync2AsyncInvokables = sync2AsyncInvokables; this.annotationProcessor = annotationProcessor; this.http = http; - this.userThreads = userThreads; + this.userExecutor = userExecutor; this.blocker = blocker; this.transformerForRequest = transformerForRequest; } @@ -125,8 +123,7 @@ public class InvokeHttpMethod implements Function { logger.trace("<< response from %s is parsed by %s", name, transformer.getClass().getSimpleName()); logger.debug(">> invoking %s", name); - ListenableFuture result = transform(makeListenable(http.submit(new HttpCommand(request)), userThreads), - transformer); + ListenableFuture result = transform(http.submit(new HttpCommand(request)), transformer, userExecutor); FutureFallback fallback = fallbacks.getUnchecked(invocation.getInvokable()); if (fallback instanceof InvocationContext) { diff --git a/core/src/main/java/org/jclouds/rest/internal/UtilsImpl.java b/core/src/main/java/org/jclouds/rest/internal/UtilsImpl.java index d4af5d7fe4..8ac824667a 100644 --- a/core/src/main/java/org/jclouds/rest/internal/UtilsImpl.java +++ b/core/src/main/java/org/jclouds/rest/internal/UtilsImpl.java @@ -19,7 +19,6 @@ package org.jclouds.rest.internal; import java.util.Map; -import java.util.concurrent.ExecutorService; import javax.inject.Inject; import javax.inject.Named; @@ -37,6 +36,7 @@ import org.jclouds.xml.XMLParser; import com.google.common.annotations.Beta; import com.google.common.eventbus.EventBus; +import com.google.common.util.concurrent.ListeningExecutorService; import com.google.inject.Injector; import com.google.inject.Singleton; @@ -51,8 +51,8 @@ public class UtilsImpl implements Utils { private final HttpAsyncClient simpleAsyncClient; private final Crypto encryption; private final DateService date; - private final ExecutorService userExecutor; - private final ExecutorService ioExecutor; + private final ListeningExecutorService userExecutor; + private final ListeningExecutorService ioExecutor; private final EventBus eventBus; private final Map credentialStore; private final LoggerFactory loggerFactory; @@ -61,8 +61,8 @@ public class UtilsImpl implements Utils { @Inject protected 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) { this.injector = injector; this.json = json; @@ -70,8 +70,8 @@ public class UtilsImpl implements Utils { this.simpleAsyncClient = simpleAsyncClient; this.encryption = encryption; this.date = date; - this.userExecutor = userThreads; - this.ioExecutor = ioThreads; + this.userExecutor = userExecutor; + this.ioExecutor = ioExecutor; this.eventBus = eventBus; this.credentialStore = credentialStore; this.loggerFactory = loggerFactory; @@ -119,22 +119,22 @@ public class UtilsImpl implements Utils { } @Override - public ExecutorService getIoExecutor() { + public ListeningExecutorService getIoExecutor() { return ioExecutor; } @Override - public ExecutorService getUserExecutor() { + public ListeningExecutorService getUserExecutor() { return userExecutor; } @Override - public ExecutorService ioExecutor() { + public ListeningExecutorService ioExecutor() { return ioExecutor; } @Override - public ExecutorService userExecutor() { + public ListeningExecutorService userExecutor() { return userExecutor; } diff --git a/core/src/test/java/com/google/common/util/concurrent/FuturesTransformPerformanceTest.java b/core/src/test/java/com/google/common/util/concurrent/FuturesTransformPerformanceTest.java deleted file mode 100644 index 3165f3bd72..0000000000 --- a/core/src/test/java/com/google/common/util/concurrent/FuturesTransformPerformanceTest.java +++ /dev/null @@ -1,257 +0,0 @@ -/** - * Licensed to jclouds, Inc. (jclouds) under one or more - * contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. jclouds licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package com.google.common.util.concurrent; - -import static com.google.common.base.Throwables.propagate; -import static com.google.common.collect.Maps.newHashMap; -import static java.util.concurrent.Executors.newCachedThreadPool; - -import java.util.Collections; -import java.util.Map; -import java.util.concurrent.Callable; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Future; - -import org.testng.annotations.Test; - -import com.google.common.base.Function; -import com.google.common.collect.Iterables; -import com.google.common.collect.Sets; - -/** - * In google appengine, we can get a future without using an executorservice, using its async http - * fetch command. However, we still may need to do some conversions, or add listeners. In - * googleappengine, we cannot employ a *real* executorservice, but we can employ a same thread - * executor. This test identifies efficiencies that can be made by strengthening guava's handling of - * same thread execution. - * - *

- * - * We simulate an i/o future by running a callable that simply sleeps. How this is created isn't - * important. - * - *

    - *
  1. {@code IO_DURATION} is the time that the source future spends doing work
  2. - *
  3. {@code LISTENER_DURATION} is the time that the attached listener or function
  4. - *
- * - * The execution time of a transformd task within a composite should not be more than {@code - * IO_DURATION} + {@code LISTENER_DURATION} + overhead when a threadpool is used. This is because - * the listener should be invoked as soon as the result is available. - *

- * The execution time of a transformd task within a composite should not be more than {@code - * IO_DURATION} + {@code LISTENER_DURATION} * {@code COUNT} + overhead when caller thread is used - * for handling the listeners. - *

- * This test shows that Futures.transform eagerly issues a get() on the source future. code iterating - * over futures and assigning listeners will take the same amount of time as calling get() on each - * one, if using a within thread executor. This exposes an inefficiency which can make some use - * cases in google appengine impossible to achieve within the cutoff limits. - * - * @author Adrian Cole - */ -@Test(groups = "performance", enabled = false, singleThreaded = true, testName = "FuturesTransformPerformanceTest") -public class FuturesTransformPerformanceTest { - private static final int FUDGE = 5; - private static final int COUNT = 100; - private static final int IO_DURATION = 50; - private static final int LISTENER_DURATION = 100; - - ExecutorService ioFunctionExecutor = newCachedThreadPool(); - - /** - * When we use threadpools for both the chain and invoking listener, user experience is - * consistent. - */ - @Test(enabled = false) - public void whenCachedThreadPoolIsUsedForChainAndListenerMaxDurationIsSumOfCallableAndListener() - throws InterruptedException, ExecutionException { - long expectedMax = IO_DURATION + LISTENER_DURATION; - long expectedMin = IO_DURATION + LISTENER_DURATION; - long expectedOverhead = COUNT * 4 + FUDGE; - - ExecutorService userthreads = newCachedThreadPool(); - try { - ExecutorService chainExecutor = userthreads; - ExecutorService listenerExecutor = userthreads; - - checkThresholdsUsingFuturesTransform(expectedMin, expectedMax, expectedOverhead, chainExecutor, listenerExecutor); - } finally { - userthreads.shutdownNow(); - } - } - - /** - * When we use threadpools for the chain, but same thread for invoking listener, user experience - * is still consistent. - */ - @Test(enabled = false) - public void whenCachedThreadPoolIsUsedForChainButSameThreadForListenerMaxDurationIsSumOfCallableAndListener() - throws InterruptedException, ExecutionException { - long expectedMax = IO_DURATION + LISTENER_DURATION; - long expectedMin = IO_DURATION + LISTENER_DURATION; - long expectedOverhead = COUNT + FUDGE; - - ExecutorService userthreads = newCachedThreadPool(); - try { - ExecutorService chainExecutor = userthreads; - ExecutorService listenerExecutor = MoreExecutors.sameThreadExecutor(); - - checkThresholdsUsingFuturesTransform(expectedMin, expectedMax, expectedOverhead, chainExecutor, listenerExecutor); - } finally { - userthreads.shutdownNow(); - } - } - - /** - * When using same thread for the chain, the futures are being called (get()) eagerly, resulting - * in the max duration being the sum of all i/o plus the cost of executing the listeners. In this - * case, listeners are executed in a different thread pool. - * - */ - @Test(enabled = false) - public void whenSameThreadIsUsedForChainButCachedThreadPoolForListenerMaxDurationIsSumOfAllIOAndOneListener() - throws InterruptedException, ExecutionException { - long expectedMax = (IO_DURATION * COUNT) + LISTENER_DURATION; - long expectedMin = IO_DURATION + LISTENER_DURATION; - long expectedOverhead = COUNT + FUDGE; - - ExecutorService userthreads = newCachedThreadPool(); - try { - ExecutorService chainExecutor = MoreExecutors.sameThreadExecutor(); - ExecutorService listenerExecutor = userthreads; - - checkThresholdsUsingFuturesTransform(expectedMin, expectedMax, expectedOverhead, chainExecutor, listenerExecutor); - } finally { - userthreads.shutdownNow(); - } - } - - /** - * This case can be optimized for sure. The side effect of the eager get() is that all i/o must - * complete before *any* listeners are run. In this case, if you are inside google appengine and - * using same thread executors, worst experience is sum of all io duration plus the sum of all - * listener duration. An efficient implementation would call get() on the i/o future lazily. Such - * an impl would have a max duration of I/O + Listener * count. - */ - @Test(enabled = false) - public void whenSameThreadIsUsedForChainAndListenerMaxDurationIsSumOfAllIOAndAllListeners() - throws InterruptedException, ExecutionException { - - long expectedMax = (IO_DURATION * COUNT) + (LISTENER_DURATION * COUNT); - long expectedMin = IO_DURATION + LISTENER_DURATION; - long expectedOverhead = COUNT + FUDGE; - - ExecutorService userthreads = newCachedThreadPool(); - try { - ExecutorService chainExecutor = MoreExecutors.sameThreadExecutor(); - ExecutorService listenerExecutor = MoreExecutors.sameThreadExecutor(); - - checkThresholdsUsingFuturesTransform(expectedMin, expectedMax, expectedOverhead, chainExecutor, listenerExecutor); - } finally { - userthreads.shutdownNow(); - } - } - - private void checkThresholdsUsingFuturesTransform(long expectedMin, long expectedMax, long expectedOverhead, - ExecutorService chainExecutor, final ExecutorService listenerExecutor) { - long start = System.currentTimeMillis(); - Map> responses = newHashMap(); - for (int i = 0; i < COUNT; i++) - responses.put(i + "", Futures.transform(JdkFutureAdapters.listenInPoolThread(simultateIO(), chainExecutor), - new Function() { - - @Override - public Long apply(Long from) { - try { - Thread.sleep(LISTENER_DURATION); - } catch (InterruptedException e) { - propagate(e); - } - return System.currentTimeMillis(); - } - - }, listenerExecutor)); - checkTimeThresholds(expectedMin, expectedMax, expectedOverhead, start, responses); - } - - private Future simultateIO() { - return ioFunctionExecutor.submit(new Callable() { - - @Override - public Long call() throws Exception { - Thread.sleep(IO_DURATION); - return System.currentTimeMillis(); - } - - }); - } - - private static long getMaxIn(Map> responses) { - Iterable collection = Iterables.transform(responses.values(), new Function, Long>() { - - @Override - public Long apply(Future from) { - try { - return from.get(); - } catch (InterruptedException e) { - } catch (ExecutionException e) { - } - return null; - } - - }); - long time = Collections.max(Sets.newHashSet(collection)); - return time; - } - - private static long getMinIn(Map> responses) { - Iterable collection = Iterables.transform(responses.values(), new Function, Long>() { - - @Override - public Long apply(Future from) { - try { - return from.get(); - } catch (InterruptedException e) { - } catch (ExecutionException e) { - } - return null; - } - - }); - long time = Collections.min(Sets.newHashSet(collection)); - return time; - } - - private static void checkTimeThresholds(long expectedMin, long expectedMax, long expectedOverhead, long start, - Map> responses) { - long time = getMaxIn(responses) - start; - assert time >= expectedMax && time < expectedMax + expectedOverhead : String.format("expectedMax %d, max %d", - expectedMax, time); - - time = getMinIn(responses) - start; - assert time >= expectedMin && time < expectedMin + expectedOverhead : String.format("expectedMin %d, min %d", - expectedMin, time); - - time = getMaxIn(responses) - start; - assert time >= expectedMax && time < expectedMax + expectedOverhead : String.format("expectedMax %d, max %d", - expectedMax, time); - } -} diff --git a/core/src/test/java/org/jclouds/concurrent/FutureIterablesTest.java b/core/src/test/java/org/jclouds/concurrent/FutureIterablesTest.java index 5e6138963e..0be1eb74eb 100644 --- a/core/src/test/java/org/jclouds/concurrent/FutureIterablesTest.java +++ b/core/src/test/java/org/jclouds/concurrent/FutureIterablesTest.java @@ -26,9 +26,7 @@ import static org.testng.Assert.assertEquals; import static org.testng.Assert.fail; import java.util.Map; -import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; -import java.util.concurrent.Future; import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicInteger; @@ -38,6 +36,9 @@ import org.testng.annotations.Test; import com.google.common.base.Function; import com.google.common.collect.ImmutableSet; +import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.ListeningExecutorService; +import com.google.common.util.concurrent.MoreExecutors; /** * Tests behavior of FutureIterables @@ -51,15 +52,12 @@ public class FutureIterablesTest { final AtomicInteger counter = new AtomicInteger(); try { - transformParallel(ImmutableSet.of("hello", "goodbye"), new Function>() { - - @Override - public Future apply(String input) { + transformParallel(ImmutableSet.of("hello", "goodbye"), new Function>() { + public ListenableFuture apply(String input) { counter.incrementAndGet(); return immediateFailedFuture(new AuthorizationException()); } - - }, sameThreadExecutor(), null, Logger.CONSOLE, ""); + }, sameThreadExecutor(), null, Logger.NULL, ""); fail("Expected AuthorizationException"); } catch (AuthorizationException e) { assertEquals(counter.get(), 2); @@ -71,14 +69,11 @@ public class FutureIterablesTest { final AtomicInteger counter = new AtomicInteger(); try { - transformParallel(ImmutableSet.of("hello", "goodbye"), new Function>() { - - @Override - public Future apply(String input) { + transformParallel(ImmutableSet.of("hello", "goodbye"), new Function>() { + public ListenableFuture apply(String input) { counter.incrementAndGet(); return immediateFailedFuture(new RuntimeException()); } - }, sameThreadExecutor(), null, Logger.CONSOLE, ""); fail("Expected TransformParallelException"); } catch (TransformParallelException e) { @@ -90,10 +85,10 @@ public class FutureIterablesTest { public void testAwaitCompletionTimeout() throws Exception { final long timeoutMs = 1000; - ExecutorService executorService = Executors.newSingleThreadExecutor(); - Map> responses = newHashMap(); + ListeningExecutorService userExecutor = MoreExecutors.listeningDecorator(Executors.newSingleThreadExecutor()); + Map> responses = newHashMap(); try { - responses.put(null, executorService.submit(new Runnable() { + responses.put(null, userExecutor.submit(new Runnable() { @Override public void run() { try { @@ -103,9 +98,8 @@ public class FutureIterablesTest { } } })); - Map errors = FutureIterables.awaitCompletion(responses, executorService, timeoutMs, - Logger.CONSOLE, - /* prefix= */""); + Map errors = FutureIterables.awaitCompletion(responses, userExecutor, timeoutMs, Logger.NULL, + /* prefix= */""); if (!errors.isEmpty()) { throw errors.values().iterator().next(); } @@ -113,7 +107,7 @@ public class FutureIterablesTest { } catch (TimeoutException te) { // expected } finally { - executorService.shutdownNow(); + userExecutor.shutdownNow(); } } } diff --git a/core/src/test/java/org/jclouds/concurrent/FuturesTest.java b/core/src/test/java/org/jclouds/concurrent/FuturesTest.java deleted file mode 100644 index a0ffaa5d57..0000000000 --- a/core/src/test/java/org/jclouds/concurrent/FuturesTest.java +++ /dev/null @@ -1,94 +0,0 @@ -/** - * Licensed to jclouds, Inc. (jclouds) under one or more - * contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. jclouds licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.jclouds.concurrent; - -import static com.google.common.util.concurrent.MoreExecutors.sameThreadExecutor; -import static org.easymock.EasyMock.createMock; -import static org.easymock.EasyMock.expect; -import static org.easymock.EasyMock.replay; -import static org.easymock.EasyMock.verify; -import static org.testng.Assert.assertEquals; -import static org.testng.Assert.fail; - -import java.util.concurrent.ExecutionException; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Future; - -import org.jclouds.concurrent.Futures.CallGetAndRunExecutionList; -import org.testng.annotations.Test; - -import com.google.common.util.concurrent.ExecutionList; - -/** - * Tests behavior of Futures - * - * @author Adrian Cole - */ -@Test(groups = "unit") -public class FuturesTest { - ExecutorService executorService = sameThreadExecutor(); - - @Test - public void testCallGetAndRunRunnableRunsListOnRuntimeException() throws InterruptedException, ExecutionException { - - Runnable runnable = createMock(Runnable.class); - @SuppressWarnings("unchecked") - Future future = createMock(Future.class); - runnable.run(); - expect(future.get()).andThrow(new RuntimeException()); - replay(runnable); - replay(future); - - ExecutionList executionList = new ExecutionList(); - executionList.add(runnable, executorService); - - CallGetAndRunExecutionList caller = new CallGetAndRunExecutionList(future, executionList); - caller.run(); - - verify(runnable); - verify(future); - } - - @Test - public void testCallGetAndRunRunnableInterruptsAndThrowsIllegalStateExceptionOnInterruptedException() - throws InterruptedException, ExecutionException { - - Runnable runnable = createMock(Runnable.class); - @SuppressWarnings("unchecked") - Future future = createMock(Future.class); - expect(future.get()).andThrow(new InterruptedException()); - replay(runnable); - replay(future); - - ExecutionList executionList = new ExecutionList(); - executionList.add(runnable, executorService); - - CallGetAndRunExecutionList caller = new CallGetAndRunExecutionList(future, executionList); - try { - caller.run(); - fail("Expected IllegalStateException"); - } catch (IllegalStateException e) { - assertEquals(e.getMessage(), "interrupted calling get() on [EasyMock for interface java.util.concurrent.Future], so could not run listeners"); - } - - verify(runnable); - verify(future); - } - -} diff --git a/core/src/test/java/org/jclouds/concurrent/config/ExecutorServiceModuleTest.java b/core/src/test/java/org/jclouds/concurrent/config/ExecutorServiceModuleTest.java index 1be5d2ae51..2b63d705ba 100644 --- a/core/src/test/java/org/jclouds/concurrent/config/ExecutorServiceModuleTest.java +++ b/core/src/test/java/org/jclouds/concurrent/config/ExecutorServiceModuleTest.java @@ -18,29 +18,31 @@ */ package org.jclouds.concurrent.config; +import static com.google.common.base.Throwables.getStackTraceAsString; +import static com.google.inject.name.Names.named; import static org.easymock.EasyMock.createMock; import static org.easymock.EasyMock.expect; import static org.easymock.EasyMock.replay; import static org.easymock.EasyMock.verify; -import static org.testng.Assert.assertEquals; -import static org.testng.Assert.fail; +import static org.jclouds.Constants.PROPERTY_IO_WORKER_THREADS; +import static org.jclouds.Constants.PROPERTY_USER_THREADS; +import static org.testng.Assert.assertFalse; +import static org.testng.Assert.assertNull; +import static org.testng.Assert.assertTrue; import java.io.IOException; -import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Future; -import org.jclouds.Constants; import org.jclouds.lifecycle.Closer; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; -import com.google.common.base.Throwables; import com.google.common.collect.ImmutableList; +import com.google.common.util.concurrent.ListeningExecutorService; import com.google.inject.Guice; import com.google.inject.Injector; import com.google.inject.Key; -import com.google.inject.name.Names; /** * @@ -49,12 +51,35 @@ import com.google.inject.name.Names; @Test public class ExecutorServiceModuleTest { + private Injector injector; + + @BeforeMethod + private void setupExecutorModule() { + ExecutorServiceModule module = new ExecutorServiceModule() { + @Override + protected void configure() { + bindConstant().annotatedWith(named(PROPERTY_IO_WORKER_THREADS)).to(1); + bindConstant().annotatedWith(named(PROPERTY_USER_THREADS)).to(1); + super.configure(); + } + }; + + injector = Guice.createInjector(module); + assertNull(module.userExecutorFromConstructor); + assertNull(module.ioExecutorFromConstructor); + } + + @AfterMethod + private void close() throws IOException { + injector.getInstance(Closer.class).close(); + } + @Test public void testShutdownOnClose() throws IOException { Injector i = Guice.createInjector(); Closer closer = i.getInstance(Closer.class); - ExecutorService executor = createMock(ExecutorService.class); + ListeningExecutorService executor = createMock(ListeningExecutorService.class); ExecutorServiceModule.shutdownOnClose(executor, closer); expect(executor.shutdownNow()).andReturn(ImmutableList. of()).atLeastOnce(); @@ -68,192 +93,64 @@ public class ExecutorServiceModuleTest { @Test public void testShutdownOnCloseThroughModule() throws IOException { - ExecutorServiceModule module = new ExecutorServiceModule() { - @Override - protected void configure() { - bindConstant().annotatedWith(Names.named(Constants.PROPERTY_IO_WORKER_THREADS)).to(1); - bindConstant().annotatedWith(Names.named(Constants.PROPERTY_USER_THREADS)).to(1); - super.configure(); - } - }; - - Injector i = Guice.createInjector(module); - assertEquals(module.userExecutorFromConstructor, null); - assertEquals(module.ioExecutorFromConstructor, null); + ListeningExecutorService user = injector.getInstance(Key.get(ListeningExecutorService.class, + named(PROPERTY_USER_THREADS))); + ListeningExecutorService io = injector.getInstance(Key.get(ListeningExecutorService.class, + named(PROPERTY_IO_WORKER_THREADS))); - Closer closer = i.getInstance(Closer.class); + assertFalse(user.isShutdown()); + assertFalse(io.isShutdown()); - ExecutorService user = i - .getInstance(Key.get(ExecutorService.class, Names.named(Constants.PROPERTY_USER_THREADS))); - ExecutorService io = i.getInstance(Key.get(ExecutorService.class, Names - .named(Constants.PROPERTY_IO_WORKER_THREADS))); - - assert !user.isShutdown(); - assert !io.isShutdown(); - - closer.close(); - - assert user.isShutdown(); - assert io.isShutdown(); + injector.getInstance(Closer.class).close(); + assertTrue(user.isShutdown()); + assertTrue(io.isShutdown()); } - + @Test - public void testDescribedFutureToString() throws Exception { - - ExecutorServiceModule module = new ExecutorServiceModule() { + public void testExceptionInSubmitRunnableIncludesSubmissionTrace() throws Exception { + ListeningExecutorService user = injector.getInstance(Key.get(ListeningExecutorService.class, + named(PROPERTY_USER_THREADS))); + ListeningExecutorService io = injector.getInstance(Key.get(ListeningExecutorService.class, + named(PROPERTY_IO_WORKER_THREADS))); + + for (ListeningExecutorService exec : ImmutableList.of(user, io)) { + String submission = null; + try { + // this is sensitive to formatting as we are looking for the stack traces to match. if you wrap the below + // line again, you'll need to change incrementInitialElement to 3 line numbers instead of 2. + submission = getStackTraceAsString(incrementInitialElement(new RuntimeException(), 2)).replaceFirst(".*\n", + ""); + exec.submit(runnableThrowsRTE()).get(); + } catch (ExecutionException e) { + assertTraceHasSubmission(getStackTraceAsString(e), submission); + assertTraceHasSubmission(getStackTraceAsString(e.getCause()), submission); + } + } + } + + static void assertTraceHasSubmission(String trace, String expected) { + assertTrue(trace.indexOf(WithSubmissionTrace.class.getName()) == -1, trace); + assertTrue(trace.indexOf(expected) != -1, trace + " " + expected); + } + + static E incrementInitialElement(E ex, int lines) { + StackTraceElement[] trace = ex.getStackTrace(); + StackTraceElement initialElement = trace[0]; + trace[0] = new StackTraceElement(initialElement.getClassName(), initialElement.getMethodName(), + initialElement.getFileName(), initialElement.getLineNumber() + lines); + ex.setStackTrace(trace); + return ex; + } + + static Runnable runnableThrowsRTE() { + return new Runnable() { + @Override - protected void configure() { - bindConstant().annotatedWith(Names.named(Constants.PROPERTY_IO_WORKER_THREADS)).to(1); - bindConstant().annotatedWith(Names.named(Constants.PROPERTY_USER_THREADS)).to(1); - super.configure(); + public void run() { + throw new RuntimeException(); } + }; - - Injector i = Guice.createInjector(module); - Closer closer = i.getInstance(Closer.class); - - ExecutorService user = i - .getInstance(Key.get(ExecutorService.class, Names.named(Constants.PROPERTY_USER_THREADS))); - ExecutorService io = i.getInstance(Key.get(ExecutorService.class, Names - .named(Constants.PROPERTY_IO_WORKER_THREADS))); - - ConfigurableRunner t1 = new ConfigurableRunner(); - t1.result = "okay"; - - Future euc = performSubmissionInSeparateMethod1(user, t1); - assert euc.toString().indexOf("ConfigurableRunner") >= 0; - assert euc.get().equals("okay"); - - Future eic = performSubmissionInSeparateMethod1(io, t1); - assert eic.toString().indexOf("ConfigurableRunner") >= 0; - assert eic.get().equals("okay"); - - - closer.close(); - } - - /* - * The decoration makes sure that the stack trace looks like the following. - * Note the last three included trace elements: this details where the task was submitted _from_ - * (technically it is a different stack frame, since it is across threads; but logically it is the same) - * -java.util.concurrent.ExecutionException: java.lang.IllegalStateException: foo - at java.util.concurrent.FutureTask$Sync.innerGet(FutureTask.java:222) - at java.util.concurrent.FutureTask.get(FutureTask.java:83) - at org.jclouds.concurrent.config.ExecutorServiceModule$DescribedFuture.get(ExecutorServiceModule.java:232) - at org.jclouds.concurrent.config.ExecutorServiceModuleTest.checkFutureGetFailsWith(ExecutorServiceModuleTest.java:186) - at org.jclouds.concurrent.config.ExecutorServiceModuleTest.testDescribedFutureExceptionIncludesSubmissionTrace(ExecutorServiceModuleTest.java:171) - at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) - at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) - at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) - at java.lang.reflect.Method.invoke(Method.java:597) - at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:80) - at org.testng.internal.Invoker.invokeMethod(Invoker.java:691) - at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:883) - at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1208) - at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:127) - at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:111) - at org.testng.TestRunner.privateRun(TestRunner.java:753) - at org.testng.TestRunner.run(TestRunner.java:613) - at org.testng.SuiteRunner.runTest(SuiteRunner.java:335) - at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:330) - at org.testng.SuiteRunner.privateRun(SuiteRunner.java:292) - at org.testng.SuiteRunner.run(SuiteRunner.java:241) - at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52) - at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86) - at org.testng.TestNG.runSuitesSequentially(TestNG.java:1169) - at org.testng.TestNG.runSuitesLocally(TestNG.java:1094) - at org.testng.TestNG.run(TestNG.java:1006) - at org.testng.remote.RemoteTestNG.run(RemoteTestNG.java:107) - at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:199) - at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:170) -Caused by: java.lang.IllegalStateException: foo - at org.jclouds.concurrent.config.ExecutorServiceModuleTest$ConfigurableRunner.call(ExecutorServiceModuleTest.java:206) - at org.jclouds.concurrent.config.ExecutorServiceModuleTest$ConfigurableRunner.run(ExecutorServiceModuleTest.java:203) - at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441) - at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303) - at java.util.concurrent.FutureTask.run(FutureTask.java:138) - at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) - at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) - at java.lang.Thread.run(Thread.java:637) - at org.jclouds.concurrent.config.ExecutorServiceModule$DescribingExecutorService.submit(ExecutorServiceModule.java:188) - at org.jclouds.concurrent.config.ExecutorServiceModuleTest.performSubmissionInSeparateMethod2(ExecutorServiceModuleTest.java:181) - at org.jclouds.concurrent.config.ExecutorServiceModuleTest.testDescribedFutureExceptionIncludesSubmissionTrace(ExecutorServiceModuleTest.java:170) - ... 24 more - - * - */ - @Test - public void testDescribedFutureExceptionIncludesSubmissionTrace() throws Exception { - - ExecutorServiceModule module = new ExecutorServiceModule() { - @Override - protected void configure() { - bindConstant().annotatedWith(Names.named(Constants.PROPERTY_IO_WORKER_THREADS)).to(1); - bindConstant().annotatedWith(Names.named(Constants.PROPERTY_USER_THREADS)).to(1); - super.configure(); - } - }; - - Injector i = Guice.createInjector(module); - Closer closer = i.getInstance(Closer.class); - - ExecutorService user = i - .getInstance(Key.get(ExecutorService.class, Names.named(Constants.PROPERTY_USER_THREADS))); - ExecutorService io = i.getInstance(Key.get(ExecutorService.class, Names - .named(Constants.PROPERTY_IO_WORKER_THREADS))); - - ConfigurableRunner t1 = new ConfigurableRunner(); - t1.failMessage = "foo"; - t1.result = "shouldn't happen"; - - Future euc = performSubmissionInSeparateMethod1(user, t1); - checkFutureGetFailsWith(euc, "foo", "testDescribedFutureExceptionIncludesSubmissionTrace", "performSubmissionInSeparateMethod1"); - - Future eur = performSubmissionInSeparateMethod2(user, t1); - checkFutureGetFailsWith(eur, "foo", "testDescribedFutureExceptionIncludesSubmissionTrace", "performSubmissionInSeparateMethod2"); - - Future eic = performSubmissionInSeparateMethod1(io, t1); - checkFutureGetFailsWith(eic, "foo", "testDescribedFutureExceptionIncludesSubmissionTrace", "performSubmissionInSeparateMethod1"); - - Future eir = performSubmissionInSeparateMethod2(io, t1); - checkFutureGetFailsWith(eir, "foo", "testDescribedFutureExceptionIncludesSubmissionTrace", "performSubmissionInSeparateMethod2"); - - closer.close(); - } - - static Future performSubmissionInSeparateMethod1(ExecutorService user, ConfigurableRunner t1) { - return user.submit((Callable)t1); - } - - static Future performSubmissionInSeparateMethod2(ExecutorService io, ConfigurableRunner t1) { - return io.submit((Runnable)t1, (Object)"shouldn't happen"); - } - - static void checkFutureGetFailsWith(Future task, String ...requiredPhrases) throws Exception { - try { - task.get(); - fail("task should have failed"); - } catch (ExecutionException e) { - String trace = Throwables.getStackTraceAsString(e); - for (String requiredPhrase : requiredPhrases) { - assert trace.indexOf(requiredPhrase) >= 0 : "stack trace should have contained '"+requiredPhrase+"'"; - } - } - } - - static class ConfigurableRunner implements Runnable, Callable { - Object result; - String failMessage; - - @Override - public void run() { - call(); - } - public Object call() { - if (failMessage!=null) throw new IllegalStateException(failMessage); - return result; - } } } diff --git a/core/src/test/java/org/jclouds/concurrent/config/ScheduledExecutorServiceModuleTest.java b/core/src/test/java/org/jclouds/concurrent/config/ScheduledExecutorServiceModuleTest.java index 990798dbcb..c1c7f4b107 100644 --- a/core/src/test/java/org/jclouds/concurrent/config/ScheduledExecutorServiceModuleTest.java +++ b/core/src/test/java/org/jclouds/concurrent/config/ScheduledExecutorServiceModuleTest.java @@ -17,46 +17,66 @@ * under the License. */ package org.jclouds.concurrent.config; - +import static com.google.common.base.Throwables.getStackTraceAsString; +import static com.google.inject.name.Names.named; +import static org.easymock.EasyMock.createMock; import static org.easymock.EasyMock.expect; import static org.easymock.EasyMock.replay; import static org.easymock.EasyMock.verify; -import static org.jclouds.concurrent.config.ExecutorServiceModuleTest.checkFutureGetFailsWith; +import static org.jclouds.Constants.PROPERTY_SCHEDULER_THREADS; +import static org.jclouds.concurrent.config.ExecutorServiceModuleTest.assertTraceHasSubmission; +import static org.jclouds.concurrent.config.ExecutorServiceModuleTest.incrementInitialElement; +import static org.testng.Assert.assertFalse; +import static org.testng.Assert.assertTrue; import java.io.IOException; -import java.util.concurrent.Callable; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; -import org.easymock.EasyMock; -import org.jclouds.Constants; -import org.jclouds.concurrent.config.ExecutorServiceModuleTest.ConfigurableRunner; import org.jclouds.lifecycle.Closer; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; import com.google.common.collect.ImmutableList; +import com.google.common.util.concurrent.ListeningScheduledExecutorService; import com.google.inject.Guice; import com.google.inject.Injector; import com.google.inject.Key; -import com.google.inject.name.Names; /** - * Unit tests for the {@link ScheduledExecutorServiceModule} class. * - * @author Ignasi Barrera - * - * @see ExecutorServiceModuleTest + * @author Adrian Cole */ -@Test(groups = "unit") +@Test public class ScheduledExecutorServiceModuleTest { - @Test(groups = "unit") + private Injector injector; + + @BeforeMethod + private void setupExecutorModule() { + ScheduledExecutorServiceModule module = new ScheduledExecutorServiceModule() { + @Override + protected void configure() { + bindConstant().annotatedWith(named(PROPERTY_SCHEDULER_THREADS)).to(1); + super.configure(); + } + }; + + injector = Guice.createInjector(module); + } + + @AfterMethod + private void close() throws IOException { + injector.getInstance(Closer.class).close(); + } + + @Test public void testShutdownOnClose() throws IOException { Injector i = Guice.createInjector(); Closer closer = i.getInstance(Closer.class); - ScheduledExecutorService executor = EasyMock.createMock(ScheduledExecutorService.class); + ListeningScheduledExecutorService executor = createMock(ListeningScheduledExecutorService.class); ExecutorServiceModule.shutdownOnClose(executor, closer); expect(executor.shutdownNow()).andReturn(ImmutableList. of()).atLeastOnce(); @@ -67,106 +87,61 @@ public class ScheduledExecutorServiceModuleTest { verify(executor); } - @Test(groups = "unit") + @Test public void testShutdownOnCloseThroughModule() throws IOException { - ScheduledExecutorServiceModule module = new ScheduledExecutorServiceModule() { + ListeningScheduledExecutorService sched = injector.getInstance(Key.get(ListeningScheduledExecutorService.class, + named(PROPERTY_SCHEDULER_THREADS))); + + assertFalse(sched.isShutdown()); + + injector.getInstance(Closer.class).close(); + + assertTrue(sched.isShutdown()); + } + + @Test + public void testExceptionInSubmitRunnableIncludesSubmissionTrace() throws Exception { + ListeningScheduledExecutorService sched = injector.getInstance(Key.get(ListeningScheduledExecutorService.class, + named(PROPERTY_SCHEDULER_THREADS))); + String submission = null; + try { + // this is sensitive to formatting as we are looking for the stack traces to match. if you wrap the below + // line again, you'll need to change incrementInitialElement to 3 line numbers instead of 2. + submission = getStackTraceAsString(incrementInitialElement(new RuntimeException(), 2)) + .replaceFirst(".*\n", ""); + sched.submit(runnableThrowsRTE()).get(); + } catch (ExecutionException e) { + assertTraceHasSubmission(getStackTraceAsString(e), submission); + assertTraceHasSubmission(getStackTraceAsString(e.getCause()), submission); + } + } + + @Test + public void testExceptionInScheduleWithFixedDelayRunnableIncludesSubmissionTrace() throws Exception { + ListeningScheduledExecutorService sched = injector.getInstance(Key.get(ListeningScheduledExecutorService.class, + named(PROPERTY_SCHEDULER_THREADS))); + String submission = null; + try { + // this is sensitive to formatting as we are looking for the stack traces to match. if you wrap the below + // line again, you'll need to change incrementInitialElement to 3 line numbers instead of 2. + submission = getStackTraceAsString(incrementInitialElement(new RuntimeException(), 2)) + .replaceFirst(".*\n", ""); + sched.scheduleWithFixedDelay(runnableThrowsRTE(), 0, 1, TimeUnit.MICROSECONDS).get(); + } catch (ExecutionException e) { + assertTraceHasSubmission(getStackTraceAsString(e), submission); + assertTraceHasSubmission(getStackTraceAsString(e.getCause()), submission); + } + } + + static Runnable runnableThrowsRTE() { + return new Runnable() { + @Override - protected void configure() { - bindConstant().annotatedWith(Names.named(Constants.PROPERTY_SCHEDULER_THREADS)).to(1); - super.configure(); + public void run() { + throw new RuntimeException(); } + }; - - Injector i = Guice.createInjector(module); - Closer closer = i.getInstance(Closer.class); - - ScheduledExecutorService sched = i.getInstance(Key.get(ScheduledExecutorService.class, Names - .named(Constants.PROPERTY_SCHEDULER_THREADS))); - - assert !sched.isShutdown(); - - closer.close(); - - assert sched.isShutdown(); - } - - @Test(groups = "unit") - public void testDescribedFutureToString() throws Exception { - - ScheduledExecutorServiceModule module = new ScheduledExecutorServiceModule() { - @Override - protected void configure() { - bindConstant().annotatedWith(Names.named(Constants.PROPERTY_SCHEDULER_THREADS)).to(1); - super.configure(); - } - }; - - Injector i = Guice.createInjector(module); - Closer closer = i.getInstance(Closer.class); - - ScheduledExecutorService sched = i.getInstance(Key.get(ScheduledExecutorService.class, Names - .named(Constants.PROPERTY_SCHEDULER_THREADS))); - - ConfigurableRunner t1 = new ConfigurableRunner(); - t1.result = "okay"; - - ScheduledFuture esc = performScheduleInSeparateMethod1(sched, t1); - assert esc.toString().indexOf("ConfigurableRunner") >= 0; - assert esc.get().equals("okay"); - - closer.close(); - } - - @Test(groups = "unit") - public void testDescribedFutureExceptionIncludesSubmissionTrace() throws Exception { - - ScheduledExecutorServiceModule module = new ScheduledExecutorServiceModule() { - @Override - protected void configure() { - bindConstant().annotatedWith(Names.named(Constants.PROPERTY_SCHEDULER_THREADS)).to(1); - super.configure(); - } - }; - - Injector i = Guice.createInjector(module); - Closer closer = i.getInstance(Closer.class); - - ScheduledExecutorService sched = i.getInstance(Key.get(ScheduledExecutorService.class, Names - .named(Constants.PROPERTY_SCHEDULER_THREADS))); - - ConfigurableRunner t1 = new ConfigurableRunner(); - t1.failMessage = "foo"; - t1.result = "shouldn't happen"; - - ScheduledFuture esc = performScheduleInSeparateMethod1(sched, t1); - checkFutureGetFailsWith(esc, "foo", "testDescribedFutureExceptionIncludesSubmissionTrace", "performScheduleInSeparateMethod1"); - - ScheduledFuture esr = performScheduleInSeparateMethod2(sched, t1); - checkFutureGetFailsWith(esr, "foo", "testDescribedFutureExceptionIncludesSubmissionTrace", "performScheduleInSeparateMethod2"); - - ScheduledFuture esfr = performScheduleInSeparateMethod3(sched, t1); - checkFutureGetFailsWith(esfr, "foo", "testDescribedFutureExceptionIncludesSubmissionTrace", "performScheduleInSeparateMethod3"); - - ScheduledFuture esfd = performScheduleInSeparateMethod4(sched, t1); - checkFutureGetFailsWith(esfd, "foo", "testDescribedFutureExceptionIncludesSubmissionTrace", "performScheduleInSeparateMethod4"); - - closer.close(); - } - - static ScheduledFuture performScheduleInSeparateMethod1(ScheduledExecutorService sched, ConfigurableRunner t1) { - return sched.schedule((Callable)t1, 0, TimeUnit.SECONDS); - } - - static ScheduledFuture performScheduleInSeparateMethod2(ScheduledExecutorService sched, ConfigurableRunner t1) { - return sched.schedule((Runnable)t1, 0, TimeUnit.SECONDS); - } - - static ScheduledFuture performScheduleInSeparateMethod3(ScheduledExecutorService sched, ConfigurableRunner t1) { - return sched.scheduleAtFixedRate((Runnable)t1, 0, 1, TimeUnit.SECONDS); - } - - static ScheduledFuture performScheduleInSeparateMethod4(ScheduledExecutorService sched, ConfigurableRunner t1) { - return sched.scheduleWithFixedDelay((Runnable)t1, 0, 1, TimeUnit.SECONDS); } } diff --git a/core/src/test/java/org/jclouds/events/config/EventBusModuleTest.java b/core/src/test/java/org/jclouds/events/config/EventBusModuleTest.java index 47a5825191..e55b6ca858 100644 --- a/core/src/test/java/org/jclouds/events/config/EventBusModuleTest.java +++ b/core/src/test/java/org/jclouds/events/config/EventBusModuleTest.java @@ -46,7 +46,7 @@ public class EventBusModuleTest { @BeforeClass public void setup() { - ExecutorServiceModule executorServiceModule = new ExecutorServiceModule() { + ExecutorServiceModule userExecutorModule = new ExecutorServiceModule() { @Override protected void configure() { bindConstant().annotatedWith(Names.named(Constants.PROPERTY_IO_WORKER_THREADS)).to(1); @@ -55,7 +55,7 @@ public class EventBusModuleTest { } }; EventBusModule eventBusModule = new EventBusModule(); - injector = Guice.createInjector(executorServiceModule, eventBusModule); + injector = Guice.createInjector(userExecutorModule, eventBusModule); } public void testAsyncExecutorIsProvided() { diff --git a/core/src/test/java/org/jclouds/http/handlers/BackoffLimitedRetryHandlerTest.java b/core/src/test/java/org/jclouds/http/handlers/BackoffLimitedRetryHandlerTest.java index 38dce3d7ad..b380fcd69b 100644 --- a/core/src/test/java/org/jclouds/http/handlers/BackoffLimitedRetryHandlerTest.java +++ b/core/src/test/java/org/jclouds/http/handlers/BackoffLimitedRetryHandlerTest.java @@ -24,33 +24,17 @@ import static org.testng.Assert.assertTrue; import java.io.IOException; import java.io.InputStream; import java.util.Properties; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import javax.net.ssl.HostnameVerifier; -import javax.net.ssl.SSLContext; -import javax.net.ssl.SSLSession; - -import org.jclouds.date.internal.DateServiceDateCodecFactory; -import org.jclouds.date.internal.SimpleDateFormatDateService; import org.jclouds.http.BaseJettyTest; import org.jclouds.http.HttpCommand; -import org.jclouds.http.HttpCommandExecutorService; import org.jclouds.http.HttpResponse; -import org.jclouds.http.HttpUtils; import org.jclouds.http.IntegrationTestAsyncClient; -import org.jclouds.http.internal.HttpWire; -import org.jclouds.http.internal.JavaUrlHttpCommandExecutorService; -import org.jclouds.io.ContentMetadataCodec; -import org.jclouds.io.ContentMetadataCodec.DefaultContentMetadataCodec; import org.jclouds.io.Payloads; -import com.google.common.reflect.Invokable; import org.jclouds.rest.internal.RestAnnotationProcessor; -import org.testng.annotations.BeforeTest; import org.testng.annotations.Test; -import com.google.common.base.Supplier; import com.google.common.collect.ImmutableList; +import com.google.common.reflect.Invokable; import com.google.inject.Key; import com.google.inject.TypeLiteral; @@ -96,35 +80,6 @@ public class BackoffLimitedRetryHandlerTest { } - HttpCommandExecutorService http; - - @BeforeTest - void setupExecutorService() throws Exception { - ExecutorService execService = Executors.newCachedThreadPool(); - BackoffLimitedRetryHandler backoff = new BackoffLimitedRetryHandler(); - HttpUtils utils = new HttpUtils(0, 500, 1, 1); - ContentMetadataCodec contentMetadataCodec = new DefaultContentMetadataCodec(new DateServiceDateCodecFactory( - new SimpleDateFormatDateService())); - RedirectionRetryHandler retry = new RedirectionRetryHandler(backoff); - http = new JavaUrlHttpCommandExecutorService(utils, - contentMetadataCodec, execService, - new DelegatingRetryHandler(backoff, retry), new BackoffLimitedRetryHandler(), - new DelegatingErrorHandler(), new HttpWire(), new HostnameVerifier() { - - @Override - public boolean verify(String hostname, SSLSession session) { - return false; - } - }, new Supplier() { - - @Override - public SSLContext get() { - return null; - } - - }); - } - @Test void testClosesInputStream() throws InterruptedException, IOException, SecurityException, NoSuchMethodException { HttpCommand command = createCommand(); diff --git a/core/src/test/java/org/jclouds/http/internal/TrackingJavaUrlHttpCommandExecutorService.java b/core/src/test/java/org/jclouds/http/internal/TrackingJavaUrlHttpCommandExecutorService.java index fd5d869a09..0719883ef7 100644 --- a/core/src/test/java/org/jclouds/http/internal/TrackingJavaUrlHttpCommandExecutorService.java +++ b/core/src/test/java/org/jclouds/http/internal/TrackingJavaUrlHttpCommandExecutorService.java @@ -20,8 +20,6 @@ package org.jclouds.http.internal; import java.util.Collection; import java.util.List; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Future; import javax.inject.Inject; import javax.inject.Named; @@ -42,6 +40,8 @@ import org.jclouds.rest.internal.GeneratedHttpRequest; import com.google.common.base.Supplier; import com.google.common.collect.Iterables; import com.google.common.reflect.Invokable; +import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.ListeningExecutorService; import com.google.inject.AbstractModule; import com.google.inject.Module; import com.google.inject.TypeLiteral; @@ -88,18 +88,18 @@ public class TrackingJavaUrlHttpCommandExecutorService extends JavaUrlHttpComman @Inject public TrackingJavaUrlHttpCommandExecutorService(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, @Named("untrusted") HostnameVerifier verifier, @Named("untrusted") Supplier untrustedSSLContextProvider, List commandsInvoked) throws SecurityException, NoSuchFieldException { - super(utils, contentMetadataCodec, ioWorkerExecutor, retryHandler, ioRetryHandler, errorHandler, wire, verifier, + super(utils, contentMetadataCodec, ioExecutor, retryHandler, ioRetryHandler, errorHandler, wire, verifier, untrustedSSLContextProvider); this.commandsInvoked = commandsInvoked; } @Override - public Future submit(HttpCommand command) { + public ListenableFuture submit(HttpCommand command) { commandsInvoked.add(command); return super.submit(command); } diff --git a/core/src/test/java/org/jclouds/lifecycle/config/LifeCycleModuleTest.java b/core/src/test/java/org/jclouds/lifecycle/config/LifeCycleModuleTest.java index 1bf0ea2858..ca2e632630 100644 --- a/core/src/test/java/org/jclouds/lifecycle/config/LifeCycleModuleTest.java +++ b/core/src/test/java/org/jclouds/lifecycle/config/LifeCycleModuleTest.java @@ -18,24 +18,24 @@ */ package org.jclouds.lifecycle.config; +import static com.google.inject.name.Names.named; +import static org.jclouds.Constants.PROPERTY_IO_WORKER_THREADS; +import static org.jclouds.Constants.PROPERTY_USER_THREADS; + import java.io.IOException; -import java.util.concurrent.ExecutorService; import javax.annotation.PostConstruct; -import javax.inject.Named; -import org.jclouds.Constants; import org.jclouds.concurrent.config.ExecutorServiceModule; import org.jclouds.lifecycle.Closer; import org.testng.annotations.Test; import com.google.common.util.concurrent.ExecutionList; +import com.google.common.util.concurrent.ListeningExecutorService; import com.google.inject.AbstractModule; import com.google.inject.Guice; import com.google.inject.Injector; import com.google.inject.Key; -import com.google.inject.Provides; -import com.google.inject.name.Names; /** * @@ -47,35 +47,17 @@ public class LifeCycleModuleTest { @Test void testBindsExecutor() { Injector i = createInjector(); - assert i.getInstance(Key.get(ExecutorService.class, Names - .named(Constants.PROPERTY_USER_THREADS))) != null; - assert i.getInstance(Key.get(ExecutorService.class, Names - .named(Constants.PROPERTY_IO_WORKER_THREADS))) != null; + assert i.getInstance(Key.get(ListeningExecutorService.class, named(PROPERTY_USER_THREADS))) != null; + assert i.getInstance(Key.get(ListeningExecutorService.class, named(PROPERTY_IO_WORKER_THREADS))) != null; } private Injector createInjector() { - Injector i = Guice.createInjector(new LifeCycleModule() { - @SuppressWarnings("unused") - @Provides - @Named(Constants.PROPERTY_USER_THREADS) - int p() { - return 1; + Injector i = Guice.createInjector(new AbstractModule() { + protected void configure() { + bindConstant().annotatedWith(named(PROPERTY_IO_WORKER_THREADS)).to(1); + bindConstant().annotatedWith(named(PROPERTY_USER_THREADS)).to(1); } - - @SuppressWarnings("unused") - @Provides - @Named(Constants.PROPERTY_MAX_CONNECTIONS_PER_CONTEXT) - int p2() { - return 1; - } - - @SuppressWarnings("unused") - @Provides - @Named(Constants.PROPERTY_IO_WORKER_THREADS) - int p3() { - return 1; - } - }, new ExecutorServiceModule()); + }, new LifeCycleModule(), new ExecutorServiceModule()); // TODO: currently have to manually invoke the execution list, as otherwise it may occur // before everything is wired up i.getInstance(ExecutionList.class).execute(); @@ -91,8 +73,8 @@ public class LifeCycleModuleTest { @Test void testCloserClosesExecutor() throws IOException { Injector i = createInjector(); - ExecutorService executor = i.getInstance(Key.get(ExecutorService.class, Names - .named(Constants.PROPERTY_USER_THREADS))); + ListeningExecutorService executor = i.getInstance(Key.get(ListeningExecutorService.class, + named(PROPERTY_USER_THREADS))); assert !executor.isShutdown(); Closer closer = i.getInstance(Closer.class); closer.close(); @@ -102,16 +84,16 @@ public class LifeCycleModuleTest { @Test void testCloserPreDestroyOrder() throws IOException { Injector i = createInjector(); - ExecutorService userThreads = i.getInstance(Key.get(ExecutorService.class, Names - .named(Constants.PROPERTY_USER_THREADS))); - assert !userThreads.isShutdown(); - ExecutorService ioThreads = i.getInstance(Key.get(ExecutorService.class, Names - .named(Constants.PROPERTY_IO_WORKER_THREADS))); - assert !ioThreads.isShutdown(); + ListeningExecutorService userExecutor = i.getInstance(Key.get(ListeningExecutorService.class, + named(PROPERTY_USER_THREADS))); + assert !userExecutor.isShutdown(); + ListeningExecutorService ioExecutor = i.getInstance(Key.get(ListeningExecutorService.class, + named(PROPERTY_IO_WORKER_THREADS))); + assert !ioExecutor.isShutdown(); Closer closer = i.getInstance(Closer.class); closer.close(); - assert userThreads.isShutdown(); - assert ioThreads.isShutdown(); + assert userExecutor.isShutdown(); + assert ioExecutor.isShutdown(); } static class PostConstructable { diff --git a/core/src/test/java/org/jclouds/rest/internal/BaseRestApiExpectTest.java b/core/src/test/java/org/jclouds/rest/internal/BaseRestApiExpectTest.java index 0ceaa50f9a..39614ee73e 100644 --- a/core/src/test/java/org/jclouds/rest/internal/BaseRestApiExpectTest.java +++ b/core/src/test/java/org/jclouds/rest/internal/BaseRestApiExpectTest.java @@ -34,7 +34,6 @@ import java.util.Map.Entry; import java.util.NoSuchElementException; import java.util.Properties; import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ExecutorService; import java.util.concurrent.atomic.AtomicInteger; import java.util.logging.Logger; @@ -84,6 +83,7 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import com.google.common.io.InputSupplier; +import com.google.common.util.concurrent.ListeningExecutorService; import com.google.gson.JsonElement; import com.google.gson.JsonParser; import com.google.inject.AbstractModule; @@ -195,7 +195,7 @@ public abstract class BaseRestApiExpectTest { @Inject public ExpectHttpCommandExecutorService(Function fn, HttpUtils utils, ContentMetadataCodec contentMetadataCodec, - @Named(PROPERTY_IO_WORKER_THREADS) ExecutorService ioExecutor, + @Named(PROPERTY_IO_WORKER_THREADS) ListeningExecutorService ioExecutor, IOExceptionRetryHandler ioRetryHandler, DelegatingRetryHandler retryHandler, DelegatingErrorHandler errorHandler, HttpWire wire) { super(utils, contentMetadataCodec, ioExecutor, retryHandler, ioRetryHandler, errorHandler, wire); @@ -230,8 +230,8 @@ public abstract class BaseRestApiExpectTest { @Override public void configure() { - bind(ExecutorService.class).annotatedWith(named(PROPERTY_USER_THREADS)).toInstance(sameThreadExecutor()); - bind(ExecutorService.class).annotatedWith(named(PROPERTY_IO_WORKER_THREADS)).toInstance(sameThreadExecutor()); + bind(ListeningExecutorService.class).annotatedWith(named(PROPERTY_USER_THREADS)).toInstance(sameThreadExecutor()); + bind(ListeningExecutorService.class).annotatedWith(named(PROPERTY_IO_WORKER_THREADS)).toInstance(sameThreadExecutor()); bind(new TypeLiteral>() { }).toInstance(fn); bind(HttpCommandExecutorService.class).to(ExpectHttpCommandExecutorService.class); diff --git a/core/src/test/java/org/jclouds/rest/internal/BaseRestApiTest.java b/core/src/test/java/org/jclouds/rest/internal/BaseRestApiTest.java index bf65184017..56da7994fd 100644 --- a/core/src/test/java/org/jclouds/rest/internal/BaseRestApiTest.java +++ b/core/src/test/java/org/jclouds/rest/internal/BaseRestApiTest.java @@ -32,7 +32,6 @@ import static org.testng.Assert.assertNull; import java.io.IOException; import java.util.Date; import java.util.Map.Entry; -import java.util.concurrent.ExecutorService; import org.jclouds.concurrent.config.ConfiguresExecutorService; import org.jclouds.fallbacks.MapHttp4xxCodesToExceptions; @@ -53,6 +52,7 @@ import com.google.common.collect.TreeMultimap; import com.google.common.reflect.Invokable; import com.google.common.reflect.TypeParameter; import com.google.common.reflect.TypeToken; +import com.google.common.util.concurrent.ListeningExecutorService; import com.google.inject.AbstractModule; import com.google.inject.Injector; import com.google.inject.Key; @@ -82,8 +82,8 @@ public abstract class BaseRestApiTest { @Override protected void configure() { - bind(ExecutorService.class).annotatedWith(named(PROPERTY_USER_THREADS)).toInstance(sameThreadExecutor()); - bind(ExecutorService.class).annotatedWith(named(PROPERTY_IO_WORKER_THREADS)).toInstance(sameThreadExecutor()); + bind(ListeningExecutorService.class).annotatedWith(named(PROPERTY_USER_THREADS)).toInstance(sameThreadExecutor()); + bind(ListeningExecutorService.class).annotatedWith(named(PROPERTY_IO_WORKER_THREADS)).toInstance(sameThreadExecutor()); bind(HttpCommandExecutorService.class).toInstance(mock); } } diff --git a/core/src/test/java/org/jclouds/rest/internal/RestAnnotationProcessorTest.java b/core/src/test/java/org/jclouds/rest/internal/RestAnnotationProcessorTest.java index a8198702b4..70a501ccb6 100644 --- a/core/src/test/java/org/jclouds/rest/internal/RestAnnotationProcessorTest.java +++ b/core/src/test/java/org/jclouds/rest/internal/RestAnnotationProcessorTest.java @@ -45,7 +45,6 @@ import java.util.Map; import java.util.NoSuchElementException; import java.util.Set; import java.util.concurrent.ExecutionException; -import java.util.concurrent.Future; import javax.inject.Named; import javax.inject.Qualifier; @@ -94,7 +93,6 @@ import org.jclouds.logging.config.NullLoggingModule; import org.jclouds.providers.AnonymousProviderMetadata; import org.jclouds.reflect.Invocation; import org.jclouds.reflect.InvocationSuccess; -import com.google.common.reflect.Invokable; import org.jclouds.rest.AuthorizationException; import org.jclouds.rest.ConfiguresRestClient; import org.jclouds.rest.InvocationContext; @@ -144,6 +142,7 @@ import com.google.common.collect.ImmutableSortedSet; import com.google.common.collect.Lists; import com.google.common.collect.Multimap; import com.google.common.io.Files; +import com.google.common.reflect.Invokable; import com.google.common.reflect.TypeToken; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; @@ -255,7 +254,7 @@ public class RestAnnotationProcessorTest extends BaseRestApiTest { Injector child = injectorForCaller(new HttpCommandExecutorService() { @Override - public Future submit(HttpCommand command) { + public ListenableFuture submit(HttpCommand command) { assertEquals(command.getCurrentRequest().getRequestLine(), "GET http://localhost:9999/client/1/foo HTTP/1.1"); return Futures.immediateFuture(HttpResponse.builder().build()); @@ -280,7 +279,7 @@ public class RestAnnotationProcessorTest extends BaseRestApiTest { int callCounter = 0; @Override - public Future submit(HttpCommand command) { + public ListenableFuture submit(HttpCommand command) { if (callCounter == 1) assertEquals(command.getCurrentRequest().getRequestLine(), "GET http://localhost:1111/client/1/bar/2 HTTP/1.1"); @@ -310,7 +309,7 @@ public class RestAnnotationProcessorTest extends BaseRestApiTest { Injector child = injectorForCaller(new HttpCommandExecutorService() { @Override - public Future submit(HttpCommand command) { + public ListenableFuture submit(HttpCommand command) { assertEquals(command.getCurrentRequest().getRequestLine(), "GET http://howdyboys/client/1/foo HTTP/1.1"); return Futures.immediateFuture(HttpResponse.builder().build()); } @@ -335,7 +334,7 @@ public class RestAnnotationProcessorTest extends BaseRestApiTest { Injector child = injectorForCaller(new HttpCommandExecutorService() { @Override - public Future submit(HttpCommand command) { + public ListenableFuture submit(HttpCommand command) { assertEquals(command.getCurrentRequest().getRequestLine(), "GET http://howdyboys/testing/testing/thepathparam/client/1/foo HTTP/1.1"); return Futures.immediateFuture(HttpResponse.builder().build()); @@ -361,7 +360,7 @@ public class RestAnnotationProcessorTest extends BaseRestApiTest { Injector child = injectorForCaller(new HttpCommandExecutorService() { @Override - public Future submit(HttpCommand command) { + public ListenableFuture submit(HttpCommand command) { assertEquals(command.getCurrentRequest().getRequestLine(), "GET http://howdyboys/client/1/foo HTTP/1.1"); return Futures.immediateFuture(HttpResponse.builder().build()); } @@ -386,7 +385,7 @@ public class RestAnnotationProcessorTest extends BaseRestApiTest { Injector child = injectorForCaller(new HttpCommandExecutorService() { @Override - public Future submit(HttpCommand command) { + public ListenableFuture submit(HttpCommand command) { assertEquals(command.getCurrentRequest().getRequestLine(), "GET http://howdyboys/client/1/foo HTTP/1.1"); return Futures.immediateFuture(HttpResponse.builder().build()); } @@ -425,7 +424,7 @@ public class RestAnnotationProcessorTest extends BaseRestApiTest { Injector child = injectorForCaller(new HttpCommandExecutorService() { @Override - public Future submit(HttpCommand command) { + public ListenableFuture submit(HttpCommand command) { assertEquals(command.getCurrentRequest().getRequestLine(), "GET http://howdyboys/client/1/foo HTTP/1.1"); return Futures.immediateFuture(HttpResponse.builder().build()); } 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; } }