diff --git a/antcontrib/src/main/java/org/jclouds/tools/ant/taskdefs/compute/ComputeTaskUtils.java b/antcontrib/src/main/java/org/jclouds/tools/ant/taskdefs/compute/ComputeTaskUtils.java index 0c4b3c2a3b..9c6d41afb5 100644 --- a/antcontrib/src/main/java/org/jclouds/tools/ant/taskdefs/compute/ComputeTaskUtils.java +++ b/antcontrib/src/main/java/org/jclouds/tools/ant/taskdefs/compute/ComputeTaskUtils.java @@ -26,9 +26,9 @@ import java.util.Set; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.Project; +import org.jclouds.ContextBuilder; import org.jclouds.compute.ComputeService; import org.jclouds.compute.ComputeServiceContext; -import org.jclouds.compute.ComputeServiceContextFactory; import org.jclouds.compute.domain.OsFamily; import org.jclouds.compute.domain.Template; import org.jclouds.compute.domain.TemplateBuilder; @@ -73,14 +73,16 @@ public class ComputeTaskUtils { public ComputeServiceContext load(URI from) { Properties props = new Properties(); props.putAll(projectProvider.get().getProperties()); + Set modules = ImmutableSet. of(new AntLoggingModule(projectProvider.get(), + ComputeServiceConstants.COMPUTE_LOGGER), new JschSshClientModule()); // adding the properties to the factory will allow us to pass // alternate endpoints String provider = from.getHost(); Credentials creds = Credentials.parse(from); - return new ComputeServiceContextFactory().createContext(provider, creds.identity, creds.credential, - ImmutableSet.of((Module) new AntLoggingModule(projectProvider.get(), - ComputeServiceConstants.COMPUTE_LOGGER), new JschSshClientModule()), props); - + return ContextBuilder.newBuilder(provider) + .credentials(creds.identity, creds.credential) + .modules(modules) + .overrides(props).buildView(ComputeServiceContext.class); } }); diff --git a/apis/atmos/src/main/java/org/jclouds/atmos/AtmosApiMetadata.java b/apis/atmos/src/main/java/org/jclouds/atmos/AtmosApiMetadata.java index c4f6f01201..82d97ed8de 100644 --- a/apis/atmos/src/main/java/org/jclouds/atmos/AtmosApiMetadata.java +++ b/apis/atmos/src/main/java/org/jclouds/atmos/AtmosApiMetadata.java @@ -85,7 +85,7 @@ public class AtmosApiMetadata extends BaseRestApiMetadata { .version("1.4.0") .defaultEndpoint("https://accesspoint.atmosonline.com") .defaultProperties(AtmosApiMetadata.defaultProperties()) - .wrapper(TypeToken.of(BlobStoreContext.class)) + .view(TypeToken.of(BlobStoreContext.class)) .defaultModules(ImmutableSet.>of(AtmosRestClientModule.class, AtmosBlobStoreContextModule.class)); } diff --git a/apis/atmos/src/main/java/org/jclouds/atmos/filters/ShareUrl.java b/apis/atmos/src/main/java/org/jclouds/atmos/filters/ShareUrl.java index 4fdf7a7cee..596235295d 100644 --- a/apis/atmos/src/main/java/org/jclouds/atmos/filters/ShareUrl.java +++ b/apis/atmos/src/main/java/org/jclouds/atmos/filters/ShareUrl.java @@ -19,8 +19,6 @@ package org.jclouds.atmos.filters; import static org.jclouds.Constants.LOGGER_SIGNATURE; -import static org.jclouds.Constants.PROPERTY_CREDENTIAL; -import static org.jclouds.Constants.PROPERTY_IDENTITY; import java.net.URI; @@ -37,6 +35,8 @@ import org.jclouds.http.HttpException; import org.jclouds.io.InputSuppliers; import org.jclouds.location.Provider; import org.jclouds.logging.Logger; +import org.jclouds.rest.annotations.Credential; +import org.jclouds.rest.annotations.Identity; import com.google.common.base.Function; import com.google.common.base.Supplier; @@ -66,7 +66,7 @@ public class ShareUrl implements Function { Logger signatureLog = Logger.NULL; @Inject - public ShareUrl(@Named(PROPERTY_IDENTITY) String uid, @Named(PROPERTY_CREDENTIAL) String encodedKey, + public ShareUrl(@Identity String uid, @Credential String encodedKey, @Provider Supplier provider, @TimeStamp javax.inject.Provider timeStampProvider, javax.inject.Provider uriBuilders, Crypto crypto) { this.uid = uid; diff --git a/apis/atmos/src/main/java/org/jclouds/atmos/filters/SignRequest.java b/apis/atmos/src/main/java/org/jclouds/atmos/filters/SignRequest.java index 94be6d2c57..65d49031b7 100644 --- a/apis/atmos/src/main/java/org/jclouds/atmos/filters/SignRequest.java +++ b/apis/atmos/src/main/java/org/jclouds/atmos/filters/SignRequest.java @@ -19,8 +19,6 @@ package org.jclouds.atmos.filters; import static org.jclouds.Constants.LOGGER_SIGNATURE; -import static org.jclouds.Constants.PROPERTY_CREDENTIAL; -import static org.jclouds.Constants.PROPERTY_IDENTITY; import static org.jclouds.util.Patterns.NEWLINE_PATTERN; import static org.jclouds.util.Patterns.TWO_SPACE_PATTERN; @@ -46,6 +44,8 @@ import org.jclouds.http.internal.SignatureWire; import org.jclouds.http.utils.ModifyRequest; import org.jclouds.io.InputSuppliers; import org.jclouds.logging.Logger; +import org.jclouds.rest.annotations.Credential; +import org.jclouds.rest.annotations.Identity; import org.jclouds.util.Strings2; import com.google.common.annotations.VisibleForTesting; @@ -79,8 +79,8 @@ public class SignRequest implements HttpRequestFilter { Logger signatureLog = Logger.NULL; @Inject - public SignRequest(SignatureWire signatureWire, @Named(PROPERTY_IDENTITY) String uid, - @Named(PROPERTY_CREDENTIAL) String encodedKey, @TimeStamp Provider timeStampProvider, Crypto crypto, + public SignRequest(SignatureWire signatureWire, @Identity String uid, + @Credential String encodedKey, @TimeStamp Provider timeStampProvider, Crypto crypto, HttpUtils utils) { this.signatureWire = signatureWire; this.uid = uid; diff --git a/apis/atmos/src/test/java/org/jclouds/atmos/AtmosClientLiveTest.java b/apis/atmos/src/test/java/org/jclouds/atmos/AtmosClientLiveTest.java index fc9adafdb9..04e9675a04 100644 --- a/apis/atmos/src/test/java/org/jclouds/atmos/AtmosClientLiveTest.java +++ b/apis/atmos/src/test/java/org/jclouds/atmos/AtmosClientLiveTest.java @@ -57,7 +57,7 @@ import com.google.common.collect.Sets; public class AtmosClientLiveTest extends BaseBlobStoreIntegrationTest { public AtmosClient getApi() { - return context.unwrap(AtmosApiMetadata.CONTEXT_TOKEN).getApi(); + return view.unwrap(AtmosApiMetadata.CONTEXT_TOKEN).getApi(); } private static final class HeadMatches implements Runnable { diff --git a/apis/atmos/src/test/java/org/jclouds/atmos/blobstore/integration/AtmosLiveTest.java b/apis/atmos/src/test/java/org/jclouds/atmos/blobstore/integration/AtmosLiveTest.java index 4c17e48f31..d826318341 100644 --- a/apis/atmos/src/test/java/org/jclouds/atmos/blobstore/integration/AtmosLiveTest.java +++ b/apis/atmos/src/test/java/org/jclouds/atmos/blobstore/integration/AtmosLiveTest.java @@ -34,6 +34,6 @@ public class AtmosLiveTest extends BaseBlobLiveTest { } protected void checkMD5(String container, String name, byte[] md5) { // atmos does not support content-md5 yet - assertEquals(context.getBlobStore().blobMetadata(container, name).getContentMetadata().getContentMD5(), null); + assertEquals(view.getBlobStore().blobMetadata(container, name).getContentMetadata().getContentMD5(), null); } } diff --git a/apis/byon/src/main/java/org/jclouds/byon/BYONApiMetadata.java b/apis/byon/src/main/java/org/jclouds/byon/BYONApiMetadata.java index 1aa7293702..9f8539ae7b 100644 --- a/apis/byon/src/main/java/org/jclouds/byon/BYONApiMetadata.java +++ b/apis/byon/src/main/java/org/jclouds/byon/BYONApiMetadata.java @@ -70,7 +70,7 @@ public class BYONApiMetadata extends BaseApiMetadata { .documentation(URI.create("https://github.com/jclouds/jclouds/tree/master/apis/byon")) .version(String.format("%s.%s", JcloudsVersion.get().majorVersion, JcloudsVersion.get().minorVersion)) .buildVersion(JcloudsVersion.get().toString()) - .wrapper(ComputeServiceContext.class) + .view(ComputeServiceContext.class) .defaultModules(ImmutableSet.>of(YamlNodeStoreModule.class, BYONComputeServiceContextModule.class)); } diff --git a/apis/cloudfiles/src/main/java/org/jclouds/cloudfiles/CloudFilesApiMetadata.java b/apis/cloudfiles/src/main/java/org/jclouds/cloudfiles/CloudFilesApiMetadata.java index 85bbdd6fd0..d2211b8395 100644 --- a/apis/cloudfiles/src/main/java/org/jclouds/cloudfiles/CloudFilesApiMetadata.java +++ b/apis/cloudfiles/src/main/java/org/jclouds/cloudfiles/CloudFilesApiMetadata.java @@ -83,7 +83,7 @@ public class CloudFilesApiMetadata extends BaseRestApiMetadata { .documentation(URI.create("http://docs.rackspacecloud.com/files/api/v1/cfdevguide_d5/content/ch01.html")) .version(OpenStackAuthAsyncClient.VERSION) .defaultProperties(CloudFilesApiMetadata.defaultProperties()) - .wrapper(TypeToken.of(BlobStoreContext.class)) + .view(TypeToken.of(BlobStoreContext.class)) .defaultModules(ImmutableSet.>of(CloudFilesRestClientModule.class, CloudFilesBlobStoreContextModule.class)); } diff --git a/apis/cloudfiles/src/main/java/org/jclouds/cloudfiles/CloudFilesAsyncClient.java b/apis/cloudfiles/src/main/java/org/jclouds/cloudfiles/CloudFilesAsyncClient.java index 7960a92c86..14e3b28f5f 100644 --- a/apis/cloudfiles/src/main/java/org/jclouds/cloudfiles/CloudFilesAsyncClient.java +++ b/apis/cloudfiles/src/main/java/org/jclouds/cloudfiles/CloudFilesAsyncClient.java @@ -55,7 +55,7 @@ import com.google.common.util.concurrent.ListenableFuture; * Provides asynchronous access to Cloud Files via their REST API. *

* All commands return a ListenableFuture of the result from Cloud Files. Any exceptions incurred - * during processing will be wrapped in an {@link ExecutionException} as documented in + * during processing will be backend in an {@link ExecutionException} as documented in * {@link ListenableFuture#get()}. * * @see CloudFilesClient diff --git a/apis/cloudfiles/src/main/java/org/jclouds/cloudfiles/CloudFilesClient.java b/apis/cloudfiles/src/main/java/org/jclouds/cloudfiles/CloudFilesClient.java index de7a030363..e74ca1ec54 100644 --- a/apis/cloudfiles/src/main/java/org/jclouds/cloudfiles/CloudFilesClient.java +++ b/apis/cloudfiles/src/main/java/org/jclouds/cloudfiles/CloudFilesClient.java @@ -33,7 +33,7 @@ import org.jclouds.openstack.swift.CommonSwiftClient; * Provides access to Cloud Files via their REST API. *

* All commands return a Future of the result from Cloud Files. Any exceptions incurred during - * processing will be wrapped in an {@link ExecutionException} as documented in {@link Future#get()}. + * processing will be backend in an {@link ExecutionException} as documented in {@link Future#get()}. * * @see * @author Adrian Cole 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 34b61b03de..4d1cbb63e0 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 @@ -49,6 +49,7 @@ import org.jclouds.openstack.swift.blobstore.functions.ObjectToBlobMetadata; 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; /** * @@ -66,10 +67,11 @@ public class CloudFilesAsyncBlobStore extends SwiftAsyncBlobStore { BlobStoreListContainerOptionsToListContainerOptions container2ContainerListOptions, ContainerToResourceList container2ResourceList, ObjectToBlob object2Blob, BlobToObject blob2Object, ObjectToBlobMetadata object2BlobMd, BlobToHttpGetOptions blob2ObjectGetOptions, - Provider fetchBlobMetadataProvider, EnableCDNAndCache enableCDNAndCache) { + Provider fetchBlobMetadataProvider, EnableCDNAndCache enableCDNAndCache, + Provider multipartUploadStrategy) { super(context, blobUtils, service, defaultLocation, locations, sync, async, container2ResourceMd, container2ContainerListOptions, container2ResourceList, object2Blob, blob2Object, object2BlobMd, - blob2ObjectGetOptions, fetchBlobMetadataProvider); + blob2ObjectGetOptions, fetchBlobMetadataProvider, multipartUploadStrategy); this.enableCDNAndCache = enableCDNAndCache; } diff --git a/apis/cloudfiles/src/main/java/org/jclouds/cloudfiles/blobstore/CloudFilesBlobStore.java b/apis/cloudfiles/src/main/java/org/jclouds/cloudfiles/blobstore/CloudFilesBlobStore.java index 42be6d884c..c0d8f2d099 100644 --- a/apis/cloudfiles/src/main/java/org/jclouds/cloudfiles/blobstore/CloudFilesBlobStore.java +++ b/apis/cloudfiles/src/main/java/org/jclouds/cloudfiles/blobstore/CloudFilesBlobStore.java @@ -42,6 +42,7 @@ import org.jclouds.openstack.swift.blobstore.functions.ObjectToBlob; import org.jclouds.openstack.swift.blobstore.functions.ObjectToBlobMetadata; import com.google.common.base.Supplier; +import org.jclouds.openstack.swift.blobstore.strategy.internal.MultipartUploadStrategy; /** * @@ -59,10 +60,11 @@ public class CloudFilesBlobStore extends SwiftBlobStore { BlobStoreListContainerOptionsToListContainerOptions container2ContainerListOptions, ContainerToResourceList container2ResourceList, ObjectToBlob object2Blob, BlobToObject blob2Object, ObjectToBlobMetadata object2BlobMd, BlobToHttpGetOptions blob2ObjectGetOptions, - Provider fetchBlobMetadataProvider, EnableCDNAndCache enableCDNAndCache) { + Provider fetchBlobMetadataProvider, EnableCDNAndCache enableCDNAndCache, + Provider multipartUploadStrategy) { super(context, blobUtils, defaultLocation, locations, sync, container2ResourceMd, container2ContainerListOptions, container2ResourceList, object2Blob, blob2Object, object2BlobMd, blob2ObjectGetOptions, - fetchBlobMetadataProvider); + fetchBlobMetadataProvider, multipartUploadStrategy); this.enableCDNAndCache = enableCDNAndCache; } diff --git a/apis/cloudfiles/src/test/java/org/jclouds/cloudfiles/CloudFilesClientLiveTest.java b/apis/cloudfiles/src/test/java/org/jclouds/cloudfiles/CloudFilesClientLiveTest.java index e7b382059f..7d4a2282fd 100644 --- a/apis/cloudfiles/src/test/java/org/jclouds/cloudfiles/CloudFilesClientLiveTest.java +++ b/apis/cloudfiles/src/test/java/org/jclouds/cloudfiles/CloudFilesClientLiveTest.java @@ -47,7 +47,7 @@ public class CloudFilesClientLiveTest extends CommonSwiftClientLiveTest>of(CloudLoadBalancersRestClientModule.class, CloudLoadBalancersLoadBalancerContextModule.class)); } diff --git a/apis/cloudloadbalancers/src/test/java/org/jclouds/cloudloadbalancers/internal/BaseCloudLoadBalancersAsyncClientTest.java b/apis/cloudloadbalancers/src/test/java/org/jclouds/cloudloadbalancers/internal/BaseCloudLoadBalancersAsyncClientTest.java index d0ed3c0283..9997affe35 100644 --- a/apis/cloudloadbalancers/src/test/java/org/jclouds/cloudloadbalancers/internal/BaseCloudLoadBalancersAsyncClientTest.java +++ b/apis/cloudloadbalancers/src/test/java/org/jclouds/cloudloadbalancers/internal/BaseCloudLoadBalancersAsyncClientTest.java @@ -77,6 +77,7 @@ public abstract class BaseCloudLoadBalancersAsyncClientTest extends BaseAsync protected void configure() { } + @SuppressWarnings("unused") @Provides @Singleton GetAuth provideGetAuth() { diff --git a/apis/cloudloadbalancers/src/test/java/org/jclouds/cloudloadbalancers/internal/BaseCloudLoadBalancersClientLiveTest.java b/apis/cloudloadbalancers/src/test/java/org/jclouds/cloudloadbalancers/internal/BaseCloudLoadBalancersClientLiveTest.java index 201a5b363a..72e734af0c 100644 --- a/apis/cloudloadbalancers/src/test/java/org/jclouds/cloudloadbalancers/internal/BaseCloudLoadBalancersClientLiveTest.java +++ b/apis/cloudloadbalancers/src/test/java/org/jclouds/cloudloadbalancers/internal/BaseCloudLoadBalancersClientLiveTest.java @@ -20,7 +20,7 @@ package org.jclouds.cloudloadbalancers.internal; import java.util.concurrent.TimeUnit; -import org.jclouds.apis.BaseContextLiveTest; +import org.jclouds.apis.BaseViewLiveTest; import org.jclouds.cloudloadbalancers.CloudLoadBalancersAsyncClient; import org.jclouds.cloudloadbalancers.CloudLoadBalancersClient; import org.jclouds.cloudloadbalancers.domain.LoadBalancer; @@ -42,7 +42,7 @@ import com.google.inject.Injector; * * @author Adrian Cole */ -public class BaseCloudLoadBalancersClientLiveTest extends BaseContextLiveTest { +public class BaseCloudLoadBalancersClientLiveTest extends BaseViewLiveTest { public BaseCloudLoadBalancersClientLiveTest() { provider = "cloudloadbalancers"; @@ -61,7 +61,7 @@ public class BaseCloudLoadBalancersClientLiveTest extends BaseContextLiveTest contextType() { + protected TypeToken viewType() { return TypeToken.of(LoadBalancerServiceContext.class); } diff --git a/apis/cloudservers/src/main/java/org/jclouds/cloudservers/CloudServersApiMetadata.java b/apis/cloudservers/src/main/java/org/jclouds/cloudservers/CloudServersApiMetadata.java index 208fb51b30..954355dfbe 100644 --- a/apis/cloudservers/src/main/java/org/jclouds/cloudservers/CloudServersApiMetadata.java +++ b/apis/cloudservers/src/main/java/org/jclouds/cloudservers/CloudServersApiMetadata.java @@ -77,7 +77,7 @@ public class CloudServersApiMetadata extends BaseRestApiMetadata { .version(OpenStackAuthAsyncClient.VERSION) .defaultEndpoint("https://auth.api.rackspacecloud.com") .defaultProperties(CloudServersApiMetadata.defaultProperties()) - .wrapper(TypeToken.of(ComputeServiceContext.class)) + .view(TypeToken.of(ComputeServiceContext.class)) .defaultModules(ImmutableSet.>of(CloudServersRestClientModule.class, CloudServersComputeServiceContextModule.class)); } diff --git a/apis/cloudservers/src/main/java/org/jclouds/cloudservers/CloudServersAsyncClient.java b/apis/cloudservers/src/main/java/org/jclouds/cloudservers/CloudServersAsyncClient.java index 86a326e42d..9a9f31ca40 100644 --- a/apis/cloudservers/src/main/java/org/jclouds/cloudservers/CloudServersAsyncClient.java +++ b/apis/cloudservers/src/main/java/org/jclouds/cloudservers/CloudServersAsyncClient.java @@ -69,7 +69,7 @@ import com.google.common.util.concurrent.ListenableFuture; * Provides asynchronous access to Cloud Servers via their REST API. *

* All commands return a ListenableFuture of the result from Cloud Servers. Any exceptions incurred - * during processing will be wrapped in an {@link ExecutionException} as documented in + * during processing will be backend in an {@link ExecutionException} as documented in * {@link ListenableFuture#get()}. * * @see CloudServersClient diff --git a/apis/cloudservers/src/main/java/org/jclouds/cloudservers/CloudServersClient.java b/apis/cloudservers/src/main/java/org/jclouds/cloudservers/CloudServersClient.java index 54f2207575..517104fd93 100644 --- a/apis/cloudservers/src/main/java/org/jclouds/cloudservers/CloudServersClient.java +++ b/apis/cloudservers/src/main/java/org/jclouds/cloudservers/CloudServersClient.java @@ -44,7 +44,7 @@ import org.jclouds.rest.ResourceNotFoundException; * Provides access to Cloud Servers via their REST API. *

* All commands return a Future of the result from Cloud Servers. Any exceptions incurred during - * processing will be wrapped in an {@link ExecutionException} as documented in {@link Future#get()}. + * processing will be backend in an {@link ExecutionException} as documented in {@link Future#get()}. * * @see CloudServersAsyncClient * @see diff --git a/apis/cloudservers/src/test/java/org/jclouds/cloudservers/CloudServersClientLiveTest.java b/apis/cloudservers/src/test/java/org/jclouds/cloudservers/CloudServersClientLiveTest.java index d1f0cc47e9..eca7ef3d62 100644 --- a/apis/cloudservers/src/test/java/org/jclouds/cloudservers/CloudServersClientLiveTest.java +++ b/apis/cloudservers/src/test/java/org/jclouds/cloudservers/CloudServersClientLiveTest.java @@ -85,7 +85,7 @@ public class CloudServersClientLiveTest extends BaseComputeServiceContextLiveTes @Override public void setupContext() { super.setupContext(); - Injector injector = context.utils().injector(); + Injector injector = view.utils().injector(); client = injector.getInstance(CloudServersClient.class); sshFactory = injector.getInstance(SshClient.Factory.class); SocketOpen socketOpen = injector.getInstance(SocketOpen.class); diff --git a/apis/cloudsigma/src/main/java/org/jclouds/cloudsigma/CloudSigmaApiMetadata.java b/apis/cloudsigma/src/main/java/org/jclouds/cloudsigma/CloudSigmaApiMetadata.java index 28be12c28c..6ea2798e47 100644 --- a/apis/cloudsigma/src/main/java/org/jclouds/cloudsigma/CloudSigmaApiMetadata.java +++ b/apis/cloudsigma/src/main/java/org/jclouds/cloudsigma/CloudSigmaApiMetadata.java @@ -82,7 +82,7 @@ public class CloudSigmaApiMetadata extends BaseRestApiMetadata { .version("1.0") .defaultEndpoint("https://api.cloudsigma.com") .defaultProperties(CloudSigmaApiMetadata.defaultProperties()) - .wrapper(TypeToken.of(ComputeServiceContext.class)) + .view(TypeToken.of(ComputeServiceContext.class)) .defaultModules(ImmutableSet.>of(CloudSigmaRestClientModule.class, CloudSigmaComputeServiceContextModule.class)); } diff --git a/apis/cloudsigma/src/test/java/org/jclouds/cloudsigma/CloudSigmaClientLiveTest.java b/apis/cloudsigma/src/test/java/org/jclouds/cloudsigma/CloudSigmaClientLiveTest.java index 48f8c98bb7..e8b0a729ff 100644 --- a/apis/cloudsigma/src/test/java/org/jclouds/cloudsigma/CloudSigmaClientLiveTest.java +++ b/apis/cloudsigma/src/test/java/org/jclouds/cloudsigma/CloudSigmaClientLiveTest.java @@ -89,7 +89,7 @@ public class CloudSigmaClientLiveTest extends BaseComputeServiceContextLiveTest @Override public void setupContext() { super.setupContext(); - cloudSigmaContext = context.unwrap(); + cloudSigmaContext = view.unwrap(); client = cloudSigmaContext.getApi(); driveNotClaimed = new RetryablePredicate(Predicates.not(new DriveClaimed(client)), maxDriveImageTime, @@ -98,7 +98,7 @@ public class CloudSigmaClientLiveTest extends BaseComputeServiceContextLiveTest TimeUnit.SECONDS); if (Strings.emptyToNull(imageId) == null) { - imageId = context.getComputeService().templateBuilder().build().getImage().getId(); + imageId = view.getComputeService().templateBuilder().build().getImage().getId(); } } diff --git a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/CloudStackApiMetadata.java b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/CloudStackApiMetadata.java index ac6981292f..cdb671f895 100644 --- a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/CloudStackApiMetadata.java +++ b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/CloudStackApiMetadata.java @@ -89,7 +89,7 @@ public class CloudStackApiMetadata extends BaseRestApiMetadata { .documentation(URI.create("http://download.cloud.com/releases/2.2.0/api_2.2.12/TOC_User.html")) .defaultEndpoint("http://localhost:8080/client/api") .version("2.2") - .wrapper(TypeToken.of(CloudStackContext.class)) + .view(TypeToken.of(CloudStackContext.class)) .defaultProperties(CloudStackApiMetadata.defaultProperties()) .defaultModules(ImmutableSet.>of(CloudStackRestClientModule.class, CloudStackComputeServiceContextModule.class)); } diff --git a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/compute/functions/TemplateToOperatingSystem.java b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/compute/functions/TemplateToOperatingSystem.java index 6c63d78e54..fb4df381fa 100644 --- a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/compute/functions/TemplateToOperatingSystem.java +++ b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/compute/functions/TemplateToOperatingSystem.java @@ -72,14 +72,14 @@ public class TemplateToOperatingSystem implements Function builder) { + public QuerySigner(SignatureWire signatureWire, @Identity String accessKey, @Credential String secretKey, + Crypto crypto, HttpUtils utils, Provider builder) { this.signatureWire = signatureWire; this.accessKey = accessKey; this.secretKey = secretKey; diff --git a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/functions/ParseAsyncJobsFromHttpResponse.java b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/functions/ParseAsyncJobsFromHttpResponse.java index 0cfeae650f..7c7e4515a6 100644 --- a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/functions/ParseAsyncJobsFromHttpResponse.java +++ b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/functions/ParseAsyncJobsFromHttpResponse.java @@ -46,10 +46,10 @@ public class ParseAsyncJobsFromHttpResponse implements Function>>>( - checkNotNull(gsonWrapper, "gsonWrapper"), + checkNotNull(gsonView, "gsonView"), new TypeLiteral>>>() { }, "asyncjobs"); } diff --git a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/functions/ParseEventTypesFromHttpResponse.java b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/functions/ParseEventTypesFromHttpResponse.java index 341b578ef0..bf2e6ece0a 100644 --- a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/functions/ParseEventTypesFromHttpResponse.java +++ b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/functions/ParseEventTypesFromHttpResponse.java @@ -54,8 +54,8 @@ public class ParseEventTypesFromHttpResponse implements Function>(checkNotNull(gsonWrapper, "gsonWrapper"), + public ParseEventTypesFromHttpResponse(GsonWrapper gsonView) { + this.parser = new ParseFirstJsonValueNamed>(checkNotNull(gsonView, "gsonView"), new TypeLiteral>() { }, "eventtype"); } diff --git a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/functions/ParseIdToNameFromHttpResponse.java b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/functions/ParseIdToNameFromHttpResponse.java index fdd1aa8718..70ff9506a4 100644 --- a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/functions/ParseIdToNameFromHttpResponse.java +++ b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/functions/ParseIdToNameFromHttpResponse.java @@ -78,8 +78,8 @@ public class ParseIdToNameFromHttpResponse implements Function>(checkNotNull(gsonWrapper, "gsonWrapper"), + public ParseIdToNameFromHttpResponse(GsonWrapper gsonView) { + this.parser = new ParseFirstJsonValueNamed>(checkNotNull(gsonView, "gsonView"), new TypeLiteral>() { }, "oscategory"); } diff --git a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/functions/ParseLoginResponseFromHttpResponse.java b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/functions/ParseLoginResponseFromHttpResponse.java index 107e7d86ef..41f9635493 100644 --- a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/functions/ParseLoginResponseFromHttpResponse.java +++ b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/functions/ParseLoginResponseFromHttpResponse.java @@ -23,7 +23,7 @@ public class ParseLoginResponseFromHttpResponse implements Function(checkNotNull(gson, "gsonWrapper"), + this.parser = new ParseFirstJsonValueNamed(checkNotNull(gson, "gsonView"), new TypeLiteral(){}, "loginresponse"); } diff --git a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/functions/ParseNamesFromHttpResponse.java b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/functions/ParseNamesFromHttpResponse.java index 16b8af5984..2f09a47245 100644 --- a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/functions/ParseNamesFromHttpResponse.java +++ b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/functions/ParseNamesFromHttpResponse.java @@ -73,8 +73,8 @@ public class ParseNamesFromHttpResponse implements Function>(checkNotNull(gsonWrapper, "gsonWrapper"), + public ParseNamesFromHttpResponse(GsonWrapper gsonView) { + this.parser = new ParseFirstJsonValueNamed>(checkNotNull(gsonView, "gsonView"), new TypeLiteral>() { }, "hypervisor"); } diff --git a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/internal/CloudStackContextImpl.java b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/internal/CloudStackContextImpl.java index 3267f9d56b..118bc7c8dc 100644 --- a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/internal/CloudStackContextImpl.java +++ b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/internal/CloudStackContextImpl.java @@ -18,12 +18,10 @@ */ package org.jclouds.cloudstack.internal; -import java.io.Closeable; -import java.util.Map; - import javax.inject.Inject; import javax.inject.Singleton; +import org.jclouds.Context; import org.jclouds.cloudstack.CloudStackAsyncClient; import org.jclouds.cloudstack.CloudStackClient; import org.jclouds.cloudstack.CloudStackContext; @@ -34,7 +32,6 @@ import org.jclouds.cloudstack.CloudStackGlobalClient; import org.jclouds.compute.ComputeService; import org.jclouds.compute.Utils; import org.jclouds.compute.internal.ComputeServiceContextImpl; -import org.jclouds.domain.Credentials; import org.jclouds.location.Provider; import org.jclouds.rest.RestContext; @@ -49,11 +46,11 @@ public class CloudStackContextImpl extends ComputeServiceContextImpl implements private final RestContext globalContext; @Inject - public CloudStackContextImpl(@Provider Closeable wrapped, @Provider TypeToken wrappedType, - ComputeService computeService, Map credentialStore, Utils utils, + public CloudStackContextImpl(@Provider Context backend, @Provider TypeToken backendType, + ComputeService computeService, Utils utils, RestContext domainContext, RestContext globalContext) { - super(wrapped, wrappedType, computeService, credentialStore, utils); + super(backend, backendType, computeService, utils); this.domainContext = domainContext; this.globalContext = globalContext; } diff --git a/apis/cloudstack/src/test/java/org/jclouds/cloudstack/compute/CloudStackComputeServiceAdapterLiveTest.java b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/compute/CloudStackComputeServiceAdapterLiveTest.java index 0da85d8081..41a32cc956 100644 --- a/apis/cloudstack/src/test/java/org/jclouds/cloudstack/compute/CloudStackComputeServiceAdapterLiveTest.java +++ b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/compute/CloudStackComputeServiceAdapterLiveTest.java @@ -157,7 +157,7 @@ public class CloudStackComputeServiceAdapterLiveTest extends BaseCloudStackClien public void testCreateNodeWithGroupEncodedIntoName() throws InterruptedException { String group = prefix + "-foo"; String name = group + "-node-" + new Random().nextInt(); - Template template = context.getComputeService().templateBuilder().build(); + Template template = view.getComputeService().templateBuilder().build(); if (!client .getTemplateClient() diff --git a/apis/cloudstack/src/test/java/org/jclouds/cloudstack/compute/CloudStackExperimentLiveTest.java b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/compute/CloudStackExperimentLiveTest.java index c8c8445bb7..2f0f6d9842 100644 --- a/apis/cloudstack/src/test/java/org/jclouds/cloudstack/compute/CloudStackExperimentLiveTest.java +++ b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/compute/CloudStackExperimentLiveTest.java @@ -90,9 +90,9 @@ public class CloudStackExperimentLiveTest extends BaseCloudStackClientLiveTest { Network network = null; Set nodes = null; try { - assert context.getComputeService().listAssignableLocations().size() > 0; + assert view.getComputeService().listAssignableLocations().size() > 0; - Template template = context.getComputeService().templateBuilder().build(); + Template template = view.getComputeService().templateBuilder().build(); // get the zone we are launching into long zoneId = Long.parseLong(template.getLocation().getId()); @@ -115,7 +115,7 @@ public class CloudStackExperimentLiveTest extends BaseCloudStackClientLiveTest { template.getOptions().as(CloudStackTemplateOptions.class).networkId(network.getId()); // launch the VM - nodes = context.getComputeService().createNodesInGroup(group, 1, template); + nodes = view.getComputeService().createNodesInGroup(group, 1, template); assert nodes.size() > 0; @@ -124,7 +124,7 @@ public class CloudStackExperimentLiveTest extends BaseCloudStackClientLiveTest { nodes = newTreeSet(concat(e.getSuccessfulNodes(), e.getNodeErrors().keySet())); } finally { if (nodes != null) - context.getComputeService().destroyNodesMatching(NodePredicates.inGroup(group)); + view.getComputeService().destroyNodesMatching(NodePredicates.inGroup(group)); if (network != null) domainAdminContext.getApi().getNetworkClient().deleteNetwork(network.getId()); } @@ -143,14 +143,14 @@ public class CloudStackExperimentLiveTest extends BaseCloudStackClientLiveTest { SshKeyPair keyPair = client.getSSHKeyPairClient().createSSHKeyPair(keyPairName); String group = prefix + "-windows-test"; - Template template = context.getComputeService().templateBuilder() + Template template = view.getComputeService().templateBuilder() .imageId("290").locationId("1") .options(new CloudStackTemplateOptions().setupStaticNat(false).keyPair(keyPairName)) .build(); NodeMetadata node = null; try { - node = getOnlyElement(context.getComputeService() + node = getOnlyElement(view.getComputeService() .createNodesInGroup(group, 1, template)); String encryptedPassword = client.getVirtualMachineClient() @@ -165,7 +165,7 @@ public class CloudStackExperimentLiveTest extends BaseCloudStackClientLiveTest { } finally { if (node != null) { - context.getComputeService().destroyNode(node.getId()); + view.getComputeService().destroyNode(node.getId()); } } diff --git a/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/BaseCloudStackClientLiveTest.java b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/BaseCloudStackClientLiveTest.java index d202c58841..f750cca75c 100644 --- a/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/BaseCloudStackClientLiveTest.java +++ b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/BaseCloudStackClientLiveTest.java @@ -51,7 +51,7 @@ import org.jclouds.cloudstack.predicates.VirtualMachineRunning; import org.jclouds.cloudstack.strategy.BlockUntilJobCompletesAndReturnResult; import org.jclouds.compute.ComputeService; import org.jclouds.compute.domain.ExecResponse; -import org.jclouds.compute.internal.BaseComputeServiceContextLiveTest; +import org.jclouds.compute.internal.BaseGenericComputeServiceContextLiveTest; import org.jclouds.net.IPSocket; import org.jclouds.predicates.InetSocketAddressConnect; import org.jclouds.predicates.RetryablePredicate; @@ -65,6 +65,7 @@ import com.google.common.base.Predicate; import com.google.common.base.Predicates; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Iterables; +import com.google.common.reflect.TypeToken; import com.google.inject.Guice; import com.google.inject.Injector; import com.google.inject.Module; @@ -73,7 +74,7 @@ import com.google.inject.Module; * * @author Adrian Cole */ -public class BaseCloudStackClientLiveTest extends BaseComputeServiceContextLiveTest { +public class BaseCloudStackClientLiveTest extends BaseGenericComputeServiceContextLiveTest { protected String domainAdminIdentity; protected String domainAdminCredential; protected String globalAdminIdentity; @@ -82,7 +83,12 @@ public class BaseCloudStackClientLiveTest extends BaseComputeServiceContextLiveT public BaseCloudStackClientLiveTest() { provider = "cloudstack"; } - + + @Override + protected TypeToken viewType() { + return TypeToken.of(CloudStackContext.class); + } + @Override protected Properties setupProperties() { Properties overrides = super.setupProperties(); @@ -193,14 +199,14 @@ public class BaseCloudStackClientLiveTest extends BaseComputeServiceContextLiveT @Override public void setupContext() { super.setupContext(); - computeClient = context.getComputeService(); - cloudStackContext = context.unwrap(); + computeClient = view.getComputeService(); + cloudStackContext = view.unwrap(); client = cloudStackContext.getApi(); user = verifyCurrentUserIsOfType(cloudStackContext, Account.Type.USER); domainAdminEnabled = setupDomainAdminProperties() != null; if (domainAdminEnabled) { - domainAdminComputeContext = createContext(setupDomainAdminProperties(), setupModules()).unwrap(); + domainAdminComputeContext = createView(setupDomainAdminProperties(), setupModules()); domainAdminContext = domainAdminComputeContext.getDomainContext(); domainAdminClient = domainAdminContext.getApi(); domainAdminUser = verifyCurrentUserIsOfType(domainAdminContext, Account.Type.DOMAIN_ADMIN); @@ -209,7 +215,7 @@ public class BaseCloudStackClientLiveTest extends BaseComputeServiceContextLiveT globalAdminEnabled = setupGlobalAdminProperties() != null; if (globalAdminEnabled) { - globalAdminComputeContext = createContext(setupGlobalAdminProperties(), setupModules()).unwrap(); + globalAdminComputeContext = createView(setupGlobalAdminProperties(), setupModules()); globalAdminContext = globalAdminComputeContext.getGlobalContext(); globalAdminClient = globalAdminContext.getApi(); globalAdminUser = verifyCurrentUserIsOfType(globalAdminContext, Account.Type.ADMIN); diff --git a/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/GlobalUserClientLiveTest.java b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/GlobalUserClientLiveTest.java index fbc3166f7d..87f4aab4f1 100644 --- a/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/GlobalUserClientLiveTest.java +++ b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/GlobalUserClientLiveTest.java @@ -27,6 +27,7 @@ import static org.testng.Assert.assertNotNull; import java.util.Properties; import java.util.Set; +import org.jclouds.cloudstack.CloudStackApiMetadata; import org.jclouds.cloudstack.CloudStackClient; import org.jclouds.cloudstack.CloudStackGlobalClient; import org.jclouds.cloudstack.domain.Account; @@ -83,9 +84,9 @@ public class GlobalUserClientLiveTest extends BaseCloudStackClientLiveTest { } private void checkAuthAsUser(ApiKeyPair keyPair) { - ComputeServiceContext context = createContext(credentialsAsProperties(keyPair), setupModules()); + ComputeServiceContext context = createView(credentialsAsProperties(keyPair), setupModules()); - CloudStackClient client = CloudStackClient.class.cast(context.getProviderSpecificContext().getApi()); + CloudStackClient client = context.unwrap(CloudStackApiMetadata.CONTEXT_TOKEN).getApi(); Set accounts = client.getAccountClient().listAccounts(); assert accounts.size() > 0; diff --git a/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/OfferingClientLiveTest.java b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/OfferingClientLiveTest.java index fd187ab6c4..b5e2a8c0c5 100644 --- a/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/OfferingClientLiveTest.java +++ b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/OfferingClientLiveTest.java @@ -66,7 +66,8 @@ public class OfferingClientLiveTest extends BaseCloudStackClientLiveTest { } catch (NoSuchElementException e) { // This bug is present both in 2.2.8 and 2.2.12 - assertTrue(Predicates.in(ImmutableSet.of("2.2.8", "2.2.12")).apply(cloudStackContext.getApiVersion())); + assertTrue(Predicates.in(ImmutableSet.of("2.2.8", "2.2.12")).apply( + cloudStackContext.getProviderMetadata().getApiMetadata().getVersion())); } } } diff --git a/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/SessionClientLiveTest.java b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/SessionClientLiveTest.java index 938be58289..aa703839b8 100644 --- a/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/SessionClientLiveTest.java +++ b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/SessionClientLiveTest.java @@ -44,7 +44,7 @@ public class SessionClientLiveTest extends BaseCloudStackClientLiveTest { @Test public void testCreateContextUsingUserAndPasswordAuthentication() { - String endpoint = cloudStackContext.getEndpoint().toASCIIString(); + String endpoint = cloudStackContext.getProviderMetadata().getEndpoint(); assert globalAdminEnabled; Account testAccount = null; @@ -75,7 +75,7 @@ public class SessionClientLiveTest extends BaseCloudStackClientLiveTest { @Test(expectedExceptions = AuthorizationException.class) public void testTryToGetApiKeypairWithWrongCredentials() { - String endpoint = cloudStackContext.getEndpoint().toASCIIString(); + String endpoint = cloudStackContext.getProviderMetadata().getEndpoint(); ApiKeyPairs.loginToEndpointAsUsernameInDomainWithPasswordAndReturnApiKeyPair( URI.create(endpoint), "dummy-missing-user", "with-a-wrong-password", ""); } diff --git a/apis/cloudwatch/src/test/java/org/jclouds/cloudwatch/CloudWatchApiMetadataTest.java b/apis/cloudwatch/src/test/java/org/jclouds/cloudwatch/CloudWatchApiMetadataTest.java index ad68f537f7..baaabf636c 100644 --- a/apis/cloudwatch/src/test/java/org/jclouds/cloudwatch/CloudWatchApiMetadataTest.java +++ b/apis/cloudwatch/src/test/java/org/jclouds/cloudwatch/CloudWatchApiMetadataTest.java @@ -18,7 +18,7 @@ */ package org.jclouds.cloudwatch; -import org.jclouds.Wrapper; +import org.jclouds.View; import org.jclouds.rest.internal.BaseRestApiMetadataTest; import org.testng.annotations.Test; @@ -34,6 +34,6 @@ public class CloudWatchApiMetadataTest extends BaseRestApiMetadataTest { // no monitoring abstraction, yet public CloudWatchApiMetadataTest() { - super(new CloudWatchApiMetadata(), ImmutableSet.> of()); + super(new CloudWatchApiMetadata(), ImmutableSet.> of()); } } diff --git a/apis/deltacloud/src/main/java/org/jclouds/deltacloud/DeltacloudApiMetadata.java b/apis/deltacloud/src/main/java/org/jclouds/deltacloud/DeltacloudApiMetadata.java index 8908404e72..1b90cb3ec5 100644 --- a/apis/deltacloud/src/main/java/org/jclouds/deltacloud/DeltacloudApiMetadata.java +++ b/apis/deltacloud/src/main/java/org/jclouds/deltacloud/DeltacloudApiMetadata.java @@ -75,7 +75,7 @@ public class DeltacloudApiMetadata extends BaseRestApiMetadata { .version("0.3.0") .defaultEndpoint("http://localhost:3001/api") .defaultProperties(DeltacloudApiMetadata.defaultProperties()) - .wrapper(TypeToken.of(ComputeServiceContext.class)) + .view(TypeToken.of(ComputeServiceContext.class)) .defaultModules(ImmutableSet.>of(DeltacloudRestClientModule.class, DeltacloudComputeServiceContextModule.class)); } diff --git a/apis/deltacloud/src/test/java/org/jclouds/deltacloud/ReadOnlyDeltacloudClientLiveTest.java b/apis/deltacloud/src/test/java/org/jclouds/deltacloud/ReadOnlyDeltacloudClientLiveTest.java index c63cbd8b47..c87a0e852e 100644 --- a/apis/deltacloud/src/test/java/org/jclouds/deltacloud/ReadOnlyDeltacloudClientLiveTest.java +++ b/apis/deltacloud/src/test/java/org/jclouds/deltacloud/ReadOnlyDeltacloudClientLiveTest.java @@ -71,7 +71,7 @@ public class ReadOnlyDeltacloudClientLiveTest extends BaseComputeServiceContextL @BeforeClass(groups = { "integration", "live" }) public void setupContext() { super.setupContext(); - client = context.unwrap(DeltacloudApiMetadata.CONTEXT_TOKEN).getApi(); + client = view.unwrap(DeltacloudApiMetadata.CONTEXT_TOKEN).getApi(); socketTester = new RetryablePredicate(new InetSocketAddressConnect(), 180, 1, TimeUnit.SECONDS); stateChanges = ImmutableMap.> of(// Instance.State.RUNNING, new RetryablePredicate(new InstanceRunning(client), 600, 1, diff --git a/apis/deltacloud/src/test/java/org/jclouds/deltacloud/compute/DeltacloudTemplateBuilderLiveTest.java b/apis/deltacloud/src/test/java/org/jclouds/deltacloud/compute/DeltacloudTemplateBuilderLiveTest.java index 4af99e42f0..acbda95347 100644 --- a/apis/deltacloud/src/test/java/org/jclouds/deltacloud/compute/DeltacloudTemplateBuilderLiveTest.java +++ b/apis/deltacloud/src/test/java/org/jclouds/deltacloud/compute/DeltacloudTemplateBuilderLiveTest.java @@ -70,7 +70,7 @@ public class DeltacloudTemplateBuilderLiveTest extends BaseTemplateBuilderLiveTe @Test public void testTemplateBuilder() { - Template defaultTemplate = this.context.getComputeService().templateBuilder().build(); + Template defaultTemplate = this.view.getComputeService().templateBuilder().build(); assertEquals(defaultTemplate.getImage().getOperatingSystem().is64Bit(), true); assertEquals(defaultTemplate.getImage().getOperatingSystem().getVersion(), "10.04"); assertEquals(defaultTemplate.getImage().getOperatingSystem().getFamily(), OsFamily.UBUNTU); diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/EC2ApiMetadata.java b/apis/ec2/src/main/java/org/jclouds/ec2/EC2ApiMetadata.java index 2964886a7b..8a67a39445 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/EC2ApiMetadata.java +++ b/apis/ec2/src/main/java/org/jclouds/ec2/EC2ApiMetadata.java @@ -104,7 +104,7 @@ public class EC2ApiMetadata extends BaseRestApiMetadata { .version(EC2AsyncClient.VERSION) .defaultProperties(EC2ApiMetadata.defaultProperties()) .context(CONTEXT_TOKEN) - .wrapper(EC2ComputeServiceContext.class) + .view(EC2ComputeServiceContext.class) .defaultModules(ImmutableSet.>of(EC2RestClientModule.class, EC2ResolveImagesModule.class, EC2ComputeServiceContextModule.class)); } diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/compute/config/EC2ComputeServiceContextModule.java b/apis/ec2/src/main/java/org/jclouds/ec2/compute/config/EC2ComputeServiceContextModule.java index 6a34b28d5e..dd714a4d0f 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/compute/config/EC2ComputeServiceContextModule.java +++ b/apis/ec2/src/main/java/org/jclouds/ec2/compute/config/EC2ComputeServiceContextModule.java @@ -72,7 +72,7 @@ public class EC2ComputeServiceContextModule extends BaseComputeServiceContextMod } @Override - protected boolean shouldParseImagesOnDemand(Injector injector) { + protected boolean shouldEagerlyParseImages(Injector injector) { // If no owners to query, then will never lookup all images String[] amiOwners = injector.getInstance(Key.get(String[].class, Names.named(PROPERTY_EC2_AMI_OWNERS))); return (amiOwners.length > 0); diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/compute/internal/EC2ComputeServiceContextImpl.java b/apis/ec2/src/main/java/org/jclouds/ec2/compute/internal/EC2ComputeServiceContextImpl.java index b63728b8b1..69099d233d 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/compute/internal/EC2ComputeServiceContextImpl.java +++ b/apis/ec2/src/main/java/org/jclouds/ec2/compute/internal/EC2ComputeServiceContextImpl.java @@ -18,15 +18,12 @@ */ package org.jclouds.ec2.compute.internal; -import java.io.Closeable; -import java.util.Map; - import javax.inject.Inject; import javax.inject.Singleton; +import org.jclouds.Context; import org.jclouds.compute.Utils; import org.jclouds.compute.internal.ComputeServiceContextImpl; -import org.jclouds.domain.Credentials; import org.jclouds.ec2.compute.EC2ComputeService; import org.jclouds.ec2.compute.EC2ComputeServiceContext; import org.jclouds.location.Provider; @@ -39,9 +36,9 @@ import com.google.common.reflect.TypeToken; @Singleton public class EC2ComputeServiceContextImpl extends ComputeServiceContextImpl implements EC2ComputeServiceContext { @Inject - public EC2ComputeServiceContextImpl(@Provider Closeable wrapped, @Provider TypeToken wrappedType, - EC2ComputeService computeService, Map credentialStore, Utils utils){ - super(wrapped, wrappedType, computeService, credentialStore, utils); + public EC2ComputeServiceContextImpl(@Provider Context backend, @Provider TypeToken backendType, + EC2ComputeService computeService, Utils utils) { + super(backend, backendType, computeService, utils); } @Override diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/options/BundleInstanceS3StorageOptions.java b/apis/ec2/src/main/java/org/jclouds/ec2/options/BundleInstanceS3StorageOptions.java index 8c0ea7d5f9..71524c24ff 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/options/BundleInstanceS3StorageOptions.java +++ b/apis/ec2/src/main/java/org/jclouds/ec2/options/BundleInstanceS3StorageOptions.java @@ -20,11 +20,9 @@ package org.jclouds.ec2.options; import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkState; -import static org.jclouds.Constants.PROPERTY_IDENTITY; - -import javax.inject.Named; import org.jclouds.ec2.options.internal.BaseEC2RequestOptions; +import org.jclouds.rest.annotations.Identity; import com.google.common.collect.Multimap; import com.google.inject.Inject; @@ -52,7 +50,7 @@ import com.google.inject.Inject; public class BundleInstanceS3StorageOptions extends BaseEC2RequestOptions { @Inject(optional = true) - @Named(PROPERTY_IDENTITY) + @Identity String currentAwsAccessKeyId; @Override diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/CloudApplicationArchitecturesEC2ClientLiveTest.java b/apis/ec2/src/test/java/org/jclouds/ec2/CloudApplicationArchitecturesEC2ClientLiveTest.java index 1993e42c3a..69e4ef37b4 100644 --- a/apis/ec2/src/test/java/org/jclouds/ec2/CloudApplicationArchitecturesEC2ClientLiveTest.java +++ b/apis/ec2/src/test/java/org/jclouds/ec2/CloudApplicationArchitecturesEC2ClientLiveTest.java @@ -95,7 +95,7 @@ public class CloudApplicationArchitecturesEC2ClientLiveTest extends BaseComputeS @BeforeClass(groups = { "integration", "live" }) public void setupContext() { super.setupContext(); - Injector injector = context.utils().injector(); + Injector injector = view.utils().injector(); client = injector.getInstance(EC2Client.class); sshFactory = injector.getInstance(SshClient.Factory.class); runningTester = new RetryablePredicate(new InstanceStateRunning(client), 180, 5, diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/EBSBootEC2ClientLiveTest.java b/apis/ec2/src/test/java/org/jclouds/ec2/EBSBootEC2ClientLiveTest.java index 87c75162a6..9f6f126bbd 100644 --- a/apis/ec2/src/test/java/org/jclouds/ec2/EBSBootEC2ClientLiveTest.java +++ b/apis/ec2/src/test/java/org/jclouds/ec2/EBSBootEC2ClientLiveTest.java @@ -126,7 +126,7 @@ public class EBSBootEC2ClientLiveTest extends BaseComputeServiceContextLiveTest @BeforeClass(groups = { "integration", "live" }) public void setupContext() { super.setupContext(); - Injector injector = context.utils().injector(); + Injector injector = view.utils().injector(); client = injector.getInstance(EC2Client.class); sshFactory = injector.getInstance(SshClient.Factory.class); SocketOpen socketOpen = injector.getInstance(SocketOpen.class); diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/compute/EC2ComputeServiceLiveTest.java b/apis/ec2/src/test/java/org/jclouds/ec2/compute/EC2ComputeServiceLiveTest.java index 500a0b0786..cb8fa386ff 100644 --- a/apis/ec2/src/test/java/org/jclouds/ec2/compute/EC2ComputeServiceLiveTest.java +++ b/apis/ec2/src/test/java/org/jclouds/ec2/compute/EC2ComputeServiceLiveTest.java @@ -102,13 +102,13 @@ public class EC2ComputeServiceLiveTest extends BaseComputeServiceLiveTest { @Test(enabled = true, dependsOnMethods = "testCompareSizes") public void testExtendedOptionsAndLogin() throws Exception { - SecurityGroupClient securityGroupClient = EC2Client.class.cast(context.unwrap(EC2ApiMetadata.CONTEXT_TOKEN).getApi()) + SecurityGroupClient securityGroupClient = EC2Client.class.cast(view.unwrap(EC2ApiMetadata.CONTEXT_TOKEN).getApi()) .getSecurityGroupServices(); - KeyPairClient keyPairClient = EC2Client.class.cast(context.unwrap(EC2ApiMetadata.CONTEXT_TOKEN).getApi()) + KeyPairClient keyPairClient = EC2Client.class.cast(view.unwrap(EC2ApiMetadata.CONTEXT_TOKEN).getApi()) .getKeyPairServices(); - InstanceClient instanceClient = EC2Client.class.cast(context.unwrap(EC2ApiMetadata.CONTEXT_TOKEN).getApi()) + InstanceClient instanceClient = EC2Client.class.cast(view.unwrap(EC2ApiMetadata.CONTEXT_TOKEN).getApi()) .getInstanceServices(); String group = this.group + "o"; @@ -181,7 +181,7 @@ public class EC2ComputeServiceLiveTest extends BaseComputeServiceLiveTest { Properties overrides = setupProperties(); overrides.setProperty(EC2Constants.PROPERTY_EC2_AUTO_ALLOCATE_ELASTIC_IPS, "true"); - context = createContext(overrides, setupModules()); + context = createView(overrides, setupModules()); // create a node Set nodes = @@ -233,19 +233,19 @@ public class EC2ComputeServiceLiveTest extends BaseComputeServiceLiveTest { @Test(enabled = true) public void testMapEBS() throws Exception { - InstanceClient instanceClient = EC2Client.class.cast(context.unwrap(EC2ApiMetadata.CONTEXT_TOKEN).getApi()) + InstanceClient instanceClient = EC2Client.class.cast(view.unwrap(EC2ApiMetadata.CONTEXT_TOKEN).getApi()) .getInstanceServices(); - ElasticBlockStoreClient ebsClient = EC2Client.class.cast(context.unwrap(EC2ApiMetadata.CONTEXT_TOKEN).getApi()) + ElasticBlockStoreClient ebsClient = EC2Client.class.cast(view.unwrap(EC2ApiMetadata.CONTEXT_TOKEN).getApi()) .getElasticBlockStoreServices(); String group = this.group + "e"; int volumeSize = 8; - final Template template = context.getComputeService().templateBuilder().hardwareId(InstanceType.M1_SMALL) + final Template template = view.getComputeService().templateBuilder().hardwareId(InstanceType.M1_SMALL) .osFamily(OsFamily.UBUNTU).osVersionMatches("10.04").imageDescriptionMatches(".*ebs.*").build(); - Location zone = Iterables.find(context.getComputeService().listAssignableLocations(), new Predicate() { + Location zone = Iterables.find(view.getComputeService().listAssignableLocations(), new Predicate() { @Override public boolean apply(Location arg0) { diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/compute/EC2TemplateBuilderLiveTest.java b/apis/ec2/src/test/java/org/jclouds/ec2/compute/EC2TemplateBuilderLiveTest.java index dafe81fc4b..7e5e09f875 100644 --- a/apis/ec2/src/test/java/org/jclouds/ec2/compute/EC2TemplateBuilderLiveTest.java +++ b/apis/ec2/src/test/java/org/jclouds/ec2/compute/EC2TemplateBuilderLiveTest.java @@ -50,7 +50,7 @@ public abstract class EC2TemplateBuilderLiveTest extends BaseTemplateBuilderLive @Test public void testTemplateBuilderCanUseImageIdWithoutFetchingAllImages() throws Exception { - Template defaultTemplate = context.getComputeService().templateBuilder().build(); + Template defaultTemplate = view.getComputeService().templateBuilder().build(); String defaultImageId = defaultTemplate.getImage().getId(); String defaultImageProviderId = defaultTemplate.getImage().getProviderId(); @@ -58,7 +58,7 @@ public abstract class EC2TemplateBuilderLiveTest extends BaseTemplateBuilderLive try { // Track http commands final List commandsInvoked = Lists.newArrayList(); - context = createContext( + context = createView( setupProperties(), ImmutableSet. of(new Log4JLoggingModule(), TrackingJavaUrlHttpCommandExecutorService.newTrackingModule(commandsInvoked))); diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/compute/TestCanRecreateGroupLiveTest.java b/apis/ec2/src/test/java/org/jclouds/ec2/compute/TestCanRecreateGroupLiveTest.java index fc7ca34a97..3856ed28c5 100644 --- a/apis/ec2/src/test/java/org/jclouds/ec2/compute/TestCanRecreateGroupLiveTest.java +++ b/apis/ec2/src/test/java/org/jclouds/ec2/compute/TestCanRecreateGroupLiveTest.java @@ -39,18 +39,18 @@ public class TestCanRecreateGroupLiveTest extends BaseComputeServiceContextLiveT public void testCanRecreateGroup() throws Exception { String tag = PREFIX + "recreate"; - context.getComputeService().destroyNodesMatching(NodePredicates.inGroup(tag)); + view.getComputeService().destroyNodesMatching(NodePredicates.inGroup(tag)); try { - Template template = context.getComputeService().templateBuilder().build(); - context.getComputeService().createNodesInGroup(tag, 1, template); - context.getComputeService().destroyNodesMatching(NodePredicates.inGroup(tag)); - context.getComputeService().createNodesInGroup(tag, 1, template); + Template template = view.getComputeService().templateBuilder().build(); + view.getComputeService().createNodesInGroup(tag, 1, template); + view.getComputeService().destroyNodesMatching(NodePredicates.inGroup(tag)); + view.getComputeService().createNodesInGroup(tag, 1, template); } catch (RunNodesException e) { System.err.println(e.getNodeErrors().keySet()); Throwables.propagate(e); } finally { - context.getComputeService().destroyNodesMatching(NodePredicates.inGroup(tag)); + view.getComputeService().destroyNodesMatching(NodePredicates.inGroup(tag)); } } diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/services/AvailabilityZoneAndRegionClientLiveTest.java b/apis/ec2/src/test/java/org/jclouds/ec2/services/AvailabilityZoneAndRegionClientLiveTest.java index 80dbaf4d1c..64b3b695f7 100644 --- a/apis/ec2/src/test/java/org/jclouds/ec2/services/AvailabilityZoneAndRegionClientLiveTest.java +++ b/apis/ec2/src/test/java/org/jclouds/ec2/services/AvailabilityZoneAndRegionClientLiveTest.java @@ -56,7 +56,7 @@ public class AvailabilityZoneAndRegionClientLiveTest extends BaseComputeServiceC @BeforeClass(groups = { "integration", "live" }) public void setupContext() { super.setupContext(); - client = context.unwrap(EC2ApiMetadata.CONTEXT_TOKEN).getApi().getAvailabilityZoneAndRegionServices(); + client = view.unwrap(EC2ApiMetadata.CONTEXT_TOKEN).getApi().getAvailabilityZoneAndRegionServices(); } public void testDescribeAvailabilityZones() { diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/services/ElasticBlockStoreClientLiveTest.java b/apis/ec2/src/test/java/org/jclouds/ec2/services/ElasticBlockStoreClientLiveTest.java index 4fd9676cec..b2618f72c9 100644 --- a/apis/ec2/src/test/java/org/jclouds/ec2/services/ElasticBlockStoreClientLiveTest.java +++ b/apis/ec2/src/test/java/org/jclouds/ec2/services/ElasticBlockStoreClientLiveTest.java @@ -61,12 +61,12 @@ public class ElasticBlockStoreClientLiveTest extends BaseComputeServiceContextLi @BeforeClass(groups = { "integration", "live" }) public void setupContext() { super.setupContext(); - client = context.unwrap(EC2ApiMetadata.CONTEXT_TOKEN).getApi().getElasticBlockStoreServices(); + client = view.unwrap(EC2ApiMetadata.CONTEXT_TOKEN).getApi().getElasticBlockStoreServices(); } @Test void testDescribeVolumes() { - for (String region : context.unwrap(EC2ApiMetadata.CONTEXT_TOKEN).getApi().getAvailabilityZoneAndRegionServices().describeRegions().keySet()) { + for (String region : view.unwrap(EC2ApiMetadata.CONTEXT_TOKEN).getApi().getAvailabilityZoneAndRegionServices().describeRegions().keySet()) { SortedSet allResults = Sets.newTreeSet(client.describeVolumesInRegion(region)); assertNotNull(allResults); if (allResults.size() >= 1) { diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/services/ElasticIPAddressClientLiveTest.java b/apis/ec2/src/test/java/org/jclouds/ec2/services/ElasticIPAddressClientLiveTest.java index 83bb5c4503..e353312235 100644 --- a/apis/ec2/src/test/java/org/jclouds/ec2/services/ElasticIPAddressClientLiveTest.java +++ b/apis/ec2/src/test/java/org/jclouds/ec2/services/ElasticIPAddressClientLiveTest.java @@ -50,7 +50,7 @@ public class ElasticIPAddressClientLiveTest extends BaseComputeServiceContextLiv @BeforeClass(groups = { "integration", "live" }) public void setupContext() { super.setupContext(); - client = context.unwrap(EC2ApiMetadata.CONTEXT_TOKEN).getApi().getElasticIPAddressServices(); + client = view.unwrap(EC2ApiMetadata.CONTEXT_TOKEN).getApi().getElasticIPAddressServices(); } @Test diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/services/InstanceClientLiveTest.java b/apis/ec2/src/test/java/org/jclouds/ec2/services/InstanceClientLiveTest.java index d44b224082..dbc4fff096 100644 --- a/apis/ec2/src/test/java/org/jclouds/ec2/services/InstanceClientLiveTest.java +++ b/apis/ec2/src/test/java/org/jclouds/ec2/services/InstanceClientLiveTest.java @@ -49,7 +49,7 @@ public class InstanceClientLiveTest extends BaseComputeServiceContextLiveTest { @BeforeClass(groups = { "integration", "live" }) public void setupContext() { super.setupContext(); - client = context.unwrap(EC2ApiMetadata.CONTEXT_TOKEN).getApi().getInstanceServices(); + client = view.unwrap(EC2ApiMetadata.CONTEXT_TOKEN).getApi().getInstanceServices(); } @Test diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/services/KeyPairClientLiveTest.java b/apis/ec2/src/test/java/org/jclouds/ec2/services/KeyPairClientLiveTest.java index cd5287b7af..5bb966d0a1 100644 --- a/apis/ec2/src/test/java/org/jclouds/ec2/services/KeyPairClientLiveTest.java +++ b/apis/ec2/src/test/java/org/jclouds/ec2/services/KeyPairClientLiveTest.java @@ -51,7 +51,7 @@ public class KeyPairClientLiveTest extends BaseComputeServiceContextLiveTest { @BeforeClass(groups = { "integration", "live" }) public void setupContext() { super.setupContext(); - client = context.unwrap(EC2ApiMetadata.CONTEXT_TOKEN).getApi().getKeyPairServices(); + client = view.unwrap(EC2ApiMetadata.CONTEXT_TOKEN).getApi().getKeyPairServices(); } @Test diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/services/SecurityGroupClientLiveTest.java b/apis/ec2/src/test/java/org/jclouds/ec2/services/SecurityGroupClientLiveTest.java index d4b623c7e5..369118a1e9 100644 --- a/apis/ec2/src/test/java/org/jclouds/ec2/services/SecurityGroupClientLiveTest.java +++ b/apis/ec2/src/test/java/org/jclouds/ec2/services/SecurityGroupClientLiveTest.java @@ -60,7 +60,7 @@ public class SecurityGroupClientLiveTest extends BaseComputeServiceContextLiveTe @BeforeClass(groups = { "integration", "live" }) public void setupContext() { super.setupContext(); - client = context.unwrap(EC2ApiMetadata.CONTEXT_TOKEN).getApi().getSecurityGroupServices(); + client = view.unwrap(EC2ApiMetadata.CONTEXT_TOKEN).getApi().getSecurityGroupServices(); } @Test @@ -281,6 +281,6 @@ public class SecurityGroupClientLiveTest extends BaseComputeServiceContextLiveTe @AfterTest public void shutdown() { - context.close(); + view.close(); } } diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/services/WindowsClientLiveTest.java b/apis/ec2/src/test/java/org/jclouds/ec2/services/WindowsClientLiveTest.java index c877fbae7c..0b7cecc82b 100644 --- a/apis/ec2/src/test/java/org/jclouds/ec2/services/WindowsClientLiveTest.java +++ b/apis/ec2/src/test/java/org/jclouds/ec2/services/WindowsClientLiveTest.java @@ -76,8 +76,8 @@ public class WindowsClientLiveTest extends BaseComputeServiceContextLiveTest { @BeforeClass(groups = { "integration", "live" }) public void setupContext() { super.setupContext(); - client = context.unwrap(EC2ApiMetadata.CONTEXT_TOKEN).getApi().getWindowsServices(); - computeService = context.getComputeService(); + client = view.unwrap(EC2ApiMetadata.CONTEXT_TOKEN).getApi().getWindowsServices(); + computeService = view.getComputeService(); } @@ -141,7 +141,7 @@ public class WindowsClientLiveTest extends BaseComputeServiceContextLiveTest { node.getCredentials().getPrivateKey()); // And apply it to the decryption function - WindowsLoginCredentialsFromEncryptedData f = context.getUtils().getInjector().getInstance(WindowsLoginCredentialsFromEncryptedData.class); + WindowsLoginCredentialsFromEncryptedData f = view.getUtils().getInjector().getInstance(WindowsLoginCredentialsFromEncryptedData.class); LoginCredentials credentials = f.apply(dataAndKey); assertEquals(credentials.getUser(), "Administrator"); diff --git a/apis/elasticstack/src/main/java/org/jclouds/elasticstack/ElasticStackApiMetadata.java b/apis/elasticstack/src/main/java/org/jclouds/elasticstack/ElasticStackApiMetadata.java index c76b0cf3d0..847e05cc0d 100644 --- a/apis/elasticstack/src/main/java/org/jclouds/elasticstack/ElasticStackApiMetadata.java +++ b/apis/elasticstack/src/main/java/org/jclouds/elasticstack/ElasticStackApiMetadata.java @@ -85,7 +85,7 @@ public class ElasticStackApiMetadata extends BaseRestApiMetadata { .version("1.0") .defaultEndpoint("https://api.lon-p.elastichosts.com") .defaultProperties(ElasticStackApiMetadata.defaultProperties()) - .wrapper(TypeToken.of(ComputeServiceContext.class)) + .view(TypeToken.of(ComputeServiceContext.class)) .defaultModules(ImmutableSet.>of(ElasticStackRestClientModule.class, ElasticStackComputeServiceContextModule.class)); } diff --git a/apis/elasticstack/src/test/java/org/jclouds/elasticstack/ElasticStackClientLiveTest.java b/apis/elasticstack/src/test/java/org/jclouds/elasticstack/ElasticStackClientLiveTest.java index 0eb8854bf1..5365d502c7 100644 --- a/apis/elasticstack/src/test/java/org/jclouds/elasticstack/ElasticStackClientLiveTest.java +++ b/apis/elasticstack/src/test/java/org/jclouds/elasticstack/ElasticStackClientLiveTest.java @@ -88,7 +88,7 @@ public class ElasticStackClientLiveTest @Override public void setupContext() { super.setupContext(); - cloudStackContext = context.unwrap(); + cloudStackContext = view.unwrap(); client = cloudStackContext.getApi(); driveNotClaimed = new RetryablePredicate(Predicates.not(new DriveClaimed(client)), maxDriveImageTime, @@ -97,7 +97,7 @@ public class ElasticStackClientLiveTest TimeUnit.SECONDS); if (Strings.emptyToNull(imageId) == null) { - imageId = context.getComputeService().templateBuilder().build().getImage().getId(); + imageId = view.getComputeService().templateBuilder().build().getImage().getId(); } } diff --git a/apis/filesystem/src/main/java/org/jclouds/filesystem/FilesystemApiMetadata.java b/apis/filesystem/src/main/java/org/jclouds/filesystem/FilesystemApiMetadata.java index 3ea463e4f9..fc5425fd38 100644 --- a/apis/filesystem/src/main/java/org/jclouds/filesystem/FilesystemApiMetadata.java +++ b/apis/filesystem/src/main/java/org/jclouds/filesystem/FilesystemApiMetadata.java @@ -63,7 +63,7 @@ public class FilesystemApiMetadata extends BaseApiMetadata { .defaultCredential("bar") .version("1") .documentation(URI.create("http://www.jclouds.org/documentation/userguide/blobstore-guide")) - .wrapper(BlobStoreContext.class) + .view(BlobStoreContext.class) .defaultModule(FilesystemBlobStoreContextModule.class); } diff --git a/apis/filesystem/src/test/java/org/jclouds/filesystem/FilesystemAsyncBlobStoreTest.java b/apis/filesystem/src/test/java/org/jclouds/filesystem/FilesystemAsyncBlobStoreTest.java index e9f6b3cbb5..0045df0be7 100644 --- a/apis/filesystem/src/test/java/org/jclouds/filesystem/FilesystemAsyncBlobStoreTest.java +++ b/apis/filesystem/src/test/java/org/jclouds/filesystem/FilesystemAsyncBlobStoreTest.java @@ -131,7 +131,7 @@ public class FilesystemAsyncBlobStoreTest { // no base directory declared in properties try { Properties props = new Properties(); - context = ContextBuilder.newBuilder(PROVIDER).overrides(props).build(); + context = ContextBuilder.newBuilder(PROVIDER).overrides(props).build(BlobStoreContext.class); fail("No error if base directory is not specified"); } catch (CreationException e) { } @@ -140,7 +140,7 @@ public class FilesystemAsyncBlobStoreTest { try { Properties props = new Properties(); props.setProperty(FilesystemConstants.PROPERTY_BASEDIR, null); - context = ContextBuilder.newBuilder(PROVIDER).overrides(props).build(); + context = ContextBuilder.newBuilder(PROVIDER).overrides(props).build(BlobStoreContext.class); fail("No error if base directory is null in the option"); } catch (NullPointerException e) { } diff --git a/apis/filesystem/src/test/java/org/jclouds/filesystem/integration/FilesystemContainerIntegrationTestDisabled.java b/apis/filesystem/src/test/java/org/jclouds/filesystem/integration/FilesystemContainerIntegrationTestDisabled.java index 4950969167..2b8aeed82a 100644 --- a/apis/filesystem/src/test/java/org/jclouds/filesystem/integration/FilesystemContainerIntegrationTestDisabled.java +++ b/apis/filesystem/src/test/java/org/jclouds/filesystem/integration/FilesystemContainerIntegrationTestDisabled.java @@ -62,14 +62,14 @@ public class FilesystemContainerIntegrationTestDisabled extends BaseContainerInt // NOTE all metadata in jclouds comes out as lowercase, in an effort to normalize the // providers. - Blob object = context.getBlobStore().blobBuilder(key).userMetadata(ImmutableMap.of("Adrian", "powderpuff")) + Blob object = view.getBlobStore().blobBuilder(key).userMetadata(ImmutableMap.of("Adrian", "powderpuff")) .payload(TEST_STRING).contentType(MediaType.TEXT_PLAIN).build(); String containerName = getContainerName(); try { addBlobToContainer(containerName, object); validateContent(containerName, key); - PageSet container = context.getBlobStore().list(containerName, maxResults(1)); + PageSet container = view.getBlobStore().list(containerName, maxResults(1)); BlobMetadata metadata = (BlobMetadata) Iterables.getOnlyElement(container); // transient container should be lenient and not return metadata on undetailed listing. diff --git a/apis/nova/src/main/java/org/jclouds/openstack/nova/NovaApiMetadata.java b/apis/nova/src/main/java/org/jclouds/openstack/nova/NovaApiMetadata.java index 60540982d9..86d34c8ac7 100644 --- a/apis/nova/src/main/java/org/jclouds/openstack/nova/NovaApiMetadata.java +++ b/apis/nova/src/main/java/org/jclouds/openstack/nova/NovaApiMetadata.java @@ -76,7 +76,7 @@ public class NovaApiMetadata extends BaseRestApiMetadata { .version("1.1") .defaultEndpoint("http://localhost:5000") .defaultProperties(NovaApiMetadata.defaultProperties()) - .wrapper(TypeToken.of(ComputeServiceContext.class)) + .view(TypeToken.of(ComputeServiceContext.class)) .defaultModules(ImmutableSet.>of(NovaRestClientModule.class, NovaComputeServiceContextModule.class)); } diff --git a/apis/nova/src/main/java/org/jclouds/openstack/nova/NovaAsyncClient.java b/apis/nova/src/main/java/org/jclouds/openstack/nova/NovaAsyncClient.java index 2fbfa44b0f..6096ec6ba8 100644 --- a/apis/nova/src/main/java/org/jclouds/openstack/nova/NovaAsyncClient.java +++ b/apis/nova/src/main/java/org/jclouds/openstack/nova/NovaAsyncClient.java @@ -62,7 +62,7 @@ import com.google.common.util.concurrent.ListenableFuture; * Provides asynchronous access to OpenStack Nova via their REST API. *

* All commands return a ListenableFuture of the result from OpenStack Nova. Any exceptions incurred - * during processing will be wrapped in an {@link ExecutionException} as documented in + * during processing will be backend in an {@link ExecutionException} as documented in * {@link ListenableFuture#get()}. * * @author Adrian Cole diff --git a/apis/nova/src/main/java/org/jclouds/openstack/nova/NovaClient.java b/apis/nova/src/main/java/org/jclouds/openstack/nova/NovaClient.java index 62f76adc67..9ce05aff95 100644 --- a/apis/nova/src/main/java/org/jclouds/openstack/nova/NovaClient.java +++ b/apis/nova/src/main/java/org/jclouds/openstack/nova/NovaClient.java @@ -40,7 +40,7 @@ import org.jclouds.rest.ResourceNotFoundException; * Provides access to OpenStack Nova via their REST API. *

* All commands return a Future of the result from OpenStack Nova. Any exceptions incurred - * during processing will be wrapped in an {@link ExecutionException} as documented in + * during processing will be backend in an {@link ExecutionException} as documented in * {@link Future#get()}. * * @see NovaAsyncClient diff --git a/apis/nova/src/test/java/org/jclouds/openstack/nova/NovaClientLiveTest.java b/apis/nova/src/test/java/org/jclouds/openstack/nova/NovaClientLiveTest.java index 117e97c726..ccbdeb509d 100644 --- a/apis/nova/src/test/java/org/jclouds/openstack/nova/NovaClientLiveTest.java +++ b/apis/nova/src/test/java/org/jclouds/openstack/nova/NovaClientLiveTest.java @@ -78,7 +78,7 @@ public class NovaClientLiveTest extends BaseComputeServiceContextLiveTest { @Override public void setupContext() { super.setupContext(); - Injector injector = context.utils().injector(); + Injector injector = view.utils().injector(); client = injector.getInstance(NovaClient.class); sshFactory = injector.getInstance(SshClient.Factory.class); SocketOpen socketOpen = injector.getInstance(SocketOpen.class); diff --git a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/NovaApiMetadata.java b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/NovaApiMetadata.java index de321c2366..efe4e7a773 100644 --- a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/NovaApiMetadata.java +++ b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/NovaApiMetadata.java @@ -94,7 +94,7 @@ public class NovaApiMetadata extends BaseRestApiMetadata { .version("1.1") .defaultEndpoint("http://localhost:5000") .defaultProperties(NovaApiMetadata.defaultProperties()) - .wrapper(TypeToken.of(ComputeServiceContext.class)) + .view(TypeToken.of(ComputeServiceContext.class)) .defaultModules(ImmutableSet.>of(NovaRestClientModule.class, NovaComputeServiceContextModule.class)); } diff --git a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/NovaAsyncClient.java b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/NovaAsyncClient.java index cb8a4864df..da9d6507b5 100644 --- a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/NovaAsyncClient.java +++ b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/NovaAsyncClient.java @@ -24,8 +24,10 @@ import org.jclouds.javax.annotation.Nullable; import org.jclouds.location.Zone; import org.jclouds.location.functions.ZoneToEndpoint; import org.jclouds.openstack.nova.v1_1.extensions.FloatingIPAsyncClient; +import org.jclouds.openstack.nova.v1_1.extensions.HostAdministrationAsyncClient; import org.jclouds.openstack.nova.v1_1.extensions.KeyPairAsyncClient; import org.jclouds.openstack.nova.v1_1.extensions.SecurityGroupAsyncClient; +import org.jclouds.openstack.nova.v1_1.extensions.SimpleTenantUsageAsyncClient; import org.jclouds.openstack.nova.v1_1.features.ExtensionAsyncClient; import org.jclouds.openstack.nova.v1_1.features.FlavorAsyncClient; import org.jclouds.openstack.nova.v1_1.features.ImageAsyncClient; @@ -103,4 +105,19 @@ public interface NovaAsyncClient { @Delegate Optional getKeyPairExtensionForZone( @EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone); + + /** + * Provides asynchronous access to Host Administration features. + */ + @Delegate + Optional getHostAdministrationExtensionForZone( + @EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone); + + /** + * Provides asynchronous access to Simple Tenant Usage features. + */ + @Delegate + Optional getSimpleTenantUsageExtensionForZone( + @EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone); + } diff --git a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/NovaClient.java b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/NovaClient.java index 65725174da..d33e0ab91b 100644 --- a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/NovaClient.java +++ b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/NovaClient.java @@ -26,8 +26,10 @@ import org.jclouds.javax.annotation.Nullable; import org.jclouds.location.Zone; import org.jclouds.location.functions.ZoneToEndpoint; import org.jclouds.openstack.nova.v1_1.extensions.FloatingIPClient; +import org.jclouds.openstack.nova.v1_1.extensions.HostAdministrationClient; import org.jclouds.openstack.nova.v1_1.extensions.KeyPairClient; import org.jclouds.openstack.nova.v1_1.extensions.SecurityGroupClient; +import org.jclouds.openstack.nova.v1_1.extensions.SimpleTenantUsageClient; import org.jclouds.openstack.nova.v1_1.features.ExtensionClient; import org.jclouds.openstack.nova.v1_1.features.FlavorClient; import org.jclouds.openstack.nova.v1_1.features.ImageClient; @@ -106,4 +108,18 @@ public interface NovaClient { Optional getKeyPairExtensionForZone( @EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone); + /** + * Provides synchronous access to Host Administration features. + */ + @Delegate + Optional getHostAdministrationExtensionForZone( + @EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone); + + /** + * Provides synchronous access to Simple Tenant Usage features. + */ + @Delegate + Optional getSimpleTenantUsageExtensionForZone( + @EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone); + } diff --git a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/compute/NovaComputeService.java b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/compute/NovaComputeService.java index f95732648a..0481a1bf09 100644 --- a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/compute/NovaComputeService.java +++ b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/compute/NovaComputeService.java @@ -151,8 +151,8 @@ public class NovaComputeService extends BaseComputeService { Optional keyPairClient = novaClient.getKeyPairExtensionForZone(zoneId); if (keyPairClient.isPresent()) { for (String group : groups) { - for (Map wrapper : keyPairClient.get().listKeyPairs()) { - for (KeyPair pair : Iterables.filter(wrapper.values(), + for (Map view : keyPairClient.get().listKeyPairs()) { + for (KeyPair pair : Iterables.filter(view.values(), KeyPairPredicates.nameMatches(namingConvention.create().containsGroup(group)))) { ZoneAndName zoneAndName = ZoneAndName.fromZoneAndName(zoneId, pair.getName()); logger.debug(">> deleting keypair(%s)", zoneAndName); diff --git a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/config/NovaParserModule.java b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/config/NovaParserModule.java index 63209fb4f0..dbe79c90a0 100644 --- a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/config/NovaParserModule.java +++ b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/config/NovaParserModule.java @@ -25,8 +25,15 @@ import javax.inject.Singleton; import org.jclouds.json.config.GsonModule; import org.jclouds.json.config.GsonModule.DateAdapter; +import org.jclouds.openstack.nova.v1_1.domain.HostResourceUsage; import com.google.common.collect.ImmutableMap; +import com.google.gson.JsonDeserializationContext; +import com.google.gson.JsonDeserializer; +import com.google.gson.JsonElement; +import com.google.gson.JsonParseException; +import com.google.gson.JsonSerializationContext; +import com.google.gson.JsonSerializer; import com.google.inject.AbstractModule; import com.google.inject.Provides; @@ -38,7 +45,7 @@ public class NovaParserModule extends AbstractModule { @Provides @Singleton public Map provideCustomAdapterBindings() { - return ImmutableMap. of(); + return ImmutableMap. of(HostResourceUsage.class, new HostResourceUsageAdapter()); } @Override @@ -46,4 +53,30 @@ public class NovaParserModule extends AbstractModule { bind(DateAdapter.class).to(GsonModule.Iso8601DateAdapter.class); } + @Singleton + public static class HostResourceUsageAdapter implements JsonSerializer, JsonDeserializer { + public HostResourceUsage apply(HostResourceUsageView in) { + return in.resource.toBuilder().build(); + } + + @Override + public HostResourceUsage deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext context) throws JsonParseException { + return apply((HostResourceUsageView) context.deserialize(jsonElement, HostResourceUsageView.class)); + } + + @Override + public JsonElement serialize(HostResourceUsage hostResourceUsage, Type type, JsonSerializationContext context) { + return context.serialize(hostResourceUsage); + } + + private static class HostResourceUsageView { + protected HostResourceUsageInternal resource; + } + private static class HostResourceUsageInternal extends HostResourceUsage { + protected HostResourceUsageInternal(Builder builder) { + super(builder); + } + } + } + } diff --git a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/config/NovaRestClientModule.java b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/config/NovaRestClientModule.java index c9f603d178..fdb3b039a8 100644 --- a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/config/NovaRestClientModule.java +++ b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/config/NovaRestClientModule.java @@ -35,12 +35,7 @@ import org.jclouds.openstack.keystone.v2_0.config.KeystoneAuthenticationModule; import org.jclouds.openstack.nova.v1_1.NovaAsyncClient; import org.jclouds.openstack.nova.v1_1.NovaClient; import org.jclouds.openstack.nova.v1_1.domain.Extension; -import org.jclouds.openstack.nova.v1_1.extensions.FloatingIPAsyncClient; -import org.jclouds.openstack.nova.v1_1.extensions.FloatingIPClient; -import org.jclouds.openstack.nova.v1_1.extensions.KeyPairAsyncClient; -import org.jclouds.openstack.nova.v1_1.extensions.KeyPairClient; -import org.jclouds.openstack.nova.v1_1.extensions.SecurityGroupAsyncClient; -import org.jclouds.openstack.nova.v1_1.extensions.SecurityGroupClient; +import org.jclouds.openstack.nova.v1_1.extensions.*; import org.jclouds.openstack.nova.v1_1.features.ExtensionAsyncClient; import org.jclouds.openstack.nova.v1_1.features.ExtensionClient; import org.jclouds.openstack.nova.v1_1.features.FlavorAsyncClient; @@ -75,7 +70,10 @@ public class NovaRestClientModule extends RestClientModule builder() { + return new ConcreteBuilder(); + } + + public Builder toBuilder() { + return new ConcreteBuilder().fromHost(this); + } + + public static abstract class Builder> { + protected abstract T self(); + + private String name; + private String service; + + public T name(String name) { + this.name = name; + return self(); + } + + public T service(String service) { + this.service = service; + return self(); + } + + public Host build() { + return new Host(this); + } + + public T fromHost(Host in) { + return this + .name(in.getName()) + .service(in.getService()) + ; + } + + } + + private static class ConcreteBuilder extends Builder { + @Override + protected ConcreteBuilder self() { + return this; + } + } + + @SerializedName(value="host_name") + private final String name; + private final String service; + + protected Host(Builder builder) { + this.name = builder.name; + this.service = builder.service; + } + + /** + */ + @Nullable + public String getName() { + return this.name; + } + + /** + */ + @Nullable + public String getService() { + return this.service; + } + + @Override + public int hashCode() { + return Objects.hashCode(name, service); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (obj == null || getClass() != obj.getClass()) return false; + Host that = Host.class.cast(obj); + return Objects.equal(this.name, that.name) + && Objects.equal(this.service, that.service) + ; + } + + protected ToStringHelper string() { + return Objects.toStringHelper("") + .add("name", name) + .add("service", service) + ; + } + + @Override + public String toString() { + return string().toString(); + } + +} \ No newline at end of file diff --git a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/domain/HostResourceUsage.java b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/domain/HostResourceUsage.java new file mode 100644 index 0000000000..e8dbbd1301 --- /dev/null +++ b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/domain/HostResourceUsage.java @@ -0,0 +1,177 @@ +/** + * 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.openstack.nova.v1_1.domain; + +import static com.google.common.base.Preconditions.checkNotNull; + +import org.jclouds.javax.annotation.Nullable; + +import com.google.common.base.Objects; +import com.google.common.base.Objects.ToStringHelper; +import com.google.gson.annotations.SerializedName; + +/** + * Class HostResourceUsage + */ +public class HostResourceUsage { + + public static Builder builder() { + return new ConcreteBuilder(); + } + + public Builder toBuilder() { + return new ConcreteBuilder().fromHostResourceUsage(this); + } + + public static abstract class Builder> { + protected abstract T self(); + + private String host; + private String project; + private int memoryMb; + private int cpu; + private int diskGb; + + public T host(String host) { + this.host = host; + return self(); + } + + public T project(String project) { + this.project = project; + return self(); + } + + public T memoryMb(int memoryMb) { + this.memoryMb = memoryMb; + return self(); + } + + public T cpu(int cpu) { + this.cpu = cpu; + return self(); + } + + public T diskGb(int diskGb) { + this.diskGb = diskGb; + return self(); + } + + public HostResourceUsage build() { + return new HostResourceUsage(this); + } + + public T fromHostResourceUsage(HostResourceUsage in) { + return this + .host(in.getHost()) + .project(in.getProject()) + .memoryMb(in.getMemoryMb()) + .cpu(in.getCpu()) + .diskGb(in.getDiskGb()) + ; + } + + } + + private static class ConcreteBuilder extends Builder { + @Override + protected ConcreteBuilder self() { + return this; + } + } + + private final String host; + private final String project; + @SerializedName(value="memory_mb") + private final int memoryMb; + private final int cpu; + @SerializedName(value="disk_gb") + private final int diskGb; + + protected HostResourceUsage(Builder builder) { + this.host = checkNotNull(builder.host, "host"); + this.project = builder.project; + this.memoryMb = checkNotNull(builder.memoryMb, "memoryMb"); + this.cpu = checkNotNull(builder.cpu, "cpu"); + this.diskGb = checkNotNull(builder.diskGb, "diskGb"); + } + + /** + */ + public String getHost() { + return this.host; + } + + /** + */ + @Nullable + public String getProject() { + return this.project; + } + + /** + */ + public int getMemoryMb() { + return this.memoryMb; + } + + /** + */ + public int getCpu() { + return this.cpu; + } + + /** + */ + public int getDiskGb() { + return this.diskGb; + } + + @Override + public int hashCode() { + return Objects.hashCode(host, project, memoryMb, cpu, diskGb); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (obj == null || getClass() != obj.getClass()) return false; + HostResourceUsage that = HostResourceUsage.class.cast(obj); + return Objects.equal(this.host, that.host) + && Objects.equal(this.project, that.project) + && Objects.equal(this.memoryMb, that.memoryMb) + && Objects.equal(this.cpu, that.cpu) + && Objects.equal(this.diskGb, that.diskGb); + } + + protected ToStringHelper string() { + return Objects.toStringHelper("") + .add("host", host) + .add("project", project) + .add("memoryMb", memoryMb) + .add("cpu", cpu) + .add("diskGb", diskGb); + } + + @Override + public String toString() { + return string().toString(); + } + +} \ No newline at end of file diff --git a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/domain/SimpleServerUsage.java b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/domain/SimpleServerUsage.java new file mode 100644 index 0000000000..c199924b61 --- /dev/null +++ b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/domain/SimpleServerUsage.java @@ -0,0 +1,302 @@ +/** + * 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.openstack.nova.v1_1.domain; + +import static com.google.common.base.Preconditions.checkNotNull; + +import java.util.Date; + +import org.jclouds.javax.annotation.Nullable; + +import com.google.common.base.Objects; +import com.google.common.base.Objects.ToStringHelper; +import com.google.gson.annotations.SerializedName; + +/** + * Information the SimpleTenantUsage extension return data about each Server + * + * @author Adam Lowe + */ +public class SimpleServerUsage { + + public static enum Status { + + UNRECOGNIZED, ACTIVE; + + public String value() { + return name(); + } + + public static Status fromValue(String v) { + try { + return valueOf(v.toUpperCase()); + } catch (IllegalArgumentException e) { + return UNRECOGNIZED; + } + } + + } + + public static Builder builder() { + return new ConcreteBuilder(); + } + + public Builder toBuilder() { + return new ConcreteBuilder().fromSimpleServerUsage(this); + } + + public static abstract class Builder> { + private String instanceName; + private double hours; + private double flavorMemoryMb; + private double flavorLocalGb; + private double flavorVcpus; + private String tenantId; + private String flavorName; + private Date instanceCreated; + private Date instanceTerminiated; + private Status instanceStatus; + private long uptime; + + protected abstract T self(); + + public T instanceName(String instanceName) { + this.instanceName = instanceName; + return self(); + } + + public T hours(double hours) { + this.hours = hours; + return self(); + } + + public T flavorMemoryMb(double flavorMemoryMb) { + this.flavorMemoryMb = flavorMemoryMb; + return self(); + } + + public T flavorLocalGb(double flavorLocalGb) { + this.flavorLocalGb = flavorLocalGb; + return self(); + } + + public T flavorVcpus(double flavorVcpus) { + this.flavorVcpus = flavorVcpus; + return self(); + } + + public T tenantId(String tenantId) { + this.tenantId = tenantId; + return self(); + } + + public T flavorName(String flavorName) { + this.flavorName = flavorName; + return self(); + } + + public T instanceCreated(Date instanceCreated) { + this.instanceCreated = instanceCreated; + return self(); + } + + public T instanceTerminiated(Date instanceTerminiated) { + this.instanceTerminiated = instanceTerminiated; + return self(); + } + + public T instanceStatus(Status instanceStatus) { + this.instanceStatus = instanceStatus; + return self(); + } + + public T uptime(long uptime) { + this.uptime = uptime; + return self(); + } + + public SimpleServerUsage build() { + return new SimpleServerUsage(this); + } + + + public T fromSimpleServerUsage(SimpleServerUsage in) { + return this + .instanceName(in.getInstanceName()) + .flavorMemoryMb(in.getFlavorMemoryMb()) + .flavorLocalGb(in.getFlavorLocalGb()) + .flavorVcpus(in.getFlavorVcpus()) + .tenantId(in.getTenantId()) + .flavorName(in.getFlavorName()) + .instanceCreated(in.getInstanceCreated()) + .instanceTerminiated(in.getInstanceTerminiated()) + .instanceStatus(in.getInstanceStatus()) + .uptime(in.getUptime()) + ; + } + + } + + private static class ConcreteBuilder extends Builder { + @Override + protected ConcreteBuilder self() { + return this; + } + } + + @SerializedName("name") + private final String instanceName; + private final double hours; + @SerializedName("memory_mb") + private final double flavorMemoryMb; + @SerializedName("local_gb") + private final double flavorLocalGb; + @SerializedName("vcpus") + private final double flavorVcpus; + @SerializedName("tenant_id") + private final String tenantId; + @SerializedName("flavor") + private final String flavorName; + @SerializedName("started_at") + private final Date instanceCreated; + @SerializedName("ended_at") + private final Date instanceTerminiated; + @SerializedName("state") + private final Status instanceStatus; + private final long uptime; + + private SimpleServerUsage(Builder builder) { + this.instanceName = checkNotNull(builder.instanceName, "instanceName"); + this.hours = builder.hours; + this.flavorMemoryMb = builder.flavorMemoryMb; + this.flavorLocalGb = builder.flavorLocalGb; + this.flavorVcpus = builder.flavorVcpus; + this.tenantId = checkNotNull(builder.tenantId, "tenantId"); + this.flavorName = checkNotNull(builder.flavorName, "flavorName"); + this.instanceCreated = builder.instanceCreated; //checkNotNull(builder.instanceCreated, "instanceCreated"); + this.instanceTerminiated = builder.instanceTerminiated; + this.instanceStatus = checkNotNull(builder.instanceStatus, "instanceStatus"); + this.uptime = checkNotNull(builder.uptime, "uptime"); + } + + /** + */ + public String getInstanceName() { + return this.instanceName; + } + + /** + */ + public double getFlavorMemoryMb() { + return this.flavorMemoryMb; + } + + /** + */ + public double getFlavorLocalGb() { + return this.flavorLocalGb; + } + + /** + */ + public double getFlavorVcpus() { + return this.flavorVcpus; + } + + /** + */ + public String getTenantId() { + return this.tenantId; + } + + /** + */ + public String getFlavorName() { + return this.flavorName; + } + + /** + */ + public Date getInstanceCreated() { + return this.instanceCreated; + } + + /** + */ + @Nullable + public Date getInstanceTerminiated() { + return this.instanceTerminiated; + } + + /** + */ + public Status getInstanceStatus() { + return this.instanceStatus; + } + + /** + */ + public long getUptime() { + return this.uptime; + } + + @Override + public int hashCode() { + return Objects.hashCode(instanceName, flavorMemoryMb, flavorLocalGb, flavorVcpus, tenantId, flavorName, instanceCreated, instanceTerminiated, instanceStatus, uptime); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (obj == null || getClass() != obj.getClass()) return false; + SimpleServerUsage that = SimpleServerUsage.class.cast(obj); + return Objects.equal(this.instanceName, that.instanceName) + && Objects.equal(this.flavorMemoryMb, that.flavorMemoryMb) + && Objects.equal(this.flavorLocalGb, that.flavorLocalGb) + && Objects.equal(this.flavorVcpus, that.flavorVcpus) + && Objects.equal(this.tenantId, that.tenantId) + && Objects.equal(this.flavorName, that.flavorName) + && Objects.equal(this.instanceCreated, that.instanceCreated) + && Objects.equal(this.instanceTerminiated, that.instanceTerminiated) + && Objects.equal(this.instanceStatus, that.instanceStatus) + && Objects.equal(this.uptime, that.uptime) + ; + } + + protected ToStringHelper string() { + return Objects.toStringHelper("") + .add("instanceName", instanceName) + .add("flavorMemoryMb", flavorMemoryMb) + .add("flavorLocalGb", flavorLocalGb) + .add("flavorVcpus", flavorVcpus) + .add("tenantId", tenantId) + .add("flavorName", flavorName) + .add("instanceCreated", instanceCreated) + .add("instanceTerminiated", instanceTerminiated) + .add("instanceStatus", instanceStatus) + .add("uptime", uptime) + ; + } + + @Override + public String toString() { + return string().toString(); + } + +} diff --git a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/domain/SimpleTenantUsage.java b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/domain/SimpleTenantUsage.java new file mode 100644 index 0000000000..b4b20ddd2e --- /dev/null +++ b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/domain/SimpleTenantUsage.java @@ -0,0 +1,239 @@ +/** + * 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.openstack.nova.v1_1.domain; + +import static com.google.common.base.Preconditions.checkNotNull; + +import java.util.Collections; +import java.util.Date; +import java.util.Set; + +import org.jclouds.javax.annotation.Nullable; + +import com.google.common.base.Objects; +import com.google.common.base.Objects.ToStringHelper; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Sets; +import com.google.gson.annotations.SerializedName; + +/** + * Information the SimpleTenantUsage extension returns data about each tenant + * + * @author Adam Lowe + */ +public class SimpleTenantUsage { + public static Builder builder() { + return new ConcreteBuilder(); + } + + public Builder toBuilder() { + return new ConcreteBuilder().fromSimpleTenantUsage(this); + } + + public static abstract class Builder> { + private String tenantId; + private double totalLocalGbUsage; + private double totalVcpusUsage; + private double totalMemoryMbUsage; + private double totalHours; + private Date start; + private Date stop; + private Set serverUsages = Sets.newLinkedHashSet(); + + protected abstract T self(); + + public T tenantId(String tenantId) { + this.tenantId = tenantId; + return self(); + } + + public T totalLocalGbUsage(double total_local_gb_usage) { + this.totalLocalGbUsage = total_local_gb_usage; + return self(); + } + + public T totalVcpusUsage(double total_vcpus_usage) { + this.totalVcpusUsage = total_vcpus_usage; + return self(); + } + + public T totalMemoryMbUsage(double total_memory_mb_usage) { + this.totalMemoryMbUsage = total_memory_mb_usage; + return self(); + } + + public T totalHours(double total_hours) { + this.totalHours = total_hours; + return self(); + } + + public T start(Date start) { + this.start = start; + return self(); + } + + public T stop(Date stop) { + this.stop = stop; + return self(); + } + + public T serverUsages(Set serverUsages) { + this.serverUsages = serverUsages; + return self(); + } + + public SimpleTenantUsage build() { + return new SimpleTenantUsage(this); + } + + + public T fromSimpleTenantUsage(SimpleTenantUsage in) { + return this + .totalLocalGbUsage(in.getTotalLocalGbUsage()) + .totalVcpusUsage(in.getTotalVcpusUsage()) + .totalMemoryMbUsage(in.getTotalMemoryMbUsage()) + .totalHours(in.getTotalHours()) + .start(in.getStart()) + .stop(in.getStop()) + .serverUsages(in.getServerUsages()) + ; + } + + } + + private static class ConcreteBuilder extends Builder { + @Override + protected ConcreteBuilder self() { + return this; + } + } + + @SerializedName("tenant_id") + private final String tenantId; + @SerializedName("total_local_gb_usage") + private final double totalLocalGbUsage; + @SerializedName("total_vcpus_usage") + private final double totalVcpusUsage; + @SerializedName("total_memory_mb_usage") + private final double totalMemoryMbUsage; + @SerializedName("total_hours") + private final double totalHours; + private final Date start; + private final Date stop; + @SerializedName("server_usages") + private final Set serverUsages; + + private SimpleTenantUsage(Builder builder) { + this.tenantId = builder.tenantId; + this.totalLocalGbUsage = builder.totalLocalGbUsage; + this.totalVcpusUsage = builder.totalVcpusUsage; + this.totalMemoryMbUsage = builder.totalMemoryMbUsage; + this.totalHours = builder.totalHours; + this.start = builder.start; + this.stop = builder.stop; + this.serverUsages = ImmutableSet.copyOf(checkNotNull(builder.serverUsages, "serverUsages")); + } + + public String getTenantId() { + return tenantId; + } + + /** + */ + public double getTotalLocalGbUsage() { + return this.totalLocalGbUsage; + } + + /** + */ + public double getTotalVcpusUsage() { + return this.totalVcpusUsage; + } + + /** + */ + public double getTotalMemoryMbUsage() { + return this.totalMemoryMbUsage; + } + + /** + */ + public double getTotalHours() { + return this.totalHours; + } + + /** + */ + @Nullable + public Date getStart() { + return this.start; + } + + /** + */ + @Nullable + public Date getStop() { + return this.stop; + } + + /** + */ + @Nullable + public Set getServerUsages() { + return serverUsages == null ? ImmutableSet.of() : Collections.unmodifiableSet(this.serverUsages); + } + + @Override + public int hashCode() { + return Objects.hashCode(totalLocalGbUsage, totalVcpusUsage, totalMemoryMbUsage, totalHours, start, stop, serverUsages); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (obj == null || getClass() != obj.getClass()) return false; + SimpleTenantUsage that = SimpleTenantUsage.class.cast(obj); + return Objects.equal(this.totalLocalGbUsage, that.totalLocalGbUsage) + && Objects.equal(this.totalVcpusUsage, that.totalVcpusUsage) + && Objects.equal(this.totalMemoryMbUsage, that.totalMemoryMbUsage) + && Objects.equal(this.totalHours, that.totalHours) + && Objects.equal(this.start, that.start) + && Objects.equal(this.stop, that.stop) + && Objects.equal(this.serverUsages, that.serverUsages) + ; + } + + protected ToStringHelper string() { + return Objects.toStringHelper("") + .add("totalLocalGbUsage", totalLocalGbUsage) + .add("totalVcpusUsage", totalVcpusUsage) + .add("totalMemoryMbUsage", totalMemoryMbUsage) + .add("totalHours", totalHours) + .add("start", start) + .add("stop", stop) + .add("serverUsages", serverUsages) + ; + } + + @Override + public String toString() { + return string().toString(); + } + +} diff --git a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/extensions/HostAdministrationAsyncClient.java b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/extensions/HostAdministrationAsyncClient.java new file mode 100644 index 0000000000..9e1819f52d --- /dev/null +++ b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/extensions/HostAdministrationAsyncClient.java @@ -0,0 +1,78 @@ +/** + * 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.openstack.nova.v1_1.extensions; + +import java.util.Set; + +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.core.MediaType; + +import org.jclouds.openstack.filters.AuthenticateRequest; +import org.jclouds.openstack.nova.v1_1.domain.Host; +import org.jclouds.openstack.nova.v1_1.domain.HostResourceUsage; +import org.jclouds.openstack.services.Extension; +import org.jclouds.openstack.services.ServiceType; +import org.jclouds.rest.annotations.ExceptionParser; +import org.jclouds.rest.annotations.RequestFilters; +import org.jclouds.rest.annotations.SelectJson; +import org.jclouds.rest.annotations.SkipEncoding; +import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404; +import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404; + +import com.google.common.util.concurrent.ListenableFuture; + +/** + * Provides asynchronous access to Host Administration features via the REST API. + *

+ * + * @author Adam Lowe + * @see SimpleTenantUsageClient + * @see + * @see + * @see + */ +@Extension(of = ServiceType.COMPUTE, namespace = ExtensionNamespaces.HOSTS) +@SkipEncoding({'/', '='}) +@RequestFilters(AuthenticateRequest.class) +public interface HostAdministrationAsyncClient { + + /** + * @see HostAdministrationClient#listHosts() + */ + @GET + @Path("/os-hosts") + @SelectJson("hosts") + @Consumes(MediaType.APPLICATION_JSON) + @ExceptionParser(ReturnEmptySetOnNotFoundOr404.class) + ListenableFuture> listHosts(); + + /** + * @see HostAdministrationClient#getHostResourceUsage(String) + */ + @GET + @Path("/os-hosts/{id}") + @SelectJson("host") + @Consumes(MediaType.APPLICATION_JSON) + @ExceptionParser(ReturnNullOnNotFoundOr404.class) + ListenableFuture> getHostResourceUsage(@PathParam("id") String hostId); + +} diff --git a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/extensions/HostAdministrationClient.java b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/extensions/HostAdministrationClient.java new file mode 100644 index 0000000000..fa23767b6b --- /dev/null +++ b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/extensions/HostAdministrationClient.java @@ -0,0 +1,56 @@ +/** + * 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.openstack.nova.v1_1.extensions; + +import java.util.Set; +import java.util.concurrent.TimeUnit; + +import javax.ws.rs.PathParam; + +import org.jclouds.concurrent.Timeout; +import org.jclouds.openstack.nova.v1_1.domain.Host; +import org.jclouds.openstack.nova.v1_1.domain.HostResourceUsage; +import org.jclouds.openstack.services.Extension; +import org.jclouds.openstack.services.ServiceType; + +/** + * Provides asynchronous access to Host Administration features via the REST API. + *

+ * TODO reboot, shutdown, startup, update + * + * @author Adam Lowe + * @see HostAdministrationAsyncClient + */ +@Extension(of = ServiceType.COMPUTE, namespace = ExtensionNamespaces.HOSTS) +@Timeout(duration = 180, timeUnit = TimeUnit.SECONDS) +public interface HostAdministrationClient { + + /** + * Returns the list of hosts + * @return the usage information + */ + Set listHosts(); + + /** + * Retrieves the physical/usage resource on a specific host + * @return the usage information + */ + Set getHostResourceUsage(@PathParam("id") String hostId); + +} diff --git a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/extensions/SimpleTenantUsageAsyncClient.java b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/extensions/SimpleTenantUsageAsyncClient.java new file mode 100644 index 0000000000..4e2e2b80cf --- /dev/null +++ b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/extensions/SimpleTenantUsageAsyncClient.java @@ -0,0 +1,77 @@ +/** + * 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.openstack.nova.v1_1.extensions; + +import java.util.Set; + +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.core.MediaType; + +import org.jclouds.openstack.filters.AuthenticateRequest; +import org.jclouds.openstack.nova.v1_1.domain.SimpleTenantUsage; +import org.jclouds.openstack.services.Extension; +import org.jclouds.openstack.services.ServiceType; +import org.jclouds.rest.annotations.ExceptionParser; +import org.jclouds.rest.annotations.RequestFilters; +import org.jclouds.rest.annotations.SelectJson; +import org.jclouds.rest.annotations.SkipEncoding; +import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404; +import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404; + +import com.google.common.util.concurrent.ListenableFuture; + +/** + * Provides asynchronous access to Simple Tenant Usage via the REST API. + *

+ * + * @author Adam Lowe + * @see SimpleTenantUsageClient + * @see + * @see + * @see + */ +@Extension(of = ServiceType.COMPUTE, namespace = ExtensionNamespaces.SIMPLE_TENANT_USAGE) +@SkipEncoding({'/', '='}) +@RequestFilters(AuthenticateRequest.class) +public interface SimpleTenantUsageAsyncClient { + + /** + * @see SimpleTenantUsageClient#listTenantUsages() + */ + @GET + @Path("/os-simple-tenant-usage") + @SelectJson("tenant_usages") + @Consumes(MediaType.APPLICATION_JSON) + @ExceptionParser(ReturnEmptySetOnNotFoundOr404.class) + ListenableFuture> listTenantUsages(); + + /** + * @see SimpleTenantUsageClient#getTenantUsage(String) + */ + @GET + @Path("/os-simple-tenant-usage/{id}") + @SelectJson("tenant_usage") + @Consumes(MediaType.APPLICATION_JSON) + @ExceptionParser(ReturnNullOnNotFoundOr404.class) + ListenableFuture getTenantUsage(@PathParam("id") String tenantId); + +} diff --git a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/extensions/SimpleTenantUsageClient.java b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/extensions/SimpleTenantUsageClient.java new file mode 100644 index 0000000000..dcef9aafde --- /dev/null +++ b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/extensions/SimpleTenantUsageClient.java @@ -0,0 +1,53 @@ +/** + * 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.openstack.nova.v1_1.extensions; + +import java.util.Set; +import java.util.concurrent.TimeUnit; + +import org.jclouds.concurrent.Timeout; +import org.jclouds.openstack.nova.v1_1.domain.SimpleTenantUsage; +import org.jclouds.openstack.services.Extension; +import org.jclouds.openstack.services.ServiceType; + +/** + * Provides asynchronous access to Simple Tenant Usage via the REST API. + *

+ * + * @author Adam Lowe + * @see SimpleTenantUsageAsyncClient + */ +@Extension(of = ServiceType.COMPUTE, namespace = ExtensionNamespaces.SIMPLE_TENANT_USAGE) +@Timeout(duration = 180, timeUnit = TimeUnit.SECONDS) +public interface SimpleTenantUsageClient { + + /** + * Retrive tenant_usage for all tenants + * + * @return the set of TenantUsage reports + */ + Set listTenantUsages(); + + /** + * Retrive tenant_usage for a specified tenant + * + * @return the requested tenant usage + */ + SimpleTenantUsage getTenantUsage(String tenantId); +} diff --git a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/functions/PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensionsSet.java b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/functions/PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensionsSet.java index 30d365d278..5db7bb9d46 100644 --- a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/functions/PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensionsSet.java +++ b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/functions/PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensionsSet.java @@ -43,7 +43,7 @@ import com.google.common.collect.Multimap; /** * We use the annotation {@link org.jclouds.openstack.services.Extension} to * bind a class that is an extension to an extension found in the - * {@link ExtensionsClient#listExtensions} call. + * {@link org.jclouds.openstack.nova.v1_1.features.ExtensionClient#listExtensions} call. * * @author Adrian Cole * @@ -62,6 +62,10 @@ public class PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensio URI.create("http://docs.openstack.org/compute/ext/floating_ips/api/v1.1")) .put(URI.create(ExtensionNamespaces.KEYPAIRS), URI.create("http://docs.openstack.org/compute/ext/keypairs/api/v1.1")) + .put(URI.create(ExtensionNamespaces.SIMPLE_TENANT_USAGE), + URI.create("http://docs.openstack.org/compute/ext/os-simple-tenant-usage/api/v1.1")) + .put(URI.create(ExtensionNamespaces.HOSTS), + URI.create("http://docs.openstack.org/compute/ext/hosts/api/v1.1")) .build(); @Inject diff --git a/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v1_1/extensions/HostAdministrationClientExpectTest.java b/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v1_1/extensions/HostAdministrationClientExpectTest.java new file mode 100644 index 0000000000..54d7036994 --- /dev/null +++ b/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v1_1/extensions/HostAdministrationClientExpectTest.java @@ -0,0 +1,84 @@ +/** + * 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.openstack.nova.v1_1.extensions; + +import static org.testng.Assert.assertEquals; + +import java.net.URI; +import java.util.Set; + +import javax.ws.rs.core.MediaType; + +import org.jclouds.http.HttpRequest; +import org.jclouds.http.HttpResponse; +import org.jclouds.openstack.nova.v1_1.domain.Host; +import org.jclouds.openstack.nova.v1_1.domain.HostResourceUsage; +import org.jclouds.openstack.nova.v1_1.internal.BaseNovaClientExpectTest; +import org.testng.annotations.Test; + +import com.google.common.collect.ImmutableMultimap; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Iterables; + +/** + * Tests HostAdministrationClient guice wiring and parsing + * + * @author Adam Lowe + */ +@Test(groups = "unit", testName = "HostAdministrationClientExpectTest") +public class HostAdministrationClientExpectTest extends BaseNovaClientExpectTest { + + + public void testList() throws Exception { + URI endpoint = URI.create("https://compute.north.host/v1.1/3456/os-hosts"); + HostAdministrationClient client = requestsSendResponses(keystoneAuthWithUsernameAndPassword, + responseWithKeystoneAccess, extensionsOfNovaRequest, extensionsOfNovaResponse, + HttpRequest.builder().method("GET").headers(ImmutableMultimap.of("Accept", MediaType.APPLICATION_JSON, "X-Auth-Token", authToken)) + .endpoint(endpoint).build(), + HttpResponse.builder().statusCode(200).payload(payloadFromResource("/hosts_list.json")).build()).getHostAdministrationExtensionForZone("az-1.region-a.geo-1").get(); + + Host expected = Host.builder().name("ubuntu").service("compute").build(); + + Set result = client.listHosts(); + Host host = Iterables.getOnlyElement(result); + assertEquals(host.getName(), "ubuntu"); + assertEquals(host.getService(), "compute"); + + assertEquals(host, expected); + } + + public void testGet() throws Exception { + URI endpoint = URI.create("https://compute.north.host/v1.1/3456/os-hosts/xyz"); + HostAdministrationClient client = requestsSendResponses(keystoneAuthWithUsernameAndPassword, + responseWithKeystoneAccess, extensionsOfNovaRequest, extensionsOfNovaResponse, + HttpRequest.builder().method("GET").headers(ImmutableMultimap.of("Accept", MediaType.APPLICATION_JSON, "X-Auth-Token", authToken)) + .endpoint(endpoint).build(), + HttpResponse.builder().statusCode(200).payload(payloadFromResource("/host.json")).build()).getHostAdministrationExtensionForZone("az-1.region-a.geo-1").get(); + + Set expected = ImmutableSet.of( + HostResourceUsage.builder().memoryMb(16083).project("(total)").cpu(4).diskGb(181).host("ubuntu").build(), + HostResourceUsage.builder().memoryMb(3396).project("(used_now)").cpu(3).diskGb(5).host("ubuntu").build(), + HostResourceUsage.builder().memoryMb(6144).project("(used_max)").cpu(3).diskGb(80).host("ubuntu").build(), + HostResourceUsage.builder().memoryMb(6144).project("f8535069c3fb404cb61c873b1a0b4921").cpu(3).diskGb(80).host("ubuntu").build() + ); + + assertEquals(client.getHostResourceUsage("xyz"), expected); + } + +} diff --git a/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v1_1/extensions/HostAdministrationClientLiveTest.java b/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v1_1/extensions/HostAdministrationClientLiveTest.java new file mode 100644 index 0000000000..e79dd89891 --- /dev/null +++ b/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v1_1/extensions/HostAdministrationClientLiveTest.java @@ -0,0 +1,58 @@ +/** + * 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.openstack.nova.v1_1.extensions; + +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNotNull; + +import java.util.Set; + +import org.jclouds.openstack.nova.v1_1.domain.Host; +import org.jclouds.openstack.nova.v1_1.domain.HostResourceUsage; +import org.jclouds.openstack.nova.v1_1.internal.BaseNovaClientLiveTest; +import org.testng.annotations.Test; + +import com.google.common.base.Optional; + +/** + * Tests behavior of HostAdministrationClient + * + * @author Adam Lowe + */ +@Test(groups = "live", testName = "HostAdministrationClientLiveTest") +public class HostAdministrationClientLiveTest extends BaseNovaClientLiveTest { + + public void testListAndGet() throws Exception { + for (String zoneId : novaContext.getApi().getConfiguredZones()) { + Optional optClient = novaContext.getApi().getHostAdministrationExtensionForZone(zoneId); + if (optClient.isPresent() && identity.endsWith(":admin")) { + HostAdministrationClient client = optClient.get(); + Set hosts = client.listHosts(); + assertNotNull(hosts); + for(Host host : hosts) { + for (HostResourceUsage usage : client.getHostResourceUsage(host.getName())) { + assertEquals(usage.getHost(), host.getName()); + assertNotNull(usage); + } + } + } + } + } + +} diff --git a/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v1_1/extensions/SimpleTenantUsageClientExpectTest.java b/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v1_1/extensions/SimpleTenantUsageClientExpectTest.java new file mode 100644 index 0000000000..3a85a3c7c5 --- /dev/null +++ b/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v1_1/extensions/SimpleTenantUsageClientExpectTest.java @@ -0,0 +1,100 @@ +/** + * 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.openstack.nova.v1_1.extensions; + +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNotNull; +import static org.testng.Assert.assertTrue; + +import java.net.URI; +import java.util.Set; + +import javax.ws.rs.core.MediaType; + +import org.jclouds.date.DateService; +import org.jclouds.date.internal.SimpleDateFormatDateService; +import org.jclouds.http.HttpRequest; +import org.jclouds.http.HttpResponse; +import org.jclouds.openstack.nova.v1_1.domain.SimpleServerUsage; +import org.jclouds.openstack.nova.v1_1.domain.SimpleTenantUsage; +import org.jclouds.openstack.nova.v1_1.internal.BaseNovaClientExpectTest; +import org.testng.annotations.Test; + +import com.google.common.collect.ImmutableMultimap; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Iterables; + +/** + * Tests SimpleTenantUsageClient guice wiring and parsing + * + * @author Adam Lowe + */ +@Test(groups = "unit", testName = "SimpleTenantUsageClientExpectTest") +public class SimpleTenantUsageClientExpectTest extends BaseNovaClientExpectTest { + private DateService dateService = new SimpleDateFormatDateService(); + + public void testList() throws Exception { + URI endpoint = URI.create("https://compute.north.host/v1.1/3456/os-simple-tenant-usage"); + SimpleTenantUsageClient client = requestsSendResponses(keystoneAuthWithUsernameAndPassword, + responseWithKeystoneAccess, extensionsOfNovaRequest, extensionsOfNovaResponse, + HttpRequest.builder().method("GET").headers(ImmutableMultimap.of("Accept", MediaType.APPLICATION_JSON, "X-Auth-Token", authToken)) + .endpoint(endpoint).build(), + HttpResponse.builder().statusCode(200) + .payload(payloadFromResource("/simple_tenant_usages.json")).build()) + .getSimpleTenantUsageExtensionForZone("az-1.region-a.geo-1").get(); + + Set results = client.listTenantUsages(); + + SimpleTenantUsage usage = Iterables.getOnlyElement(results); + assertEquals(usage.getTenantId(), "f8535069c3fb404cb61c873b1a0b4921"); + assertEquals(usage.getTotalHours(), 4.888888888888889e-07); + assertEquals(usage.getTotalLocalGbUsage(), 1.9555555555555557e-05); + assertEquals(usage.getTotalMemoryMbUsage(), 0.0015018666666666667); + assertEquals(usage.getTotalVcpusUsage(), 7.333333333333333e-07); + assertEquals(usage.getStart(), dateService.iso8601DateParse("2012-04-18 12:18:39.702411")); + assertEquals(usage.getStop(), dateService.iso8601DateParse("2012-04-18 12:18:39.702499")); + assertNotNull(usage.getServerUsages()); + assertTrue(usage.getServerUsages().isEmpty()); + } + + public void testGet() throws Exception { + URI endpoint = URI.create("https://compute.north.host/v1.1/3456/os-simple-tenant-usage/test-1234"); + SimpleTenantUsageClient client = requestsSendResponses(keystoneAuthWithUsernameAndPassword, + responseWithKeystoneAccess, extensionsOfNovaRequest, extensionsOfNovaResponse, + HttpRequest.builder().method("GET").headers(ImmutableMultimap.of("Accept", MediaType.APPLICATION_JSON, "X-Auth-Token", authToken)) + .endpoint(endpoint).build(), + HttpResponse.builder().statusCode(200) + .payload(payloadFromResource("/simple_tenant_usage.json")).build()) + .getSimpleTenantUsageExtensionForZone("az-1.region-a.geo-1").get(); + + SimpleTenantUsage usage = client.getTenantUsage("test-1234"); + assertEquals(usage.getTenantId(), "f8535069c3fb404cb61c873b1a0b4921"); + + SimpleTenantUsage expected = SimpleTenantUsage.builder().totalHours(4.833333333333333E-7).totalLocalGbUsage(1.933333333333333E-05) + .start(dateService.iso8601DateParse("2012-04-18 13:32:07.255743")).stop(dateService.iso8601DateParse("2012-04-18 13:32:07.255743")) + .totalMemoryMbUsage(0.0014847999999999999).totalVcpusUsage(7.249999999999999E-07).serverUsages( + ImmutableSet.of( + SimpleServerUsage.builder().hours(2.4166666666666665e-07).uptime(91149).flavorLocalGb(50).instanceName("test1").tenantId("f8535069c3fb404cb61c873b1a0b4921").flavorVcpus(2).flavorMemoryMb(4096).instanceStatus(SimpleServerUsage.Status.ACTIVE).flavorName("m1.medium").instanceCreated(this.dateService.iso8601SecondsDateParse("2012-04-17T12:12:58")).build(), + SimpleServerUsage.builder().hours(2.4166666666666665e-07).uptime(84710).flavorLocalGb(30).instanceName("mish_test").tenantId("f8535069c3fb404cb61c873b1a0b4921").flavorVcpus(1).flavorMemoryMb(2048).instanceStatus(SimpleServerUsage.Status.ACTIVE).flavorName("m1.small").instanceCreated(this.dateService.iso8601SecondsDateParse("2012-04-17T14:00:17")).build() + )).build(); + + assertEquals(usage, expected); + } + +} diff --git a/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v1_1/extensions/SimpleTenantUsageClientLiveTest.java b/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v1_1/extensions/SimpleTenantUsageClientLiveTest.java new file mode 100644 index 0000000000..89307955d1 --- /dev/null +++ b/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v1_1/extensions/SimpleTenantUsageClientLiveTest.java @@ -0,0 +1,53 @@ +/** + * 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.openstack.nova.v1_1.extensions; + +import static org.testng.Assert.assertNotNull; + +import java.util.Set; + +import org.jclouds.openstack.nova.v1_1.domain.SimpleTenantUsage; +import org.jclouds.openstack.nova.v1_1.internal.BaseNovaClientLiveTest; +import org.testng.annotations.Test; + +import com.google.common.base.Optional; + +/** + * Tests behavior of SimpleTenantUsageClient + * + * @author Adam Lowe + */ +@Test(groups = "live", testName = "SimpleTenantUsageClientLiveTest") +public class SimpleTenantUsageClientLiveTest extends BaseNovaClientLiveTest { + + public void testList() throws Exception { + for (String zoneId : novaContext.getApi().getConfiguredZones()) { + Optional optClient = novaContext.getApi().getSimpleTenantUsageExtensionForZone(zoneId); + if (optClient.isPresent() && identity.endsWith(":admin")) { + SimpleTenantUsageClient client = optClient.get(); + Set usages = client.listTenantUsages(); + assertNotNull(usages); + for (SimpleTenantUsage usage : usages) { + SimpleTenantUsage details = client.getTenantUsage(usage.getTenantId()); + assertNotNull(details); + } + } + } + } +} diff --git a/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v1_1/functions/PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensionsSetTest.java b/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v1_1/functions/PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensionsSetTest.java index 73f1db16d0..07cb2df6c3 100644 --- a/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v1_1/functions/PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensionsSetTest.java +++ b/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v1_1/functions/PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensionsSetTest.java @@ -123,17 +123,25 @@ public class PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensio CacheLoader.from(Functions.forMap(ImmutableMap.of("expectedzone", extensions, "differentzone", ImmutableSet. of())))); - PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensionsSet fn = Guice.createInjector(new AbstractModule() { - @Override - protected void configure() {} - - @Provides - LoadingCache> getExtensions() { return extensionsForZone;} + PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensionsSet fn = Guice.createInjector( + new AbstractModule() { + @Override + protected void configure() { + } - @Provides - @Named("openstack.nova.extensions") - Multimap getAliases() { return aliases;} - }).getInstance(PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensionsSet.class); + @SuppressWarnings("unused") + @Provides + LoadingCache> getExtensions() { + return extensionsForZone; + } + + @SuppressWarnings("unused") + @Provides + @Named("openstack.nova.extensions") + Multimap getAliases() { + return aliases; + } + }).getInstance(PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensionsSet.class); return fn; } diff --git a/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v1_1/internal/BaseNovaClientLiveTest.java b/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v1_1/internal/BaseNovaClientLiveTest.java index f4cc9157e4..ca8089bf7f 100644 --- a/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v1_1/internal/BaseNovaClientLiveTest.java +++ b/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v1_1/internal/BaseNovaClientLiveTest.java @@ -48,7 +48,7 @@ public class BaseNovaClientLiveTest extends BaseComputeServiceContextLiveTest { @Override public void setupContext() { super.setupContext(); - novaContext = context.unwrap(); + novaContext = view.unwrap(); } @Override diff --git a/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v1_1/internal/BaseNovaExpectTest.java b/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v1_1/internal/BaseNovaExpectTest.java index c311dbcbe0..336f507ba7 100644 --- a/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v1_1/internal/BaseNovaExpectTest.java +++ b/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v1_1/internal/BaseNovaExpectTest.java @@ -63,7 +63,7 @@ public class BaseNovaExpectTest extends BaseRestClientExpectTest { .put("X-Auth-Token", authToken).build()).build(); extensionsOfNovaResponse = HttpResponse.builder().statusCode(200) - .payload(payloadFromResource("/extension_list_normal.json")).build(); + .payload(payloadFromResource("/extension_list_full.json")).build(); unmatchedExtensionsOfNovaResponse = HttpResponse.builder().statusCode(200) .payload(payloadFromResource("/extension_list.json")).build(); diff --git a/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v1_1/parse/ParseKeyPairListTest.java b/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v1_1/parse/ParseKeyPairListTest.java index 8622e08a97..fe8a72b801 100644 --- a/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v1_1/parse/ParseKeyPairListTest.java +++ b/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v1_1/parse/ParseKeyPairListTest.java @@ -25,7 +25,7 @@ import java.util.Set; import javax.ws.rs.Consumes; import javax.ws.rs.core.MediaType; -import org.jclouds.json.BaseParserTest; +import org.jclouds.json.BaseItemParserTest; import org.jclouds.json.config.GsonModule; import org.jclouds.openstack.nova.v1_1.config.NovaParserModule; import org.jclouds.openstack.nova.v1_1.domain.KeyPair; @@ -41,7 +41,7 @@ import com.google.inject.Injector; * @author Michael Arnold */ @Test(groups = "unit", testName = "ParseKeyPairListTest") -public class ParseKeyPairListTest extends BaseParserTest { +public class ParseKeyPairListTest extends BaseItemParserTest>> { @Override public String resource() { diff --git a/apis/openstack-nova/src/test/resources/extension_list_full.json b/apis/openstack-nova/src/test/resources/extension_list_full.json new file mode 100644 index 0000000000..298a2f2f4a --- /dev/null +++ b/apis/openstack-nova/src/test/resources/extension_list_full.json @@ -0,0 +1,123 @@ +{ + "extensions": [{ + "updated": "2011-06-09T00:00:00+00:00", + "name": "Multinic", + "links": [], + "namespace": "https://docs.openstack.org/ext/multinic/api/v1.1", + "alias": "NMN", + "description": "Multiple network support" + }, { + "updated": "2011-06-29T00:00:00+00:00", + "name": "Hosts", + "links": [], + "namespace": "https://docs.openstack.org/ext/hosts/api/v1.1", + "alias": "os-hosts", + "description": "Host administration" + }, { + "updated": "2011-03-25T00:00:00+00:00", + "name": "Volumes", + "links": [], + "namespace": "https://docs.openstack.org/ext/volumes/api/v1.1", + "alias": "os-volumes", + "description": "Volumes support" + }, { + "updated": "2011-05-25 16:12:21.656723", + "name": "Admin Controller", + "links": [], + "namespace": "https:TODO/", + "alias": "ADMIN", + "description": "The Admin API Extension" + }, { + "updated": "2011-08-08T00:00:00+00:00", + "name": "Quotas", + "links": [], + "namespace": "https://docs.openstack.org/ext/quotas-sets/api/v1.1", + "alias": "os-quota-sets", + "description": "Quotas management support" + }, { + "updated": "2011-08-24T00:00:00+00:00", + "name": "VolumeTypes", + "links": [], + "namespace": "https://docs.openstack.org/ext/volume_types/api/v1.1", + "alias": "os-volume-types", + "description": "Volume types support" + }, { + "updated": "2011-06-23T00:00:00+00:00", + "name": "FlavorExtraSpecs", + "links": [], + "namespace": "https://docs.openstack.org/ext/flavor_extra_specs/api/v1.1", + "alias": "os-flavor-extra-specs", + "description": "Instance type (flavor) extra specs" + }, { + "updated": "2011-09-14T00:00:00+00:00", + "name": "FlavorExtraData", + "links": [], + "namespace": "https://docs.openstack.org/ext/flavor_extra_data/api/v1.1", + "alias": "os-flavor-extra-data", + "description": "Provide additional data for flavors" + }, { + "updated": "2011-08-17T00:00:00+00:00", + "name": "VirtualInterfaces", + "links": [], + "namespace": "https://docs.openstack.org/ext/virtual_interfaces/api/v1.1", + "alias": "virtual_interfaces", + "description": "Virtual interface support" + }, { + "updated": "2011-07-19T00:00:00+00:00", + "name": "Createserverext", + "links": [], + "namespace": "https://docs.openstack.org/ext/createserverext/api/v1.1", + "alias": "os-create-server-ext", + "description": "Extended support to the Create Server v1.1 API" + }, { + "updated": "2011-08-08T00:00:00+00:00", + "name": "Keypairs", + "links": [], + "namespace": "https://docs.openstack.org/ext/keypairs/api/v1.1", + "alias": "os-keypairs", + "description": "Keypair Support" + }, { + "updated": "2011-08-25T00:00:00+00:00", + "name": "VSAs", + "links": [], + "namespace": "https://docs.openstack.org/ext/vsa/api/v1.1", + "alias": "zadr-vsa", + "description": "Virtual Storage Arrays support" + }, { + "updated": "2011-08-19T00:00:00+00:00", + "name": "SimpleTenantUsage", + "links": [], + "namespace": "https://docs.openstack.org/ext/os-simple-tenant-usage/api/v1.1", + "alias": "os-simple-tenant-usage", + "description": "Simple tenant usage extension" + }, { + "updated": "2011-08-18T00:00:00+00:00", + "name": "Rescue", + "links": [], + "namespace": "https://docs.openstack.org/ext/rescue/api/v1.1", + "alias": "os-rescue", + "description": "Instance rescue mode" + }, { + "updated": "2011-07-21T00:00:00+00:00", + "name": "SecurityGroups", + "links": [], + "namespace": "https://docs.openstack.org/ext/securitygroups/api/v1.1", + "alias": "security_groups", + "description": "Security group support" + }, { + "updated": "2011-06-16T00:00:00+00:00", + "name": "Floating_ips", + "links": [], + "namespace": "https://docs.openstack.org/ext/floating_ips/api/v1.1", + "alias": "os-floating-ips", + "description": "Floating IPs support" + }, { + "updated": "2011-06-16T00:00:00+00:00", + "name": "Users", + "links": [], + "namespace": "http://docs.openstack.org/compute/ext/users/api/v1.1", + "alias": "os-users", + "description": "Users support" + } + ] +} \ No newline at end of file diff --git a/apis/openstack-nova/src/test/resources/host.json b/apis/openstack-nova/src/test/resources/host.json new file mode 100644 index 0000000000..ad2e217e24 --- /dev/null +++ b/apis/openstack-nova/src/test/resources/host.json @@ -0,0 +1 @@ +{"host": [{"resource": {"project": "(total)", "memory_mb": 16083, "host": "ubuntu", "cpu": 4, "disk_gb": 181}}, {"resource": {"project": "(used_now)", "memory_mb": 3396, "host": "ubuntu", "cpu": 3, "disk_gb": 5}}, {"resource": {"project": "(used_max)", "memory_mb": 6144, "host": "ubuntu", "cpu": 3, "disk_gb": 80}}, {"resource": {"project": "f8535069c3fb404cb61c873b1a0b4921", "memory_mb": 6144, "host": "ubuntu", "cpu": 3, "disk_gb": 80}}]} \ No newline at end of file diff --git a/apis/openstack-nova/src/test/resources/hosts_list.json b/apis/openstack-nova/src/test/resources/hosts_list.json new file mode 100644 index 0000000000..30d377016b --- /dev/null +++ b/apis/openstack-nova/src/test/resources/hosts_list.json @@ -0,0 +1 @@ +{"hosts": [{"host_name": "ubuntu", "service": "compute"}]} \ No newline at end of file diff --git a/apis/openstack-nova/src/test/resources/simple_tenant_usage.json b/apis/openstack-nova/src/test/resources/simple_tenant_usage.json new file mode 100644 index 0000000000..de07dc4f7c --- /dev/null +++ b/apis/openstack-nova/src/test/resources/simple_tenant_usage.json @@ -0,0 +1 @@ +{"tenant_usage": {"total_memory_mb_usage": 0.0014847999999999999, "total_vcpus_usage": 7.249999999999999e-07, "total_hours": 4.833333333333333e-07, "tenant_id": "f8535069c3fb404cb61c873b1a0b4921", "stop": "2012-04-18 13:32:07.255830", "server_usages": [{"hours": 2.4166666666666665e-07, "uptime": 91149, "local_gb": 50, "ended_at": null, "name": "test1", "tenant_id": "f8535069c3fb404cb61c873b1a0b4921", "vcpus": 2, "memory_mb": 4096, "state": "active", "flavor": "m1.medium", "started_at": "2012-04-17 12:12:58"}, {"hours": 2.4166666666666665e-07, "uptime": 84710, "local_gb": 30, "ended_at": null, "name": "mish_test", "tenant_id": "f8535069c3fb404cb61c873b1a0b4921", "vcpus": 1, "memory_mb": 2048, "state": "active", "flavor": "m1.small", "started_at": "2012-04-17 14:00:17"}], "start": "2012-04-18 13:32:07.255743", "total_local_gb_usage": 1.933333333333333e-05}} \ No newline at end of file diff --git a/apis/openstack-nova/src/test/resources/simple_tenant_usages.json b/apis/openstack-nova/src/test/resources/simple_tenant_usages.json new file mode 100644 index 0000000000..6f3c0d74f6 --- /dev/null +++ b/apis/openstack-nova/src/test/resources/simple_tenant_usages.json @@ -0,0 +1 @@ +{"tenant_usages": [{"total_memory_mb_usage": 0.0015018666666666667, "total_vcpus_usage": 7.333333333333333e-07, "start": "2012-04-18 12:18:39.702411", "tenant_id": "f8535069c3fb404cb61c873b1a0b4921", "stop": "2012-04-18 12:18:39.702499", "total_hours": 4.888888888888889e-07, "total_local_gb_usage": 1.9555555555555557e-05}] \ No newline at end of file diff --git a/apis/s3/src/main/java/org/jclouds/s3/S3ApiMetadata.java b/apis/s3/src/main/java/org/jclouds/s3/S3ApiMetadata.java index ae09127794..93a05fdef3 100644 --- a/apis/s3/src/main/java/org/jclouds/s3/S3ApiMetadata.java +++ b/apis/s3/src/main/java/org/jclouds/s3/S3ApiMetadata.java @@ -108,7 +108,7 @@ public class S3ApiMetadata extends BaseRestApiMetadata { .version(S3AsyncClient.VERSION) .defaultProperties(S3ApiMetadata.defaultProperties()) .context(CONTEXT_TOKEN) - .wrapper(TypeToken.of(S3BlobStoreContext.class)) + .view(TypeToken.of(S3BlobStoreContext.class)) .defaultModules(ImmutableSet.>of(S3RestClientModule.class, S3BlobStoreContextModule.class)); } diff --git a/apis/s3/src/main/java/org/jclouds/s3/S3AsyncClient.java b/apis/s3/src/main/java/org/jclouds/s3/S3AsyncClient.java index 122970450a..b29b572747 100644 --- a/apis/s3/src/main/java/org/jclouds/s3/S3AsyncClient.java +++ b/apis/s3/src/main/java/org/jclouds/s3/S3AsyncClient.java @@ -95,7 +95,7 @@ import com.google.inject.Provides; * Provides asynchronous access to S3 via their REST API. *

* All commands return a ListenableFuture of the result from S3. Any exceptions incurred during - * processing will be wrapped in an {@link ExecutionException} as documented in + * processing will be backend in an {@link ExecutionException} as documented in * {@link ListenableFuture#get()}. * * @author Adrian Cole 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 a393d40d78..84dd24a71c 100644 --- a/apis/s3/src/main/java/org/jclouds/s3/S3Client.java +++ b/apis/s3/src/main/java/org/jclouds/s3/S3Client.java @@ -44,7 +44,7 @@ import com.google.inject.Provides; * Provides access to S3 via their REST API. *

* All commands return a Future of the result from S3. Any exceptions incurred during - * processing will be wrapped in an {@link ExecutionException} as documented in + * processing will be backend in an {@link ExecutionException} as documented in * {@link Future#get()}. * * @author Adrian Cole diff --git a/apis/s3/src/main/java/org/jclouds/s3/blobstore/internal/S3BlobStoreContextImpl.java b/apis/s3/src/main/java/org/jclouds/s3/blobstore/internal/S3BlobStoreContextImpl.java index 16146c35c8..2b3e4b2ae4 100644 --- a/apis/s3/src/main/java/org/jclouds/s3/blobstore/internal/S3BlobStoreContextImpl.java +++ b/apis/s3/src/main/java/org/jclouds/s3/blobstore/internal/S3BlobStoreContextImpl.java @@ -18,11 +18,10 @@ */ package org.jclouds.s3.blobstore.internal; -import java.io.Closeable; - import javax.inject.Inject; import javax.inject.Singleton; +import org.jclouds.Context; import org.jclouds.blobstore.AsyncBlobStore; import org.jclouds.blobstore.BlobMap; import org.jclouds.blobstore.BlobRequestSigner; @@ -45,11 +44,11 @@ import com.google.common.reflect.TypeToken; public class S3BlobStoreContextImpl extends BlobStoreContextImpl implements S3BlobStoreContext { @Inject - public S3BlobStoreContextImpl(@Provider Closeable wrapped, @Provider TypeToken wrappedType, + public S3BlobStoreContextImpl(@Provider Context backend, @Provider TypeToken backendType, BlobMap.Factory blobMapFactory, Utils utils, ConsistencyModel consistencyModel, InputStreamMap.Factory inputStreamMapFactory, AsyncBlobStore ablobStore, BlobStore blobStore, BlobRequestSigner blobRequestSigner) { - super(wrapped, wrappedType, blobMapFactory, utils, consistencyModel, inputStreamMapFactory, ablobStore, + super(backend, backendType, blobMapFactory, utils, consistencyModel, inputStreamMapFactory, ablobStore, blobStore, blobRequestSigner); } diff --git a/apis/s3/src/main/java/org/jclouds/s3/filters/RequestAuthorizeSignature.java b/apis/s3/src/main/java/org/jclouds/s3/filters/RequestAuthorizeSignature.java index db8d97f4dc..74876d10e6 100644 --- a/apis/s3/src/main/java/org/jclouds/s3/filters/RequestAuthorizeSignature.java +++ b/apis/s3/src/main/java/org/jclouds/s3/filters/RequestAuthorizeSignature.java @@ -21,8 +21,6 @@ package org.jclouds.s3.filters; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.collect.Iterables.any; import static com.google.common.collect.Iterables.get; -import static org.jclouds.Constants.PROPERTY_CREDENTIAL; -import static org.jclouds.Constants.PROPERTY_IDENTITY; import static org.jclouds.aws.reference.AWSConstants.PROPERTY_AUTH_TAG; import static org.jclouds.aws.reference.AWSConstants.PROPERTY_HEADER_TAG; import static org.jclouds.http.utils.ModifyRequest.parseQueryToMap; @@ -35,8 +33,8 @@ import java.lang.annotation.Annotation; import java.util.Arrays; import java.util.Collection; import java.util.Locale; -import java.util.Map.Entry; import java.util.Set; +import java.util.Map.Entry; import javax.annotation.Resource; import javax.inject.Inject; @@ -57,6 +55,8 @@ import org.jclouds.http.internal.SignatureWire; import org.jclouds.io.InputSuppliers; import org.jclouds.logging.Logger; import org.jclouds.rest.RequestSigner; +import org.jclouds.rest.annotations.Credential; +import org.jclouds.rest.annotations.Identity; import org.jclouds.rest.internal.GeneratedHttpRequest; import org.jclouds.s3.Bucket; @@ -114,7 +114,7 @@ public class RequestAuthorizeSignature implements HttpRequestFilter, RequestSign public RequestAuthorizeSignature(SignatureWire signatureWire, @Named(PROPERTY_AUTH_TAG) String authTag, @Named(PROPERTY_S3_VIRTUAL_HOST_BUCKETS) boolean isVhostStyle, @Named(PROPERTY_S3_SERVICE_PATH) String servicePath, @Named(PROPERTY_HEADER_TAG) String headerTag, - @Named(PROPERTY_IDENTITY) String accessKey, @Named(PROPERTY_CREDENTIAL) String secretKey, + @Identity String accessKey, @Credential String secretKey, @TimeStamp Provider timeStampProvider, Crypto crypto, HttpUtils utils) { this.isVhostStyle = isVhostStyle; this.servicePath = servicePath; 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 74c0b0989a..774871ee65 100644 --- a/apis/s3/src/test/java/org/jclouds/s3/S3ClientLiveTest.java +++ b/apis/s3/src/test/java/org/jclouds/s3/S3ClientLiveTest.java @@ -68,7 +68,7 @@ public class S3ClientLiveTest extends BaseBlobStoreIntegrationTest { } public S3Client getApi() { - return context.unwrap(S3ApiMetadata.CONTEXT_TOKEN).getApi(); + return view.unwrap(S3ApiMetadata.CONTEXT_TOKEN).getApi(); } /** diff --git a/apis/s3/src/test/java/org/jclouds/s3/services/BucketsLiveTest.java b/apis/s3/src/test/java/org/jclouds/s3/services/BucketsLiveTest.java index 90de74bb69..ea22c1f3ff 100644 --- a/apis/s3/src/test/java/org/jclouds/s3/services/BucketsLiveTest.java +++ b/apis/s3/src/test/java/org/jclouds/s3/services/BucketsLiveTest.java @@ -71,7 +71,7 @@ public class BucketsLiveTest extends BaseBlobStoreIntegrationTest { } public S3Client getApi() { - return (S3Client) context.unwrap(S3ApiMetadata.CONTEXT_TOKEN).getApi(); + return (S3Client) view.unwrap(S3ApiMetadata.CONTEXT_TOKEN).getApi(); } /** diff --git a/apis/swift/src/main/java/org/jclouds/openstack/swift/CommonSwiftAsyncClient.java b/apis/swift/src/main/java/org/jclouds/openstack/swift/CommonSwiftAsyncClient.java index 2fff5ae24e..71aae2d781 100644 --- a/apis/swift/src/main/java/org/jclouds/openstack/swift/CommonSwiftAsyncClient.java +++ b/apis/swift/src/main/java/org/jclouds/openstack/swift/CommonSwiftAsyncClient.java @@ -52,14 +52,7 @@ import org.jclouds.openstack.swift.functions.ParseObjectInfoFromHeaders; import org.jclouds.openstack.swift.functions.ParseObjectInfoListFromJsonResponse; import org.jclouds.openstack.swift.functions.ReturnTrueOn404FalseOn409; import org.jclouds.openstack.swift.options.ListContainerOptions; -import org.jclouds.rest.annotations.BinderParam; -import org.jclouds.rest.annotations.Endpoint; -import org.jclouds.rest.annotations.ExceptionParser; -import org.jclouds.rest.annotations.ParamParser; -import org.jclouds.rest.annotations.QueryParams; -import org.jclouds.rest.annotations.RequestFilters; -import org.jclouds.rest.annotations.ResponseParser; -import org.jclouds.rest.annotations.SkipEncoding; +import org.jclouds.rest.annotations.*; import org.jclouds.rest.functions.ReturnVoidOnNotFoundOr404; import com.google.common.util.concurrent.ListenableFuture; @@ -183,4 +176,11 @@ public interface CommonSwiftAsyncClient { @Path("/{container}/{name}") ListenableFuture removeObject(@PathParam("container") String container, @PathParam("name") String name); + @PUT + @Path("/{container}/{name}") + @ResponseParser(ParseETagHeader.class) + @Headers(keys = "X-Object-Manifest", values="{container}/{name}") + ListenableFuture putObjectManifest(@PathParam("container") String container, + @PathParam("name") String name); + } diff --git a/apis/swift/src/main/java/org/jclouds/openstack/swift/CommonSwiftClient.java b/apis/swift/src/main/java/org/jclouds/openstack/swift/CommonSwiftClient.java index a8b5210a32..e325aef6de 100644 --- a/apis/swift/src/main/java/org/jclouds/openstack/swift/CommonSwiftClient.java +++ b/apis/swift/src/main/java/org/jclouds/openstack/swift/CommonSwiftClient.java @@ -113,4 +113,5 @@ public interface CommonSwiftClient { */ boolean objectExists(String container, String name); + String putObjectManifest(String container, String name); } diff --git a/apis/swift/src/main/java/org/jclouds/openstack/swift/SwiftApiMetadata.java b/apis/swift/src/main/java/org/jclouds/openstack/swift/SwiftApiMetadata.java index c628ae65c8..2dae10ea7c 100644 --- a/apis/swift/src/main/java/org/jclouds/openstack/swift/SwiftApiMetadata.java +++ b/apis/swift/src/main/java/org/jclouds/openstack/swift/SwiftApiMetadata.java @@ -83,7 +83,7 @@ public class SwiftApiMetadata extends BaseRestApiMetadata { .documentation(URI.create("http://api.openstack.org/")) .version(OpenStackAuthAsyncClient.VERSION) .defaultProperties(SwiftApiMetadata.defaultProperties()) - .wrapper(TypeToken.of(BlobStoreContext.class)) + .view(TypeToken.of(BlobStoreContext.class)) .defaultModules(ImmutableSet.>of(SwiftRestClientModule.class, SwiftBlobStoreContextModule.class)); } 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 b0873c9af6..5ae25a4989 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 @@ -55,6 +55,7 @@ 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 org.jclouds.openstack.swift.domain.ContainerMetadata; import org.jclouds.openstack.swift.domain.MutableObjectInfoWithMetadata; import org.jclouds.openstack.swift.domain.ObjectInfo; @@ -81,6 +82,7 @@ public class SwiftAsyncBlobStore extends BaseAsyncBlobStore { private final ObjectToBlobMetadata object2BlobMd; private final BlobToHttpGetOptions blob2ObjectGetOptions; private final Provider fetchBlobMetadataProvider; + private final Provider multipartUploadStrategy; @Inject protected SwiftAsyncBlobStore(BlobStoreContext context, BlobUtils blobUtils, @@ -90,7 +92,8 @@ public class SwiftAsyncBlobStore extends BaseAsyncBlobStore { BlobStoreListContainerOptionsToListContainerOptions container2ContainerListOptions, ContainerToResourceList container2ResourceList, ObjectToBlob object2Blob, BlobToObject blob2Object, ObjectToBlobMetadata object2BlobMd, BlobToHttpGetOptions blob2ObjectGetOptions, - Provider fetchBlobMetadataProvider) { + Provider fetchBlobMetadataProvider, + Provider multipartUploadStrategy) { super(context, blobUtils, service, defaultLocation, locations); this.sync = sync; this.async = async; @@ -102,6 +105,7 @@ public class SwiftAsyncBlobStore extends BaseAsyncBlobStore { this.object2BlobMd = object2BlobMd; this.blob2ObjectGetOptions = blob2ObjectGetOptions; this.fetchBlobMetadataProvider = checkNotNull(fetchBlobMetadataProvider, "fetchBlobMetadataProvider"); + this.multipartUploadStrategy = multipartUploadStrategy; } /** @@ -238,8 +242,11 @@ public class SwiftAsyncBlobStore extends BaseAsyncBlobStore { @Override public ListenableFuture putBlob(String container, Blob blob, PutOptions options) { - // TODO implement options - return putBlob(container, blob); + if (options.isMultipart()) { + return multipartUploadStrategy.get().execute(container, blob, options, blob2Object); + } else { + return putBlob(container, blob); + } } @Override diff --git a/apis/swift/src/main/java/org/jclouds/openstack/swift/blobstore/SwiftBlobStore.java b/apis/swift/src/main/java/org/jclouds/openstack/swift/blobstore/SwiftBlobStore.java index e96909ba18..2afc789227 100644 --- a/apis/swift/src/main/java/org/jclouds/openstack/swift/blobstore/SwiftBlobStore.java +++ b/apis/swift/src/main/java/org/jclouds/openstack/swift/blobstore/SwiftBlobStore.java @@ -50,6 +50,7 @@ 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.MultipartUploadStrategy; import org.jclouds.openstack.swift.domain.ContainerMetadata; import com.google.common.base.Function; @@ -71,6 +72,7 @@ public class SwiftBlobStore extends BaseBlobStore { private final ObjectToBlobMetadata object2BlobMd; private final BlobToHttpGetOptions blob2ObjectGetOptions; private final Provider fetchBlobMetadataProvider; + private final Provider multipartUploadStrategy; @Inject protected SwiftBlobStore(BlobStoreContext context, BlobUtils blobUtils, Supplier defaultLocation, @@ -79,7 +81,8 @@ public class SwiftBlobStore extends BaseBlobStore { BlobStoreListContainerOptionsToListContainerOptions container2ContainerListOptions, ContainerToResourceList container2ResourceList, ObjectToBlob object2Blob, BlobToObject blob2Object, ObjectToBlobMetadata object2BlobMd, BlobToHttpGetOptions blob2ObjectGetOptions, - Provider fetchBlobMetadataProvider) { + Provider fetchBlobMetadataProvider, + Provider multipartUploadStrategy) { super(context, blobUtils, defaultLocation, locations); this.sync = sync; this.container2ResourceMd = container2ResourceMd; @@ -90,6 +93,7 @@ public class SwiftBlobStore extends BaseBlobStore { this.object2BlobMd = object2BlobMd; this.blob2ObjectGetOptions = blob2ObjectGetOptions; this.fetchBlobMetadataProvider = checkNotNull(fetchBlobMetadataProvider, "fetchBlobMetadataProvider"); + this.multipartUploadStrategy = multipartUploadStrategy; } /** @@ -206,8 +210,11 @@ public class SwiftBlobStore extends BaseBlobStore { */ @Override public String putBlob(String container, Blob blob, PutOptions options) { - // TODO implement options - return putBlob(container, blob); + if (options.isMultipart()) { + return multipartUploadStrategy.get().execute(container, blob, options, blob2Object); + } else { + return putBlob(container, blob); + } } /** diff --git a/apis/swift/src/main/java/org/jclouds/openstack/swift/blobstore/strategy/MultipartUpload.java b/apis/swift/src/main/java/org/jclouds/openstack/swift/blobstore/strategy/MultipartUpload.java new file mode 100644 index 0000000000..9c2ead8253 --- /dev/null +++ b/apis/swift/src/main/java/org/jclouds/openstack/swift/blobstore/strategy/MultipartUpload.java @@ -0,0 +1,17 @@ +package org.jclouds.openstack.swift.blobstore.strategy; + +public interface MultipartUpload { + + /* Maximum number of parts per upload */ + public static final int MAX_NUMBER_OF_PARTS = 10000; + /* Maximum number of parts returned for a list parts request */ + public static final int MAX_LIST_PARTS_RETURNED = 1000; + /* Maximum number of multipart uploads returned in a list multipart uploads request */ + public static final int MAX_LIST_MPU_RETURNED = 1000; + + /* + * part size 5 MB to 5 GB, last part can be < 5 MB + */ + public static final long MIN_PART_SIZE = 5242880L; + public static final long MAX_PART_SIZE = 5368709120L; +} diff --git a/apis/swift/src/main/java/org/jclouds/openstack/swift/blobstore/strategy/internal/AsyncMultipartUploadStrategy.java b/apis/swift/src/main/java/org/jclouds/openstack/swift/blobstore/strategy/internal/AsyncMultipartUploadStrategy.java new file mode 100644 index 0000000000..017d1dac22 --- /dev/null +++ b/apis/swift/src/main/java/org/jclouds/openstack/swift/blobstore/strategy/internal/AsyncMultipartUploadStrategy.java @@ -0,0 +1,12 @@ +package org.jclouds.openstack.swift.blobstore.strategy.internal; + +import com.google.common.util.concurrent.ListenableFuture; +import com.google.inject.ImplementedBy; +import org.jclouds.blobstore.domain.Blob; +import org.jclouds.blobstore.options.PutOptions; +import org.jclouds.openstack.swift.blobstore.functions.BlobToObject; + +@ImplementedBy(ParallelMultipartUploadStrategy.class) +public interface AsyncMultipartUploadStrategy { + ListenableFuture execute(String container, Blob blob, PutOptions options, BlobToObject blob2Object); +} diff --git a/apis/swift/src/main/java/org/jclouds/openstack/swift/blobstore/strategy/internal/MultipartUploadSlicingAlgorithm.java b/apis/swift/src/main/java/org/jclouds/openstack/swift/blobstore/strategy/internal/MultipartUploadSlicingAlgorithm.java new file mode 100644 index 0000000000..26c5979dea --- /dev/null +++ b/apis/swift/src/main/java/org/jclouds/openstack/swift/blobstore/strategy/internal/MultipartUploadSlicingAlgorithm.java @@ -0,0 +1,152 @@ +/** + * 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. + */ +/* + * MultipartUploadSlicingAlgorithm.java + * + * + * Created by: tibor + * + * History + * + */ + +package org.jclouds.openstack.swift.blobstore.strategy.internal; + +import com.google.common.annotations.VisibleForTesting; +import com.google.inject.Inject; +import org.jclouds.blobstore.reference.BlobStoreConstants; +import org.jclouds.logging.Logger; +import org.jclouds.openstack.swift.blobstore.strategy.MultipartUpload; + +import javax.annotation.Resource; +import javax.inject.Named; + +public class MultipartUploadSlicingAlgorithm { + + @Resource + @Named(BlobStoreConstants.BLOBSTORE_LOGGER) + protected Logger logger = Logger.NULL; + + @VisibleForTesting + static final long DEFAULT_PART_SIZE = 33554432; // 32MB + + @VisibleForTesting + static final int DEFAULT_MAGNITUDE_BASE = 100; + + @Inject(optional = true) + @Named("jclouds.mpu.parts.size") + @VisibleForTesting + long defaultPartSize = DEFAULT_PART_SIZE; + + @Inject(optional = true) + @Named("jclouds.mpu.parts.magnitude") + @VisibleForTesting + int magnitudeBase = DEFAULT_MAGNITUDE_BASE; + + // calculated only once, but not from the constructor + private volatile int parts; // required number of parts with chunkSize + private volatile long chunkSize; + private volatile long remaining; // number of bytes remained for the last part + + // sequentially updated values + private volatile int part; + private volatile long chunkOffset; + private volatile long copied; + + @VisibleForTesting + protected long calculateChunkSize(long length) { + long unitPartSize = defaultPartSize; // first try with default part size + int parts = (int)(length / unitPartSize); + long partSize = unitPartSize; + int magnitude = (int) (parts / magnitudeBase); + if (magnitude > 0) { + partSize = magnitude * unitPartSize; + if (partSize > MultipartUpload.MAX_PART_SIZE) { + partSize = MultipartUpload.MAX_PART_SIZE; + unitPartSize = MultipartUpload.MAX_PART_SIZE; + } + parts = (int)(length / partSize); + if (parts * partSize < length) { + partSize = (magnitude + 1) * unitPartSize; + if (partSize > MultipartUpload.MAX_PART_SIZE) { + partSize = MultipartUpload.MAX_PART_SIZE; + unitPartSize = MultipartUpload.MAX_PART_SIZE; + } + parts = (int)(length / partSize); + } + } + if (parts > MultipartUpload.MAX_NUMBER_OF_PARTS) { // if splits in too many parts or + // cannot be split + unitPartSize = MultipartUpload.MIN_PART_SIZE; // take the minimum part size + parts = (int)(length / unitPartSize); + } + if (parts > MultipartUpload.MAX_NUMBER_OF_PARTS) { // if still splits in too many parts + parts = MultipartUpload.MAX_NUMBER_OF_PARTS - 1; // limit them. do not care about not + // covering + } + long remainder = length % unitPartSize; + if (remainder == 0 && parts > 0) { + parts -= 1; + } + this.chunkSize = partSize; + this.parts = parts; + this.remaining = length - partSize * parts; + logger.debug(" %d bytes partitioned in %d parts of part size: %d, remaining: %d%s", length, parts, chunkSize, + remaining, (remaining > MultipartUpload.MAX_PART_SIZE ? " overflow!" : "")); + return this.chunkSize; + } + + public long getCopied() { + return copied; + } + + public void setCopied(long copied) { + this.copied = copied; + } + + @VisibleForTesting + protected int getParts() { + return parts; + } + + protected int getNextPart() { + return ++part; + } + + protected void addCopied(long copied) { + this.copied += copied; + } + + protected long getNextChunkOffset() { + long next = chunkOffset; + chunkOffset += getChunkSize(); + return next; + } + + @VisibleForTesting + protected long getChunkSize() { + return chunkSize; + } + + @VisibleForTesting + protected long getRemaining() { + return remaining; + } + +} diff --git a/apis/swift/src/main/java/org/jclouds/openstack/swift/blobstore/strategy/internal/MultipartUploadStrategy.java b/apis/swift/src/main/java/org/jclouds/openstack/swift/blobstore/strategy/internal/MultipartUploadStrategy.java new file mode 100644 index 0000000000..c536a8e8c2 --- /dev/null +++ b/apis/swift/src/main/java/org/jclouds/openstack/swift/blobstore/strategy/internal/MultipartUploadStrategy.java @@ -0,0 +1,13 @@ +package org.jclouds.openstack.swift.blobstore.strategy.internal; + +import com.google.inject.ImplementedBy; +import org.jclouds.blobstore.domain.Blob; +import org.jclouds.blobstore.options.PutOptions; +import org.jclouds.openstack.swift.blobstore.functions.BlobToObject; +import org.jclouds.openstack.swift.blobstore.strategy.MultipartUpload; + +@ImplementedBy(SequentialMultipartUploadStrategy.class) +public interface MultipartUploadStrategy extends MultipartUpload { + + String execute(String container, Blob blob, PutOptions options, BlobToObject blob2Object); +} 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 new file mode 100644 index 0000000000..a5b02c5728 --- /dev/null +++ b/apis/swift/src/main/java/org/jclouds/openstack/swift/blobstore/strategy/internal/ParallelMultipartUploadStrategy.java @@ -0,0 +1,267 @@ +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 javax.annotation.Resource; +import javax.inject.Named; +import java.util.Map; +import java.util.Queue; +import java.util.SortedMap; +import java.util.concurrent.*; +import java.util.concurrent.atomic.AtomicInteger; + +import static com.google.common.base.Preconditions.checkNotNull; + +public class ParallelMultipartUploadStrategy implements AsyncMultipartUploadStrategy { + @Resource + @Named(BlobStoreConstants.BLOBSTORE_LOGGER) + protected Logger logger = Logger.NULL; + + public static final String PART_SEPARATOR = "/"; + @VisibleForTesting + static final int DEFAULT_PARALLEL_DEGREE = 4; + @VisibleForTesting + static final int DEFAULT_MIN_RETRIES = 5; + @VisibleForTesting + static final int DEFAULT_MAX_PERCENT_RETRIES = 10; + + @Inject(optional = true) + @Named("jclouds.mpu.parallel.degree") + @VisibleForTesting + int parallelDegree = DEFAULT_PARALLEL_DEGREE; + + @Inject(optional = true) + @Named("jclouds.mpu.parallel.retries.min") + @VisibleForTesting + int minRetries = DEFAULT_MIN_RETRIES; + + @Inject(optional = true) + @Named("jclouds.mpu.parallel.retries.maxpercent") + @VisibleForTesting + int maxPercentRetries = DEFAULT_MAX_PERCENT_RETRIES; + + /** + * maximum duration of an blob Request + */ + @Inject(optional = true) + @Named(Constants.PROPERTY_REQUEST_TIMEOUT) + protected Long maxTime; + + private final ExecutorService ioWorkerExecutor; + + protected final SwiftAsyncBlobStore ablobstore; + protected final PayloadSlicer slicer; + + @Inject + public ParallelMultipartUploadStrategy(SwiftAsyncBlobStore ablobstore, PayloadSlicer slicer, + @Named(Constants.PROPERTY_IO_WORKER_THREADS) ExecutorService ioWorkerExecutor) { + this.ablobstore = checkNotNull(ablobstore, "ablobstore"); + this.slicer = checkNotNull(slicer, "slicer"); + this.ioWorkerExecutor = checkNotNull(ioWorkerExecutor, "ioWorkerExecutor"); + } + + + protected void prepareUploadPart(final String container, final Blob blob, final String key, + final Integer part, final Payload payload, + final long offset, final long size, final SortedMap etags, + final BlockingQueue activeParts, + final Map> futureParts, + final AtomicInteger errors, final int maxRetries, final Map errorMap, + final Queue toRetry, final CountDownLatch latch, + BlobToObject blob2Object) { + if (errors.get() > maxRetries) { + activeParts.remove(part); // remove part from the bounded-queue without blocking + latch.countDown(); + return; + } + final CommonSwiftAsyncClient client = ablobstore.getContext().unwrap(SwiftApiMetadata.CONTEXT_TOKEN).getAsyncApi(); + Payload chunkedPart = slicer.slice(payload, offset, size); + logger.debug(String.format("async uploading part %s of %s to container %s", part, key, container)); + final long start = System.currentTimeMillis(); + String blobPartName = blob.getMetadata().getName() + PART_SEPARATOR + + String.valueOf(part); + + Blob blobPart = ablobstore.blobBuilder(blobPartName).payload(chunkedPart). + contentDisposition(blobPartName).build(); + final ListenableFuture futureETag = client.putObject(container, blob2Object.apply(blobPart)); + futureETag.addListener(new Runnable() { + @Override + public void run() { + try { + etags.put(part, futureETag.get()); + logger.debug(String.format("async uploaded part %s of %s to container %s in %sms", + part, key, container, (System.currentTimeMillis() - start))); + } catch (CancellationException e) { + errorMap.put(part, e); + String message = String.format("%s while uploading part %s - [%s,%s] to container %s with running since %dms", + e.getMessage(), part, offset, size, container, (System.currentTimeMillis() - start)); + logger.debug(message); + } catch (Exception e) { + errorMap.put(part, e); + String message = String.format("%s while uploading part %s - [%s,%s] to container %s running since %dms", + e.getMessage(), part, offset, size, container, (System.currentTimeMillis() - start)); + logger.error(message, e); + if (errors.incrementAndGet() <= maxRetries) + toRetry.add(new Part(part, offset, size)); + } finally { + activeParts.remove(part); // remove part from the bounded-queue without blocking + futureParts.remove(part); + latch.countDown(); + } + } + }, ioWorkerExecutor); + 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() { + @Override + public String call() throws Exception { + String key = blob.getMetadata().getName(); + Payload payload = blob.getPayload(); + MultipartUploadSlicingAlgorithm algorithm = new MultipartUploadSlicingAlgorithm(); + algorithm.calculateChunkSize(payload.getContentMetadata() + .getContentLength()); + int parts = algorithm.getParts(); + long chunkSize = algorithm.getChunkSize(); + long remaining = algorithm.getRemaining(); + if (parts > 0) { + CommonSwiftClient client = ablobstore.getContext().unwrap(SwiftApiMetadata.CONTEXT_TOKEN).getApi(); + final Map> futureParts = + new ConcurrentHashMap>(); + final Map errorMap = Maps.newHashMap(); + AtomicInteger errors = new AtomicInteger(0); + int maxRetries = Math.max(minRetries, parts * maxPercentRetries / 100); + int effectiveParts = remaining > 0 ? parts + 1 : parts; + try { + logger.debug(String.format("initiated multipart upload of %s to container %s" + + " consisting from %s part (possible max. retries: %d)", + key, container, effectiveParts, maxRetries)); + // we need a bounded-blocking queue to control the amount of parallel jobs + ArrayBlockingQueue activeParts = new ArrayBlockingQueue(parallelDegree); + Queue toRetry = new ConcurrentLinkedQueue(); + SortedMap etags = new ConcurrentSkipListMap(); + CountDownLatch latch = new CountDownLatch(effectiveParts); + int part; + while ((part = algorithm.getNextPart()) <= parts) { + Integer partKey = new Integer(part); + activeParts.put(partKey); + + prepareUploadPart(container, blob, key, partKey, payload, + algorithm.getNextChunkOffset(), chunkSize, etags, + activeParts, futureParts, errors, maxRetries, errorMap, toRetry, latch, + blob2Object); + } + if (remaining > 0) { + Integer partKey = new Integer(part); + activeParts.put(partKey); + prepareUploadPart(container, blob, key, partKey, payload, + algorithm.getNextChunkOffset(), remaining, etags, + activeParts, futureParts, errors, maxRetries, errorMap, toRetry, latch, + blob2Object); + } + latch.await(); + // handling retries + while (errors.get() <= maxRetries && toRetry.size() > 0) { + int atOnce = Math.min(Math.min(toRetry.size(), errors.get()), parallelDegree); + CountDownLatch retryLatch = new CountDownLatch(atOnce); + for (int i = 0; i < atOnce; i++) { + Part failedPart = toRetry.poll(); + Integer partKey = new Integer(failedPart.getPart()); + activeParts.put(partKey); + prepareUploadPart(container, blob, key, partKey, payload, + failedPart.getOffset(), failedPart.getSize(), etags, + activeParts, futureParts, errors, maxRetries, errorMap, toRetry, retryLatch, + blob2Object); + } + retryLatch.await(); + } + if (errors.get() > maxRetries) { + throw new BlobRuntimeException(String.format( + "Too many failed parts: %s while multipart upload of %s to container %s", + errors.get(), key, container)); + } + + String eTag = client.putObjectManifest(container, key); + logger.debug(String.format("multipart upload of %s to container %s" + + " succeffully finished with %s retries", key, container, errors.get())); + return eTag; + } catch (Exception ex) { + RuntimeException rtex = Throwables2.getFirstThrowableOfType(ex, RuntimeException.class); + if (rtex == null) { + rtex = new RuntimeException(ex); + } + for (Map.Entry> entry : futureParts.entrySet()) { + entry.getValue().cancel(false); + } + /* + if (uploadId != null) { + client.abortMultipartUpload(container, key, uploadId); + } */ + throw rtex; + } + } else { + ListenableFuture futureETag = ablobstore.putBlob(container, blob, options); + return maxTime != null ? + futureETag.get(maxTime, TimeUnit.SECONDS) : futureETag.get(); + } + } + }), ioWorkerExecutor); + } + + class Part { + private int part; + private long offset; + private long size; + + Part(int part, long offset, long size) { + this.part = part; + this.offset = offset; + this.size = size; + } + + public int getPart() { + return part; + } + + public void setPart(int part) { + this.part = part; + } + + public long getOffset() { + return offset; + } + + public void setOffset(long offset) { + this.offset = offset; + } + + public long getSize() { + return size; + } + + public void setSize(long size) { + this.size = size; + } + } +} diff --git a/apis/swift/src/main/java/org/jclouds/openstack/swift/blobstore/strategy/internal/SequentialMultipartUploadStrategy.java b/apis/swift/src/main/java/org/jclouds/openstack/swift/blobstore/strategy/internal/SequentialMultipartUploadStrategy.java new file mode 100644 index 0000000000..9618e25aa3 --- /dev/null +++ b/apis/swift/src/main/java/org/jclouds/openstack/swift/blobstore/strategy/internal/SequentialMultipartUploadStrategy.java @@ -0,0 +1,83 @@ +package org.jclouds.openstack.swift.blobstore.strategy.internal; + +import static com.google.common.base.Preconditions.checkNotNull; + +import javax.annotation.Resource; +import javax.inject.Named; + +import org.jclouds.blobstore.domain.Blob; +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.CommonSwiftClient; +import org.jclouds.openstack.swift.SwiftApiMetadata; +import org.jclouds.openstack.swift.blobstore.SwiftBlobStore; +import org.jclouds.openstack.swift.blobstore.functions.BlobToObject; +import org.jclouds.util.Throwables2; + +import com.google.inject.Inject; + + +public class SequentialMultipartUploadStrategy implements MultipartUploadStrategy { + public static final String PART_SEPARATOR = "/"; + + @Resource + @Named(BlobStoreConstants.BLOBSTORE_LOGGER) + protected Logger logger = Logger.NULL; + + protected final SwiftBlobStore ablobstore; + protected final PayloadSlicer slicer; + + @Inject + public SequentialMultipartUploadStrategy(SwiftBlobStore ablobstore, PayloadSlicer slicer) { + this.ablobstore = checkNotNull(ablobstore, "ablobstore"); + this.slicer = checkNotNull(slicer, "slicer"); + } + + @Override + public String execute(String container, Blob blob, PutOptions options, BlobToObject blob2Object) { + String key = blob.getMetadata().getName(); + Payload payload = blob.getPayload(); + MultipartUploadSlicingAlgorithm algorithm = new MultipartUploadSlicingAlgorithm(); + algorithm + .calculateChunkSize(checkNotNull( + payload.getContentMetadata().getContentLength(), + "contentLength required on all uploads to swift; please invoke payload.getContentMetadata().setContentLength(length) first")); + int parts = algorithm.getParts(); + long chunkSize = algorithm.getChunkSize(); + if (parts > 0) { + CommonSwiftClient client = ablobstore.getContext().unwrap(SwiftApiMetadata.CONTEXT_TOKEN).getApi(); + try { + int part; + while ((part = algorithm.getNextPart()) <= parts) { + Payload chunkedPart = slicer.slice(payload, + algorithm.getNextChunkOffset(), chunkSize); + Blob blobPart = ablobstore.blobBuilder(blob.getMetadata().getName() + PART_SEPARATOR + + String.valueOf(part)).payload(chunkedPart).contentDisposition( + blob.getMetadata().getName() + PART_SEPARATOR + String.valueOf(part)).build(); + client.putObject(container, blob2Object.apply(blobPart)); + } + long remaining = algorithm.getRemaining(); + if (remaining > 0) { + Payload chunkedPart = slicer.slice(payload, + algorithm.getNextChunkOffset(), remaining); + Blob blobPart = ablobstore.blobBuilder(blob.getMetadata().getName() + PART_SEPARATOR + + String.valueOf(part)).payload(chunkedPart).contentDisposition( + blob.getMetadata().getName() + PART_SEPARATOR + String.valueOf(part)).build(); + client.putObject(container, blob2Object.apply(blobPart)); + } + return client.putObjectManifest(container, key); + } catch (Exception ex) { + RuntimeException rtex = Throwables2.getFirstThrowableOfType(ex, RuntimeException.class); + if (rtex == null) { + rtex = new RuntimeException(ex); + } + throw rtex; + } + } else { + return ablobstore.putBlob(container, blob, PutOptions.NONE); + } + } +} diff --git a/apis/swift/src/test/java/org/jclouds/openstack/swift/SwiftClientLiveTest.java b/apis/swift/src/test/java/org/jclouds/openstack/swift/SwiftClientLiveTest.java index 06a26a5ca3..6a06670bc9 100644 --- a/apis/swift/src/test/java/org/jclouds/openstack/swift/SwiftClientLiveTest.java +++ b/apis/swift/src/test/java/org/jclouds/openstack/swift/SwiftClientLiveTest.java @@ -33,7 +33,7 @@ public class SwiftClientLiveTest extends CommonSwiftClientLiveTest @Override public SwiftClient getApi() { - return context.unwrap(SwiftApiMetadata.CONTEXT_TOKEN).getApi(); + return view.unwrap(SwiftApiMetadata.CONTEXT_TOKEN).getApi(); } } diff --git a/apis/swift/src/test/java/org/jclouds/openstack/swift/blobstore/integration/SwiftBlobIntegrationLiveTest.java b/apis/swift/src/test/java/org/jclouds/openstack/swift/blobstore/integration/SwiftBlobIntegrationLiveTest.java index 8268a4a339..aaddb68017 100644 --- a/apis/swift/src/test/java/org/jclouds/openstack/swift/blobstore/integration/SwiftBlobIntegrationLiveTest.java +++ b/apis/swift/src/test/java/org/jclouds/openstack/swift/blobstore/integration/SwiftBlobIntegrationLiveTest.java @@ -18,11 +18,20 @@ */ package org.jclouds.openstack.swift.blobstore.integration; +import com.google.common.io.ByteStreams; +import com.google.common.io.InputSupplier; +import org.jclouds.blobstore.BlobStore; import org.jclouds.blobstore.domain.Blob; import org.jclouds.blobstore.integration.internal.BaseBlobIntegrationTest; +import org.jclouds.blobstore.options.PutOptions; +import org.jclouds.crypto.CryptoStreams; +import org.testng.ITestContext; +import org.testng.annotations.BeforeClass; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; +import java.io.*; + /** * * @author James Murty @@ -30,6 +39,9 @@ import org.testng.annotations.Test; */ @Test(groups = "live") public class SwiftBlobIntegrationLiveTest extends BaseBlobIntegrationTest { + private InputSupplier oneHundredOneConstitutions; + private byte[] oneHundredOneConstitutionsMD5; + public SwiftBlobIntegrationLiveTest() { provider = "swift"; } @@ -39,6 +51,13 @@ public class SwiftBlobIntegrationLiveTest extends BaseBlobIntegrationTest { // not supported in swift } + @BeforeClass(groups = { "integration", "live" }, dependsOnMethods = "setupContext") + @Override + public void setUpResourcesOnThisThread(ITestContext testContext) throws Exception { + super.setUpResourcesOnThisThread(testContext); + oneHundredOneConstitutions = getTestDataSupplier(); + oneHundredOneConstitutionsMD5 = CryptoStreams.md5(oneHundredOneConstitutions); + } @Override protected void checkContentDisposition(Blob blob, String contentDisposition) { @@ -61,4 +80,22 @@ public class SwiftBlobIntegrationLiveTest extends BaseBlobIntegrationTest { return new Object[][] { { "normal" }, { "sp ace" }, { "qu?stion" }, { "unic₪de" }, { "path/foo" }, { "colon:" }, { "asteri*k" }, { "{greaten" }, { "p|pe" } }; } + + public void testMultipartChunkedFileStream() throws IOException, InterruptedException { + FileOutputStream fous = new FileOutputStream(new File("target/const.txt")); + ByteStreams.copy(oneHundredOneConstitutions.getInput(), fous); + fous.flush(); + fous.close(); + String containerName = getContainerName(); + + try { + BlobStore blobStore = view.getBlobStore(); + blobStore.createContainerInLocation(null, containerName); + Blob blob = blobStore.blobBuilder("const.txt") + .payload(new File("target/const.txt")).contentMD5(oneHundredOneConstitutionsMD5).build(); + blobStore.putBlob(containerName, blob, PutOptions.Builder.multipart()); + } finally { + returnContainer(containerName); + } + } } diff --git a/apis/swift/src/test/java/org/jclouds/openstack/swift/blobstore/integration/SwiftContainerLiveTest.java b/apis/swift/src/test/java/org/jclouds/openstack/swift/blobstore/integration/SwiftContainerLiveTest.java index 7901ac4fa8..cbd39b5c15 100644 --- a/apis/swift/src/test/java/org/jclouds/openstack/swift/blobstore/integration/SwiftContainerLiveTest.java +++ b/apis/swift/src/test/java/org/jclouds/openstack/swift/blobstore/integration/SwiftContainerLiveTest.java @@ -27,12 +27,13 @@ import org.testng.annotations.Test; /** * @author Adrian Cole */ -@Test(groups = { "live" }) +@Test(groups = "live", testName = "SwiftContainerLiveTest" ) public class SwiftContainerLiveTest extends BaseContainerLiveTest { public SwiftContainerLiveTest() { provider = "swift"; } - @Test(expectedExceptions=UnsupportedOperationException.class) + + @Test(expectedExceptions = UnsupportedOperationException.class) public void testPublicAccess() throws MalformedURLException, InterruptedException, IOException { super.testPublicAccess(); } 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 01ccfe458b..308a62a2cf 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 @@ -167,7 +167,12 @@ public class StubSwiftAsyncClient implements CommonSwiftAsyncClient { return blobStore.removeBlob(container, key); } - public ListenableFuture setObjectInfo(String container, String key, Map userMetadata) { + @Override + public ListenableFuture putObjectManifest(String container, String name) { + return null; + } + + public ListenableFuture setObjectInfo(String container, String key, Map userMetadata) { throw new UnsupportedOperationException(); } diff --git a/apis/vcloud/src/main/java/org/jclouds/vcloud/VCloudApiMetadata.java b/apis/vcloud/src/main/java/org/jclouds/vcloud/VCloudApiMetadata.java index eeb118be97..191d14ae5d 100644 --- a/apis/vcloud/src/main/java/org/jclouds/vcloud/VCloudApiMetadata.java +++ b/apis/vcloud/src/main/java/org/jclouds/vcloud/VCloudApiMetadata.java @@ -96,7 +96,7 @@ public class VCloudApiMetadata extends BaseRestApiMetadata { .documentation(URI.create("http://www.vmware.com/support/pubs/vcd_pubs.html")) .version("1.0") .defaultProperties(VCloudApiMetadata.defaultProperties()) - .wrapper(TypeToken.of(ComputeServiceContext.class)) + .view(TypeToken.of(ComputeServiceContext.class)) .defaultModules(ImmutableSet.>of(VCloudRestClientModule.class, VCloudComputeServiceContextModule.class)); } diff --git a/apis/vcloud/src/main/java/org/jclouds/vcloud/compute/strategy/InstantiateVAppTemplateWithGroupEncodedIntoNameThenCustomizeDeployAndPowerOn.java b/apis/vcloud/src/main/java/org/jclouds/vcloud/compute/strategy/InstantiateVAppTemplateWithGroupEncodedIntoNameThenCustomizeDeployAndPowerOn.java index b307b877a4..83300a54aa 100644 --- a/apis/vcloud/src/main/java/org/jclouds/vcloud/compute/strategy/InstantiateVAppTemplateWithGroupEncodedIntoNameThenCustomizeDeployAndPowerOn.java +++ b/apis/vcloud/src/main/java/org/jclouds/vcloud/compute/strategy/InstantiateVAppTemplateWithGroupEncodedIntoNameThenCustomizeDeployAndPowerOn.java @@ -22,7 +22,6 @@ import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Predicates.not; import static com.google.common.collect.Iterables.find; import static com.google.common.collect.Iterables.get; -import static org.jclouds.Constants.PROPERTY_BUILD_VERSION; import static org.jclouds.compute.util.ComputeServiceUtils.getCores; import static org.jclouds.vcloud.compute.util.VCloudComputeUtils.getCredentialsFrom; import static org.jclouds.vcloud.options.InstantiateVAppTemplateOptions.Builder.addNetworkConfig; @@ -41,17 +40,18 @@ import org.jclouds.javax.annotation.Nullable; import org.jclouds.logging.Logger; import org.jclouds.ovf.Network; import org.jclouds.predicates.validators.DnsNameValidator; +import org.jclouds.rest.annotations.BuildVersion; import org.jclouds.vcloud.TaskStillRunningException; import org.jclouds.vcloud.VCloudClient; import org.jclouds.vcloud.compute.options.VCloudTemplateOptions; import org.jclouds.vcloud.domain.GuestCustomizationSection; import org.jclouds.vcloud.domain.NetworkConnection; import org.jclouds.vcloud.domain.NetworkConnectionSection; -import org.jclouds.vcloud.domain.NetworkConnectionSection.Builder; import org.jclouds.vcloud.domain.Task; import org.jclouds.vcloud.domain.VApp; import org.jclouds.vcloud.domain.VAppTemplate; import org.jclouds.vcloud.domain.Vm; +import org.jclouds.vcloud.domain.NetworkConnectionSection.Builder; import org.jclouds.vcloud.domain.network.IpAddressAllocationMode; import org.jclouds.vcloud.domain.network.NetworkConfig; import org.jclouds.vcloud.options.InstantiateVAppTemplateOptions; @@ -79,7 +79,7 @@ public class InstantiateVAppTemplateWithGroupEncodedIntoNameThenCustomizeDeployA @Inject protected InstantiateVAppTemplateWithGroupEncodedIntoNameThenCustomizeDeployAndPowerOn(VCloudClient client, Predicate successTester, LoadingCache vAppTemplates, - Supplier defaultNetworkConfig, @Named(PROPERTY_BUILD_VERSION) String buildVersion) { + Supplier defaultNetworkConfig, @BuildVersion String buildVersion) { this.client = client; this.successTester = successTester; this.vAppTemplates = vAppTemplates; diff --git a/apis/vcloud/src/main/java/org/jclouds/vcloud/config/DefaultVCloudReferencesModule.java b/apis/vcloud/src/main/java/org/jclouds/vcloud/config/DefaultVCloudReferencesModule.java index 314825fc36..fe8c4088a9 100644 --- a/apis/vcloud/src/main/java/org/jclouds/vcloud/config/DefaultVCloudReferencesModule.java +++ b/apis/vcloud/src/main/java/org/jclouds/vcloud/config/DefaultVCloudReferencesModule.java @@ -18,17 +18,15 @@ */ package org.jclouds.vcloud.config; -import static org.jclouds.Constants.PROPERTY_IDENTITY; - import java.net.URI; import java.util.Map; import javax.annotation.Resource; import javax.inject.Inject; -import javax.inject.Named; import javax.inject.Singleton; import org.jclouds.logging.Logger; +import org.jclouds.rest.annotations.Identity; import org.jclouds.vcloud.domain.Catalog; import org.jclouds.vcloud.domain.ReferenceType; @@ -58,7 +56,7 @@ public class DefaultVCloudReferencesModule extends AbstractModule { @org.jclouds.vcloud.endpoints.Org @Singleton protected Supplier provideDefaultOrg(DefaultOrgForUser defaultOrgURIForUser, - @Named(PROPERTY_IDENTITY) String user) { + @Identity String user) { return defaultOrgURIForUser.apply(user); } diff --git a/apis/vcloud/src/main/java/org/jclouds/vcloud/config/VCloudRestClientModule.java b/apis/vcloud/src/main/java/org/jclouds/vcloud/config/VCloudRestClientModule.java index 96d82e0201..c84b1a37d6 100644 --- a/apis/vcloud/src/main/java/org/jclouds/vcloud/config/VCloudRestClientModule.java +++ b/apis/vcloud/src/main/java/org/jclouds/vcloud/config/VCloudRestClientModule.java @@ -27,17 +27,16 @@ import static com.google.common.collect.Iterables.filter; import static com.google.common.collect.Iterables.getLast; import static com.google.common.collect.Iterables.transform; import static com.google.common.collect.Maps.transformValues; -import static org.jclouds.Constants.PROPERTY_API_VERSION; import static org.jclouds.Constants.PROPERTY_SESSION_INTERVAL; import static org.jclouds.rest.config.BinderUtils.bindClientAndAsyncClient; +import static org.jclouds.util.Maps2.uniqueIndex; import static org.jclouds.vcloud.reference.VCloudConstants.PROPERTY_VCLOUD_DEFAULT_FENCEMODE; import static org.jclouds.vcloud.reference.VCloudConstants.PROPERTY_VCLOUD_TIMEOUT_TASK_COMPLETED; -import static org.jclouds.util.Maps2.uniqueIndex; import java.net.URI; import java.util.Map; -import java.util.Map.Entry; import java.util.SortedMap; +import java.util.Map.Entry; import java.util.concurrent.atomic.AtomicReference; import javax.inject.Inject; @@ -56,6 +55,7 @@ import org.jclouds.ovf.Envelope; import org.jclouds.predicates.RetryablePredicate; import org.jclouds.rest.AuthorizationException; import org.jclouds.rest.ConfiguresRestClient; +import org.jclouds.rest.annotations.ApiVersion; import org.jclouds.rest.config.RestClientModule; import org.jclouds.rest.suppliers.MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier; import org.jclouds.vcloud.VCloudAsyncClient; @@ -117,8 +117,8 @@ import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheLoader; import com.google.common.cache.LoadingCache; import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableMap.Builder; import com.google.common.collect.Lists; +import com.google.common.collect.ImmutableMap.Builder; import com.google.inject.Injector; import com.google.inject.Provides; import com.google.inject.Scopes; @@ -390,7 +390,7 @@ public class VCloudRestClientModule extends RestClientModule provideAuthenticationURI(final VCloudVersionsClient versionService, - @Named(PROPERTY_API_VERSION) final String version) { + @ApiVersion final String version) { return new Supplier() { @Override diff --git a/apis/vcloud/src/test/java/org/jclouds/vcloud/features/CatalogClientLiveTest.java b/apis/vcloud/src/test/java/org/jclouds/vcloud/features/CatalogClientLiveTest.java index 36ee0a4b00..54c5021ad8 100644 --- a/apis/vcloud/src/test/java/org/jclouds/vcloud/features/CatalogClientLiveTest.java +++ b/apis/vcloud/src/test/java/org/jclouds/vcloud/features/CatalogClientLiveTest.java @@ -49,7 +49,7 @@ public class CatalogClientLiveTest extends BaseVCloudClientLiveTest { public void testFindCatalogIsWriteableIfNotVersion1_5() throws Exception { // when we are in vCloud 1.0.0 public catalogs don't work, so our default // catalog is private - if (!context.utils().injector().getInstance(Key.get(String.class, ApiVersion.class)).startsWith("1.5")) + if (!view.utils().injector().getInstance(Key.get(String.class, ApiVersion.class)).startsWith("1.5")) assertTrue(getVCloudApi().getCatalogClient().findCatalogInOrgNamed(null, null).isReadOnly()); } } \ No newline at end of file diff --git a/apis/vcloud/src/test/java/org/jclouds/vcloud/internal/BaseVCloudClientLiveTest.java b/apis/vcloud/src/test/java/org/jclouds/vcloud/internal/BaseVCloudClientLiveTest.java index e806763fe3..40c68aff3d 100644 --- a/apis/vcloud/src/test/java/org/jclouds/vcloud/internal/BaseVCloudClientLiveTest.java +++ b/apis/vcloud/src/test/java/org/jclouds/vcloud/internal/BaseVCloudClientLiveTest.java @@ -45,14 +45,14 @@ public abstract class BaseVCloudClientLiveTest extends BaseComputeServiceContext } protected VCloudClient getVCloudApi() { - return VCloudClient.class.cast(context.unwrap(VCloudApiMetadata.CONTEXT_TOKEN).getApi()); + return VCloudClient.class.cast(view.unwrap(VCloudApiMetadata.CONTEXT_TOKEN).getApi()); } @Override @BeforeClass(groups = { "integration", "live" }) public void setupContext() { super.setupContext(); - client = context.getComputeService(); + client = view.getComputeService(); } @Override diff --git a/blobstore/src/main/java/org/jclouds/blobstore/BlobStoreContext.java b/blobstore/src/main/java/org/jclouds/blobstore/BlobStoreContext.java index c30a7adb7d..0be3c4d23d 100644 --- a/blobstore/src/main/java/org/jclouds/blobstore/BlobStoreContext.java +++ b/blobstore/src/main/java/org/jclouds/blobstore/BlobStoreContext.java @@ -20,7 +20,7 @@ package org.jclouds.blobstore; import java.io.Closeable; -import org.jclouds.Wrapper; +import org.jclouds.View; import org.jclouds.blobstore.attr.ConsistencyModel; import org.jclouds.blobstore.internal.BlobStoreContextImpl; import org.jclouds.blobstore.options.ListContainerOptions; @@ -37,7 +37,7 @@ import com.google.inject.ImplementedBy; * */ @ImplementedBy(BlobStoreContextImpl.class) -public interface BlobStoreContext extends Closeable, Wrapper { +public interface BlobStoreContext extends Closeable, View { /** * * Generates signed requests for blobs. useful in other tools such as backup utilities. @@ -119,8 +119,8 @@ public interface BlobStoreContext extends Closeable, Wrapper { /** * will be removed in jclouds 1.6 * - * @see Wrapper#getInputType - * @see Wrapper#unwrap + * @see View#getInputType + * @see View#unwrap */ @Deprecated RestContext getProviderSpecificContext(); diff --git a/blobstore/src/main/java/org/jclouds/blobstore/TransientApiMetadata.java b/blobstore/src/main/java/org/jclouds/blobstore/TransientApiMetadata.java index 88f9fc1d07..82256b19ac 100644 --- a/blobstore/src/main/java/org/jclouds/blobstore/TransientApiMetadata.java +++ b/blobstore/src/main/java/org/jclouds/blobstore/TransientApiMetadata.java @@ -61,7 +61,7 @@ public class TransientApiMetadata extends BaseApiMetadata { .defaultIdentity(System.getProperty("user.name")) .defaultCredential("bar") .version("1") - .wrapper(BlobStoreContext.class) + .view(BlobStoreContext.class) .defaultModule(TransientBlobStoreContextModule.class) .documentation(URI.create("http://www.jclouds.org/documentation/userguide/blobstore-guide")); } diff --git a/blobstore/src/main/java/org/jclouds/blobstore/internal/BlobStoreContextImpl.java b/blobstore/src/main/java/org/jclouds/blobstore/internal/BlobStoreContextImpl.java index 3a08168b26..64ab7f718f 100644 --- a/blobstore/src/main/java/org/jclouds/blobstore/internal/BlobStoreContextImpl.java +++ b/blobstore/src/main/java/org/jclouds/blobstore/internal/BlobStoreContextImpl.java @@ -20,11 +20,10 @@ package org.jclouds.blobstore.internal; import static com.google.common.base.Preconditions.checkNotNull; -import java.io.Closeable; - import javax.inject.Inject; import javax.inject.Singleton; +import org.jclouds.Context; import org.jclouds.blobstore.AsyncBlobStore; import org.jclouds.blobstore.BlobMap; import org.jclouds.blobstore.BlobRequestSigner; @@ -33,7 +32,7 @@ import org.jclouds.blobstore.BlobStoreContext; import org.jclouds.blobstore.InputStreamMap; import org.jclouds.blobstore.attr.ConsistencyModel; import org.jclouds.blobstore.options.ListContainerOptions; -import org.jclouds.internal.BaseWrapper; +import org.jclouds.internal.BaseView; import org.jclouds.location.Provider; import org.jclouds.rest.RestContext; import org.jclouds.rest.Utils; @@ -45,7 +44,7 @@ import com.google.common.reflect.TypeToken; * @author Adrian Cole */ @Singleton -public class BlobStoreContextImpl extends BaseWrapper implements BlobStoreContext { +public class BlobStoreContextImpl extends BaseView implements BlobStoreContext { private final BlobMap.Factory blobMapFactory; private final InputStreamMap.Factory inputStreamMapFactory; private final AsyncBlobStore ablobStore; @@ -55,11 +54,11 @@ public class BlobStoreContextImpl extends BaseWrapper implements BlobStoreContex private final BlobRequestSigner blobRequestSigner; @Inject - public BlobStoreContextImpl(@Provider Closeable wrapped, @Provider TypeToken wrappedType, + public BlobStoreContextImpl(@Provider Context backend, @Provider TypeToken backendType, BlobMap.Factory blobMapFactory, Utils utils, ConsistencyModel consistencyModel, InputStreamMap.Factory inputStreamMapFactory, AsyncBlobStore ablobStore, BlobStore blobStore, BlobRequestSigner blobRequestSigner) { - super(wrapped, wrappedType); + super(backend, backendType); this.consistencyModel = checkNotNull(consistencyModel, "consistencyModel"); this.blobMapFactory = checkNotNull(blobMapFactory, "blobMapFactory"); this.inputStreamMapFactory = checkNotNull(inputStreamMapFactory, "inputStreamMapFactory"); @@ -122,26 +121,26 @@ public class BlobStoreContextImpl extends BaseWrapper implements BlobStoreContex @SuppressWarnings("unchecked") @Override public RestContext getProviderSpecificContext() { - return (RestContext) getWrapped(); + return (RestContext) delegate(); } @Override public void close() { - Closeables.closeQuietly(getWrapped()); + Closeables.closeQuietly(delegate()); } public int hashCode() { - return getWrapped().hashCode(); + return delegate().hashCode(); } @Override public String toString() { - return getWrapped().toString(); + return delegate().toString(); } @Override public boolean equals(Object obj) { - return getWrapped().equals(obj); + return delegate().equals(obj); } } diff --git a/blobstore/src/test/java/org/jclouds/blobstore/integration/TransientContainerIntegrationTest.java b/blobstore/src/test/java/org/jclouds/blobstore/integration/TransientContainerIntegrationTest.java index 5ab15a7137..ee01ee3206 100644 --- a/blobstore/src/test/java/org/jclouds/blobstore/integration/TransientContainerIntegrationTest.java +++ b/blobstore/src/test/java/org/jclouds/blobstore/integration/TransientContainerIntegrationTest.java @@ -53,7 +53,7 @@ public class TransientContainerIntegrationTest extends BaseContainerIntegrationT String key = "hello"; // NOTE all metadata in jclouds comes out as lowercase, in an effort to normalize the // providers. - Blob blob = context.getBlobStore().blobBuilder("hello").userMetadata(ImmutableMap.of("Adrian", "powderpuff")) + Blob blob = view.getBlobStore().blobBuilder("hello").userMetadata(ImmutableMap.of("Adrian", "powderpuff")) .payload(TEST_STRING).contentType(MediaType.TEXT_PLAIN).build(); String containerName = getContainerName(); @@ -61,7 +61,7 @@ public class TransientContainerIntegrationTest extends BaseContainerIntegrationT addBlobToContainer(containerName, blob); validateContent(containerName, key); - PageSet container = context.getBlobStore().list(containerName, maxResults(1)); + PageSet container = view.getBlobStore().list(containerName, maxResults(1)); BlobMetadata metadata = (BlobMetadata) getOnlyElement(container); // transient container should be lenient and not return metadata on undetailed listing. @@ -75,7 +75,7 @@ public class TransientContainerIntegrationTest extends BaseContainerIntegrationT @Test(groups = { "integration", "live" }) public void testDuplicateCreateContainer() { - BlobStore blobStore = context.getBlobStore(); + BlobStore blobStore = view.getBlobStore(); Location location = null; String container = "container"; boolean created; 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 e9aac1bc3a..753d27bb2f 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 @@ -141,15 +141,15 @@ public class BaseBlobIntegrationTest extends BaseBlobStoreIntegrationTest { @Override public Void call() throws Exception { String name = blobCount.incrementAndGet() + ""; - Blob blob = context.getBlobStore().blobBuilder(name).payload(testPayload).build(); - context.getBlobStore().putBlob(container, blob); + Blob blob = view.getBlobStore().blobBuilder(name).payload(testPayload).build(); + view.getBlobStore().putBlob(container, blob); assertConsistencyAwareBlobExists(container, name); - blob = context.getBlobStore().getBlob(container, name); + blob = view.getBlobStore().getBlob(container, name); assert Arrays.equals(CryptoStreams.md5(blob.getPayload()), md5) : String.format( "md5 didn't match on %s/%s", container, name); - context.getBlobStore().removeBlob(container, name); + view.getBlobStore().removeBlob(container, name); assertConsistencyAwareBlobDoesntExist(container, name); return null; } @@ -176,7 +176,7 @@ public class BaseBlobIntegrationTest extends BaseBlobStoreIntegrationTest { Map> responses = Maps.newHashMap(); for (int i = 0; i < 10; i++) { - responses.put(i, Futures.compose(context.getAsyncBlobStore().getBlob(container, name), + responses.put(i, Futures.compose(view.getAsyncBlobStore().getBlob(container, name), new Function() { @Override @@ -204,9 +204,9 @@ public class BaseBlobIntegrationTest extends BaseBlobStoreIntegrationTest { } private void uploadConstitution(String container, String name, String contentDisposition) throws IOException { - context.getBlobStore().putBlob( + view.getBlobStore().putBlob( container, - context.getBlobStore().blobBuilder(name).payload(oneHundredOneConstitutions.getInput()).contentType( + view.getBlobStore().blobBuilder(name).payload(oneHundredOneConstitutions.getInput()).contentType( "text/plain").contentMD5(oneHundredOneConstitutionsMD5).contentLength( oneHundredOneConstitutionsLength).contentDisposition(contentDisposition).build()); } @@ -224,11 +224,11 @@ public class BaseBlobIntegrationTest extends BaseBlobStoreIntegrationTest { addObjectAndValidateContent(container, name); Date after = new Date(System.currentTimeMillis() + 1000); - context.getBlobStore().getBlob(container, name, ifModifiedSince(before)); + view.getBlobStore().getBlob(container, name, ifModifiedSince(before)); validateContent(container, name); try { - context.getBlobStore().getBlob(container, name, ifModifiedSince(after)); + view.getBlobStore().getBlob(container, name, ifModifiedSince(after)); validateContent(container, name); } catch (HttpResponseException ex) { assertEquals(ex.getResponse().getStatusCode(), 304); @@ -250,11 +250,11 @@ public class BaseBlobIntegrationTest extends BaseBlobStoreIntegrationTest { addObjectAndValidateContent(container, name); Date after = new Date(System.currentTimeMillis() + 1000); - context.getBlobStore().getBlob(container, name, ifUnmodifiedSince(after)); + view.getBlobStore().getBlob(container, name, ifUnmodifiedSince(after)); validateContent(container, name); try { - context.getBlobStore().getBlob(container, name, ifUnmodifiedSince(before)); + view.getBlobStore().getBlob(container, name, ifUnmodifiedSince(before)); validateContent(container, name); } catch (HttpResponseException ex) { assertEquals(ex.getResponse().getStatusCode(), 412); @@ -273,11 +273,11 @@ public class BaseBlobIntegrationTest extends BaseBlobStoreIntegrationTest { String goodETag = addObjectAndValidateContent(container, name); - context.getBlobStore().getBlob(container, name, ifETagMatches(goodETag)); + view.getBlobStore().getBlob(container, name, ifETagMatches(goodETag)); validateContent(container, name); try { - context.getBlobStore().getBlob(container, name, ifETagMatches("powerfrisbee")); + view.getBlobStore().getBlob(container, name, ifETagMatches("powerfrisbee")); validateContent(container, name); } catch (HttpResponseException ex) { assertEquals(ex.getResponse().getStatusCode(), 412); @@ -296,11 +296,11 @@ public class BaseBlobIntegrationTest extends BaseBlobStoreIntegrationTest { String goodETag = addObjectAndValidateContent(container, name); - context.getBlobStore().getBlob(container, name, ifETagDoesntMatch("powerfrisbee")); + view.getBlobStore().getBlob(container, name, ifETagDoesntMatch("powerfrisbee")); validateContent(container, name); try { - context.getBlobStore().getBlob(container, name, ifETagDoesntMatch(goodETag)); + view.getBlobStore().getBlob(container, name, ifETagDoesntMatch(goodETag)); } catch (HttpResponseException ex) { assertEquals(ex.getResponse().getStatusCode(), 304); } @@ -317,11 +317,11 @@ public class BaseBlobIntegrationTest extends BaseBlobStoreIntegrationTest { String name = "apples"; addObjectAndValidateContent(container, name); - Blob blob1 = context.getBlobStore().getBlob(container, name, range(0, 5)); + Blob blob1 = view.getBlobStore().getBlob(container, name, range(0, 5)); validateMetadata(blob1.getMetadata(), container, name); assertEquals(getContentAsStringOrNullAndClose(blob1), TEST_STRING.substring(0, 6)); - Blob blob2 = context.getBlobStore().getBlob(container, name, range(6, TEST_STRING.length())); + Blob blob2 = view.getBlobStore().getBlob(container, name, range(6, TEST_STRING.length())); validateMetadata(blob2.getMetadata(), container, name); assertEquals(getContentAsStringOrNullAndClose(blob2), TEST_STRING.substring(6, TEST_STRING.length())); } finally { @@ -337,7 +337,7 @@ public class BaseBlobIntegrationTest extends BaseBlobStoreIntegrationTest { String name = "apples"; addObjectAndValidateContent(container, name); - Blob blob = context.getBlobStore().getBlob(container, name, range(0, 5).range(6, TEST_STRING.length())); + Blob blob = view.getBlobStore().getBlob(container, name, range(0, 5).range(6, TEST_STRING.length())); validateMetadata(blob.getMetadata(), container, name); assertEquals(getContentAsStringOrNullAndClose(blob), TEST_STRING); } finally { @@ -401,7 +401,7 @@ public class BaseBlobIntegrationTest extends BaseBlobStoreIntegrationTest { String container = getContainerName(); String name = "test"; try { - context.getBlobStore().removeBlob(container, name); + view.getBlobStore().removeBlob(container, name); } finally { returnContainer(container); } @@ -412,7 +412,7 @@ public class BaseBlobIntegrationTest extends BaseBlobStoreIntegrationTest { String container = getContainerName(); String name = "test"; try { - assert !context.getBlobStore().blobExists(container, name); + assert !view.getBlobStore().blobExists(container, name); } finally { returnContainer(container); } @@ -429,7 +429,7 @@ public class BaseBlobIntegrationTest extends BaseBlobStoreIntegrationTest { String container = getContainerName(); try { addBlobToContainer(container, name, name, MediaType.TEXT_PLAIN); - context.getBlobStore().removeBlob(container, name); + view.getBlobStore().removeBlob(container, name); assertContainerEmptyDeleting(container, name); } finally { returnContainer(container); @@ -437,7 +437,7 @@ public class BaseBlobIntegrationTest extends BaseBlobStoreIntegrationTest { } private void assertContainerEmptyDeleting(String container, String name) { - Iterable listing = Iterables.filter(context.getBlobStore().list(container), + Iterable listing = Iterables.filter(view.getBlobStore().list(container), new Predicate() { @Override @@ -454,7 +454,7 @@ public class BaseBlobIntegrationTest extends BaseBlobStoreIntegrationTest { @Test(groups = { "integration", "live" }) public void deleteObjectNoContainer() { try { - context.getBlobStore().removeBlob("donb", "test"); + view.getBlobStore().removeBlob("donb", "test"); } catch (HttpResponseException e) { assertEquals(e.getResponse().getStatusCode(), 404); } catch (ContainerNotFoundException e) { @@ -475,7 +475,7 @@ public class BaseBlobIntegrationTest extends BaseBlobStoreIntegrationTest { @Test(groups = { "integration", "live" }, dataProvider = "putTests") public void testPutObject(String name, String type, Object content, Object realObject) throws InterruptedException, IOException { - PayloadBlobBuilder blobBuilder = context.getBlobStore().blobBuilder(name).payload(Payloads.newPayload(content)) + PayloadBlobBuilder blobBuilder = view.getBlobStore().blobBuilder(name).payload(Payloads.newPayload(content)) .contentType(type); addContentMetadata(blobBuilder); if (content instanceof InputStream) { @@ -484,14 +484,14 @@ public class BaseBlobIntegrationTest extends BaseBlobStoreIntegrationTest { Blob blob = blobBuilder.build(); String container = getContainerName(); try { - assertNotNull(context.getBlobStore().putBlob(container, blob)); - blob = context.getBlobStore().getBlob(container, blob.getMetadata().getName()); + assertNotNull(view.getBlobStore().putBlob(container, blob)); + blob = view.getBlobStore().getBlob(container, blob.getMetadata().getName()); validateMetadata(blob.getMetadata(), container, name); checkContentMetadata(blob); String returnedString = getContentAsStringOrNullAndClose(blob); assertEquals(returnedString, realObject); - PageSet set = context.getBlobStore().list(container); + PageSet set = view.getBlobStore().list(container); assert set.size() == 1 : set; } finally { returnContainer(container); @@ -500,7 +500,7 @@ public class BaseBlobIntegrationTest extends BaseBlobStoreIntegrationTest { @Test(groups = { "integration", "live" }) public void testPutObjectStream() throws InterruptedException, IOException, ExecutionException { - PayloadBlobBuilder blobBuilder = context.getBlobStore().blobBuilder("streaming").payload( + PayloadBlobBuilder blobBuilder = view.getBlobStore().blobBuilder("streaming").payload( new StreamingPayload(new WriteTo() { @Override public void writeTo(OutputStream outstream) throws IOException { @@ -514,14 +514,14 @@ public class BaseBlobIntegrationTest extends BaseBlobStoreIntegrationTest { String container = getContainerName(); try { - assertNotNull(context.getBlobStore().putBlob(container, blob)); + assertNotNull(view.getBlobStore().putBlob(container, blob)); - blob = context.getBlobStore().getBlob(container, blob.getMetadata().getName()); + blob = view.getBlobStore().getBlob(container, blob.getMetadata().getName()); String returnedString = getContentAsStringOrNullAndClose(blob); assertEquals(returnedString, "foo"); validateMetadata(blob.getMetadata(), container, blob.getMetadata().getName()); checkContentMetadata(blob); - PageSet set = context.getBlobStore().list(container); + PageSet set = view.getBlobStore().list(container); assert set.size() == 1 : set; } finally { returnContainer(container); @@ -588,11 +588,11 @@ public class BaseBlobIntegrationTest extends BaseBlobStoreIntegrationTest { // NOTE all metadata in jclouds comes out as lowercase, in an effort to // normalize the // providers. - Blob blob = context.getBlobStore().blobBuilder(name).userMetadata(ImmutableMap.of("Adrian", "powderpuff")) + Blob blob = view.getBlobStore().blobBuilder(name).userMetadata(ImmutableMap.of("Adrian", "powderpuff")) .payload(TEST_STRING).contentType(MediaType.TEXT_PLAIN).calculateMD5().build(); String container = getContainerName(); try { - assertNull(context.getBlobStore().blobMetadata(container, "powderpuff")); + assertNull(view.getBlobStore().blobMetadata(container, "powderpuff")); addBlobToContainer(container, blob); Blob newObject = validateContent(container, name); @@ -601,7 +601,7 @@ public class BaseBlobIntegrationTest extends BaseBlobStoreIntegrationTest { validateMetadata(metadata); validateMetadata(metadata, container, name); - validateMetadata(context.getBlobStore().blobMetadata(container, name)); + validateMetadata(view.getBlobStore().blobMetadata(container, name)); // write 2 items with the same name to ensure that provider doesn't // accept dupes @@ -609,7 +609,7 @@ public class BaseBlobIntegrationTest extends BaseBlobStoreIntegrationTest { blob.getMetadata().getUserMetadata().put("Adrian", "powderpuff"); addBlobToContainer(container, blob); - validateMetadata(context.getBlobStore().blobMetadata(container, name)); + validateMetadata(view.getBlobStore().blobMetadata(container, name)); } finally { returnContainer(container); diff --git a/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseBlobLiveTest.java b/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseBlobLiveTest.java index 7bd700ae84..f781526a64 100644 --- a/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseBlobLiveTest.java +++ b/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseBlobLiveTest.java @@ -51,18 +51,18 @@ public class BaseBlobLiveTest extends BaseBlobStoreIntegrationTest { httpStreamMD5 = checkNotNull(httpStreamMD5 != null ? httpStreamMD5 : sysHttpStreamMD5, "httpStreamMd5"); - HttpResponse response = context.utils().http().invoke( + HttpResponse response = view.utils().http().invoke( HttpRequest.builder().method("GET").endpoint(URI.create(httpStreamUrl)).build()); long length = response.getPayload().getContentMetadata().getContentLength(); String name = "hello"; byte[] md5 = CryptoStreams.hex(httpStreamMD5); - Blob blob = context.getBlobStore().blobBuilder(name).payload(response.getPayload()).contentLength(length) + Blob blob = view.getBlobStore().blobBuilder(name).payload(response.getPayload()).contentLength(length) .contentMD5(md5).build(); String container = getContainerName(); try { - context.getBlobStore().putBlob(container, blob); + view.getBlobStore().putBlob(container, blob); checkMD5(container, name, md5); } finally { returnContainer(container); @@ -70,7 +70,7 @@ public class BaseBlobLiveTest extends BaseBlobStoreIntegrationTest { } protected void checkMD5(String container, String name, byte[] md5) { - assertEquals(context.getBlobStore().blobMetadata(container, name).getContentMetadata().getContentMD5(), md5); + assertEquals(view.getBlobStore().blobMetadata(container, name).getContentMetadata().getContentMD5(), md5); } } \ No newline at end of file diff --git a/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseBlobMapIntegrationTest.java b/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseBlobMapIntegrationTest.java index 384c9121f5..adcc70132b 100644 --- a/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseBlobMapIntegrationTest.java +++ b/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseBlobMapIntegrationTest.java @@ -73,7 +73,7 @@ public abstract class BaseBlobMapIntegrationTest extends BaseMapIntegrationTest< public void testValues() throws IOException, InterruptedException { String bucketName = getContainerName(); try { - BlobMap map = createMap(context, bucketName); + BlobMap map = createMap(view, bucketName); putFiveStrings(map); putFiveStringsUnderPath(map); @@ -95,7 +95,7 @@ public abstract class BaseBlobMapIntegrationTest extends BaseMapIntegrationTest< public void testRemove() throws InterruptedException, ExecutionException, TimeoutException, IOException { String bucketName = getContainerName(); try { - Map map = createMap(context, bucketName); + Map map = createMap(view, bucketName); putStringWithMD5(map, "one", "two"); assertConsistencyAwareContentEquals(map, "one", "two"); // TODO track how often this occurs and potentially update map implementation @@ -126,7 +126,7 @@ public abstract class BaseBlobMapIntegrationTest extends BaseMapIntegrationTest< public void testEntrySet() throws IOException, InterruptedException { String bucketName = getContainerName(); try { - final BlobMap map = createMap(context, bucketName); + final BlobMap map = createMap(view, bucketName); putFiveStrings(map); assertConsistencyAwareMapSize(map, 5); Set> entries = map.entrySet(); @@ -159,9 +159,9 @@ public abstract class BaseBlobMapIntegrationTest extends BaseMapIntegrationTest< public void testContains() throws InterruptedException, ExecutionException, TimeoutException, IOException { String bucketName = getContainerName(); try { - Map map = createMap(context, bucketName); + Map map = createMap(view, bucketName); putStringWithMD5(map, "one", "apple"); - Blob blob = context.getBlobStore().blobBuilder("one").payload("apple").calculateMD5().build(); + Blob blob = view.getBlobStore().blobBuilder("one").payload("apple").calculateMD5().build(); assertConsistencyAwareContainsValue(map, blob); } finally { returnContainer(bucketName); @@ -185,8 +185,8 @@ public abstract class BaseBlobMapIntegrationTest extends BaseMapIntegrationTest< public void testPut() throws IOException, InterruptedException { String bucketName = getContainerName(); try { - Map map = createMap(context, bucketName); - Blob blob = context.getBlobStore().blobBuilder("one").payload(Strings2.toInputStream("apple")).calculateMD5() + Map map = createMap(view, bucketName); + Blob blob = view.getBlobStore().blobBuilder("one").payload(Strings2.toInputStream("apple")).calculateMD5() .build(); Blob old = map.put(blob.getMetadata().getName(), blob); getOneReturnsAppleAndOldValueIsNull(map, old); @@ -203,12 +203,12 @@ public abstract class BaseBlobMapIntegrationTest extends BaseMapIntegrationTest< public void testPutAll() throws InterruptedException, ExecutionException, TimeoutException { String bucketName = getContainerName(); try { - Map map = createMap(context, bucketName); + Map map = createMap(view, bucketName); ImmutableMap.Builder newMap = ImmutableMap.builder(); for (String key : fiveInputs.keySet()) { newMap.put( key, - context.getBlobStore().blobBuilder(key).payload(fiveInputs.get(key)) + view.getBlobStore().blobBuilder(key).payload(fiveInputs.get(key)) .contentLength((long) fiveBytes.get(key).length).build()); } map.putAll(newMap.build()); @@ -226,7 +226,7 @@ public abstract class BaseBlobMapIntegrationTest extends BaseMapIntegrationTest< return; String bucketName = getContainerName(); try { - BlobMap map = createMap(context, bucketName); + BlobMap map = createMap(view, bucketName); Builder keySet = ImmutableSet.builder(); for (int i = 0; i < maxResultsForTestListings() + 1; i++) { keySet.add(i + ""); @@ -250,7 +250,7 @@ public abstract class BaseBlobMapIntegrationTest extends BaseMapIntegrationTest< @Override protected void putStringWithMD5(Map map, String key, String text) throws IOException { - map.put(key, context.getBlobStore().blobBuilder(key).payload(text).calculateMD5().build()); + map.put(key, view.getBlobStore().blobBuilder(key).payload(text).calculateMD5().build()); } protected void putFiveStrings(BlobMap map) { @@ -277,7 +277,7 @@ public abstract class BaseBlobMapIntegrationTest extends BaseMapIntegrationTest< @Override protected void addTenObjectsUnderPrefix(String containerName, String prefix) throws InterruptedException { - BlobMap blobMap = createMap(context, containerName, inDirectory(prefix)); + BlobMap blobMap = createMap(view, containerName, inDirectory(prefix)); for (int i = 0; i < 10; i++) { blobMap.put(i + "", blobMap.blobBuilder().payload(i + "content").build()); } @@ -285,7 +285,7 @@ public abstract class BaseBlobMapIntegrationTest extends BaseMapIntegrationTest< @Override protected void addTenObjectsUnderRoot(String containerName) throws InterruptedException { - BlobMap blobMap = createMap(context, containerName, ListContainerOptions.NONE); + BlobMap blobMap = createMap(view, containerName, ListContainerOptions.NONE); for (int i = 0; i < 10; i++) { blobMap.put(i + "", blobMap.blobBuilder().payload(i + "content").build()); } diff --git a/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseBlobSignerLiveTest.java b/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseBlobSignerLiveTest.java index 5eba4cfc37..9b9a1402af 100644 --- a/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseBlobSignerLiveTest.java +++ b/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseBlobSignerLiveTest.java @@ -41,15 +41,15 @@ public class BaseBlobSignerLiveTest extends BaseBlobStoreIntegrationTest { String name = "hello"; String text = "fooooooooooooooooooooooo"; - Blob blob = context.getBlobStore().blobBuilder(name).payload(text).contentType("text/plain").build(); + Blob blob = view.getBlobStore().blobBuilder(name).payload(text).contentType("text/plain").build(); String container = getContainerName(); try { - context.getBlobStore().putBlob(container, blob); + view.getBlobStore().putBlob(container, blob); assertConsistencyAwareContainerSize(container, 1); - HttpRequest request = context.getSigner().signRemoveBlob(container, name); + HttpRequest request = view.getSigner().signRemoveBlob(container, name); assertEquals(request.getFilters().size(), 0); - context.utils().http().invoke(request); - assert !context.getBlobStore().blobExists(container, name); + view.utils().http().invoke(request); + assert !view.getBlobStore().blobExists(container, name); } finally { returnContainer(container); } @@ -60,14 +60,14 @@ public class BaseBlobSignerLiveTest extends BaseBlobStoreIntegrationTest { String name = "hello"; String text = "fooooooooooooooooooooooo"; - Blob blob = context.getBlobStore().blobBuilder(name).payload(text).contentType("text/plain").build(); + Blob blob = view.getBlobStore().blobBuilder(name).payload(text).contentType("text/plain").build(); String container = getContainerName(); try { - context.getBlobStore().putBlob(container, blob); + view.getBlobStore().putBlob(container, blob); assertConsistencyAwareContainerSize(container, 1); - HttpRequest request = context.getSigner().signGetBlob(container, name); + HttpRequest request = view.getSigner().signGetBlob(container, name); assertEquals(request.getFilters().size(), 0); - assertEquals(Strings2.toStringAndClose(context.utils().http().invoke(request).getPayload().getInput()), text); + assertEquals(Strings2.toStringAndClose(view.utils().http().invoke(request).getPayload().getInput()), text); } finally { returnContainer(container); } @@ -78,14 +78,14 @@ public class BaseBlobSignerLiveTest extends BaseBlobStoreIntegrationTest { String name = "hello"; String text = "fooooooooooooooooooooooo"; - Blob blob = context.getBlobStore().blobBuilder(name).payload(text).contentType("text/plain").build(); + Blob blob = view.getBlobStore().blobBuilder(name).payload(text).contentType("text/plain").build(); String container = getContainerName(); try { - context.getBlobStore().putBlob(container, blob); + view.getBlobStore().putBlob(container, blob); assertConsistencyAwareContainerSize(container, 1); - HttpRequest request = context.getSigner().signGetBlob(container, name, range(0, 1)); + HttpRequest request = view.getSigner().signGetBlob(container, name, range(0, 1)); assertEquals(request.getFilters().size(), 0); - assertEquals(Strings2.toStringAndClose(context.utils().http().invoke(request).getPayload().getInput()), "fo"); + assertEquals(Strings2.toStringAndClose(view.utils().http().invoke(request).getPayload().getInput()), "fo"); } finally { returnContainer(container); } @@ -96,12 +96,12 @@ public class BaseBlobSignerLiveTest extends BaseBlobStoreIntegrationTest { String name = "hello"; String text = "fooooooooooooooooooooooo"; - Blob blob = context.getBlobStore().blobBuilder(name).payload(text).contentType("text/plain").build(); + Blob blob = view.getBlobStore().blobBuilder(name).payload(text).contentType("text/plain").build(); String container = getContainerName(); try { - HttpRequest request = context.getSigner().signPutBlob(container, blob); + HttpRequest request = view.getSigner().signPutBlob(container, blob); assertEquals(request.getFilters().size(), 0); - Strings2.toStringAndClose(context.utils().http().invoke(request).getPayload().getInput()); + Strings2.toStringAndClose(view.utils().http().invoke(request).getPayload().getInput()); assertConsistencyAwareContainerSize(container, 1); } finally { returnContainer(container); 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 2872c1db01..9445f01835 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 @@ -36,7 +36,7 @@ import java.util.concurrent.atomic.AtomicInteger; import javax.ws.rs.core.MediaType; -import org.jclouds.apis.BaseContextLiveTest; +import org.jclouds.apis.BaseViewLiveTest; import org.jclouds.blobstore.BlobStoreContext; import org.jclouds.blobstore.attr.ConsistencyModel; import org.jclouds.blobstore.domain.Blob; @@ -59,7 +59,7 @@ import com.google.common.collect.Sets; import com.google.common.reflect.TypeToken; import com.google.inject.Module; -public class BaseBlobStoreIntegrationTest extends BaseContextLiveTest { +public class BaseBlobStoreIntegrationTest extends BaseViewLiveTest { protected static final String LOCAL_ENCODING = System.getProperty("file.encoding"); protected static final String XML_STRING_FORMAT = " "; protected static final String TEST_STRING = String.format(XML_STRING_FORMAT, "apple"); @@ -90,9 +90,9 @@ public class BaseBlobStoreIntegrationTest extends BaseContextLiveTest setupModules() { @@ -119,7 +119,7 @@ public class BaseBlobStoreIntegrationTest extends BaseContextLiveTest entry : Iterables.concat(fiveStrings.entrySet(), fiveStringsUnderPath.entrySet())) { - Blob sourceObject = context.getBlobStore().blobBuilder(entry.getKey()).payload(entry.getValue()) + Blob sourceObject = view.getBlobStore().blobBuilder(entry.getKey()).payload(entry.getValue()) .contentType("text/xml").build(); addBlobToContainer(sourceContainer, sourceObject); } } protected String addBlobToContainer(String sourceContainer, Blob object) { - return context.getBlobStore().putBlob(sourceContainer, object); + return view.getBlobStore().putBlob(sourceContainer, object); } protected T validateMetadata(T md, String container, String name) { @@ -269,7 +269,7 @@ public class BaseBlobStoreIntegrationTest extends BaseContextLiveTest() { public String apply(StorageMetadata from) { @@ -307,9 +307,9 @@ public class BaseBlobStoreIntegrationTest extends BaseContextLiveTest() { + view.getBlobStore().list(containerName), new Function() { public String apply(StorageMetadata from) { return from.getName(); @@ -328,7 +328,7 @@ public class BaseBlobStoreIntegrationTest extends BaseContextLiveTest() { + if (!Iterables.any(view.getBlobStore().list(), new Predicate() { public boolean apply(StorageMetadata md) { return containerName.equals(md.getName()); } @@ -382,7 +382,7 @@ public class BaseBlobStoreIntegrationTest extends BaseContextLiveTest contextType() { + protected TypeToken viewType() { return TypeToken.of(BlobStoreContext.class); } diff --git a/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseContainerIntegrationTest.java b/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseContainerIntegrationTest.java index ed2bcc34d5..ec55d601a5 100644 --- a/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseContainerIntegrationTest.java +++ b/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseContainerIntegrationTest.java @@ -49,21 +49,21 @@ public class BaseContainerIntegrationTest extends BaseBlobStoreIntegrationTest { @Test(groups = { "integration", "live" }) public void containerDoesntExist() { - assert !context.getBlobStore().containerExists("forgetaboutit"); - assert !context.getBlobStore().containerExists("cloudcachestorefunctionalintegrationtest-first"); + assert !view.getBlobStore().containerExists("forgetaboutit"); + assert !view.getBlobStore().containerExists("cloudcachestorefunctionalintegrationtest-first"); } @Test(groups = { "integration", "live" }) public void testPutTwiceIsOkAndDoesntOverwrite() throws InterruptedException { String containerName = getContainerName(); try { - context.getBlobStore().createContainerInLocation(null, containerName); + view.getBlobStore().createContainerInLocation(null, containerName); - Blob blob = context.getBlobStore().blobBuilder("hello").payload(TEST_STRING).build(); - context.getBlobStore().putBlob(containerName, blob); + Blob blob = view.getBlobStore().blobBuilder("hello").payload(TEST_STRING).build(); + view.getBlobStore().putBlob(containerName, blob); - context.getBlobStore().createContainerInLocation(null, containerName); - assertEquals(context.getBlobStore().countBlobs(containerName), 1); + view.getBlobStore().createContainerInLocation(null, containerName); + assertEquals(view.getBlobStore().countBlobs(containerName), 1); } finally { returnContainer(containerName); } @@ -77,11 +77,11 @@ public class BaseContainerIntegrationTest extends BaseBlobStoreIntegrationTest { addBlobToContainer(containerName, // NOTE all metadata in jclouds comes out as lowercase, in an effort to // normalize the providers. - context.getBlobStore().blobBuilder(key).userMetadata(ImmutableMap.of("Adrian", "powderpuff")) + view.getBlobStore().blobBuilder(key).userMetadata(ImmutableMap.of("Adrian", "powderpuff")) .payload(TEST_STRING).contentType(MediaType.TEXT_PLAIN).calculateMD5().build()); validateContent(containerName, key); - PageSet container = context.getBlobStore().list(containerName, + PageSet container = view.getBlobStore().list(containerName, maxResults(1).withDetails()); BlobMetadata metadata = BlobMetadata.class.cast(get(container, 0)); @@ -105,7 +105,7 @@ public class BaseContainerIntegrationTest extends BaseBlobStoreIntegrationTest { String containerName = getContainerName(); try { add5BlobsUnderPathAnd5UnderRootToContainer(containerName); - context.getBlobStore().clearContainer(containerName); + view.getBlobStore().clearContainer(containerName); assertConsistencyAwareContainerSize(containerName, 0); } finally { returnContainer(containerName); @@ -118,13 +118,13 @@ public class BaseContainerIntegrationTest extends BaseBlobStoreIntegrationTest { try { addAlphabetUnderRoot(containerName); - PageSet container = context.getBlobStore().list(containerName, maxResults(1)); + PageSet container = view.getBlobStore().list(containerName, maxResults(1)); assert container.getNextMarker() != null; assertEquals(container.size(), 1); String marker = container.getNextMarker(); - container = context.getBlobStore().list(containerName, afterMarker(marker)); + container = view.getBlobStore().list(containerName, afterMarker(marker)); assertEquals(container.getNextMarker(), null); assert container.size() == 25 : String.format("size should have been 25, but was %d: %s", container.size(), container); @@ -142,7 +142,7 @@ public class BaseContainerIntegrationTest extends BaseBlobStoreIntegrationTest { String prefix = "rootdelimeter"; addTenObjectsUnderPrefix(containerName, prefix); add15UnderRoot(containerName); - PageSet container = context.getBlobStore().list(containerName); + PageSet container = view.getBlobStore().list(containerName); assert container.getNextMarker() == null; assertEquals(container.size(), 16); } finally { @@ -157,17 +157,17 @@ public class BaseContainerIntegrationTest extends BaseBlobStoreIntegrationTest { try { String directory = "directory"; - assert !context.getBlobStore().directoryExists(containerName, directory); + assert !view.getBlobStore().directoryExists(containerName, directory); - context.getBlobStore().createDirectory(containerName, directory); + view.getBlobStore().createDirectory(containerName, directory); - assert context.getBlobStore().directoryExists(containerName, directory); - PageSet container = context.getBlobStore().list(containerName); + assert view.getBlobStore().directoryExists(containerName, directory); + PageSet container = view.getBlobStore().list(containerName); // we should have only the directory under root assert container.getNextMarker() == null; assert container.size() == 1 : container; - container = context.getBlobStore().list(containerName, inDirectory(directory)); + container = view.getBlobStore().list(containerName, inDirectory(directory)); // we should have nothing in the directory assert container.getNextMarker() == null; @@ -175,50 +175,50 @@ public class BaseContainerIntegrationTest extends BaseBlobStoreIntegrationTest { addTenObjectsUnderPrefix(containerName, directory); - container = context.getBlobStore().list(containerName); + container = view.getBlobStore().list(containerName); // we should still have only the directory under root assert container.getNextMarker() == null; assert container.size() == 1 : container; - container = context.getBlobStore().list(containerName, inDirectory(directory)); + container = view.getBlobStore().list(containerName, inDirectory(directory)); // we should have only the 10 items under the directory assert container.getNextMarker() == null; assert container.size() == 10 : container; // try 2 level deep directory - assert !context.getBlobStore().directoryExists(containerName, directory + "/" + directory); - context.getBlobStore().createDirectory(containerName, directory + "/" + directory); - assert context.getBlobStore().directoryExists(containerName, directory + "/" + directory); + assert !view.getBlobStore().directoryExists(containerName, directory + "/" + directory); + view.getBlobStore().createDirectory(containerName, directory + "/" + directory); + assert view.getBlobStore().directoryExists(containerName, directory + "/" + directory); - context.getBlobStore().clearContainer(containerName, inDirectory(directory)); - assert context.getBlobStore().directoryExists(containerName, directory); - assert context.getBlobStore().directoryExists(containerName, directory + "/" + directory); + view.getBlobStore().clearContainer(containerName, inDirectory(directory)); + assert view.getBlobStore().directoryExists(containerName, directory); + assert view.getBlobStore().directoryExists(containerName, directory + "/" + directory); // should have only the 2 level-deep directory above - container = context.getBlobStore().list(containerName, inDirectory(directory)); + container = view.getBlobStore().list(containerName, inDirectory(directory)); assert container.getNextMarker() == null; assert container.size() == 1 : container; - context.getBlobStore().createDirectory(containerName, directory + "/" + directory); + view.getBlobStore().createDirectory(containerName, directory + "/" + directory); - container = context.getBlobStore().list(containerName, inDirectory(directory).recursive()); + container = view.getBlobStore().list(containerName, inDirectory(directory).recursive()); assert container.getNextMarker() == null; assert container.size() == 1 : container; - context.getBlobStore().clearContainer(containerName, inDirectory(directory).recursive()); + view.getBlobStore().clearContainer(containerName, inDirectory(directory).recursive()); // should no longer have the 2 level-deep directory above - container = context.getBlobStore().list(containerName, inDirectory(directory)); + container = view.getBlobStore().list(containerName, inDirectory(directory)); assert container.getNextMarker() == null; assert container.size() == 0 : container; - container = context.getBlobStore().list(containerName); + container = view.getBlobStore().list(containerName); // should only have the directory assert container.getNextMarker() == null; assert container.size() == 1 : container; - context.getBlobStore().deleteDirectory(containerName, directory); + view.getBlobStore().deleteDirectory(containerName, directory); - container = context.getBlobStore().list(containerName); + container = view.getBlobStore().list(containerName); // now should be completely empty assert container.getNextMarker() == null; assert container.size() == 0 : container; @@ -236,7 +236,7 @@ public class BaseContainerIntegrationTest extends BaseBlobStoreIntegrationTest { addTenObjectsUnderPrefix(containerName, prefix); add15UnderRoot(containerName); - PageSet container = context.getBlobStore().list(containerName, inDirectory(prefix)); + PageSet container = view.getBlobStore().list(containerName, inDirectory(prefix)); assert container.getNextMarker() == null; assertEquals(container.size(), 10); } finally { @@ -251,7 +251,7 @@ public class BaseContainerIntegrationTest extends BaseBlobStoreIntegrationTest { try { addAlphabetUnderRoot(containerName); - PageSet container = context.getBlobStore().list(containerName, maxResults(5)); + PageSet container = view.getBlobStore().list(containerName, maxResults(5)); assertEquals(container.size(), 5); assert container.getNextMarker() != null; } finally { @@ -263,7 +263,7 @@ public class BaseContainerIntegrationTest extends BaseBlobStoreIntegrationTest { public void containerExists() throws InterruptedException { String containerName = getContainerName(); try { - assert context.getBlobStore().containerExists(containerName); + assert view.getBlobStore().containerExists(containerName); } finally { returnContainer(containerName); } @@ -274,7 +274,7 @@ public class BaseContainerIntegrationTest extends BaseBlobStoreIntegrationTest { String containerName = getContainerName(); try { addBlobToContainer(containerName, "test"); - context.getBlobStore().deleteContainer(containerName); + view.getBlobStore().deleteContainer(containerName); assertNotExists(containerName); } finally { recycleContainer(containerName); @@ -285,7 +285,7 @@ public class BaseContainerIntegrationTest extends BaseBlobStoreIntegrationTest { public void deleteContainerIfEmpty() throws InterruptedException { final String containerName = getContainerName(); try { - context.getBlobStore().deleteContainer(containerName); + view.getBlobStore().deleteContainer(containerName); assertNotExists(containerName); } finally { // this container is now deleted, so we can't reuse it directly @@ -298,7 +298,7 @@ public class BaseContainerIntegrationTest extends BaseBlobStoreIntegrationTest { String containerName = getContainerName(); try { add15UnderRoot(containerName); - Set container = context.getBlobStore().list(containerName); + Set container = view.getBlobStore().list(containerName); assertEquals(container.size(), 15); } finally { returnContainer(containerName); @@ -308,8 +308,8 @@ public class BaseContainerIntegrationTest extends BaseBlobStoreIntegrationTest { protected void addAlphabetUnderRoot(String containerName) throws InterruptedException { for (char letter = 'a'; letter <= 'z'; letter++) { - context.getBlobStore().putBlob(containerName, - context.getBlobStore().blobBuilder(letter + "").payload(letter + "content").build()); + view.getBlobStore().putBlob(containerName, + view.getBlobStore().blobBuilder(letter + "").payload(letter + "content").build()); } assertContainerSize(containerName, 26); @@ -319,7 +319,7 @@ public class BaseContainerIntegrationTest extends BaseBlobStoreIntegrationTest { assertConsistencyAware(new Runnable() { public void run() { try { - assertEquals(context.getBlobStore().countBlobs(containerName), size); + assertEquals(view.getBlobStore().countBlobs(containerName), size); } catch (Exception e) { propagateIfPossible(e); } @@ -329,15 +329,15 @@ public class BaseContainerIntegrationTest extends BaseBlobStoreIntegrationTest { protected void add15UnderRoot(String containerName) throws InterruptedException { for (int i = 0; i < 15; i++) { - context.getBlobStore().putBlob(containerName, - context.getBlobStore().blobBuilder(i + "").payload(i + "content").build()); + view.getBlobStore().putBlob(containerName, + view.getBlobStore().blobBuilder(i + "").payload(i + "content").build()); } } protected void addTenObjectsUnderPrefix(String containerName, String prefix) throws InterruptedException { for (int i = 0; i < 10; i++) { - context.getBlobStore().putBlob(containerName, - context.getBlobStore().blobBuilder(prefix + "/" + i).payload(i + "content").build()); + view.getBlobStore().putBlob(containerName, + view.getBlobStore().blobBuilder(prefix + "/" + i).payload(i + "content").build()); } } } \ No newline at end of file diff --git a/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseContainerLiveTest.java b/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseContainerLiveTest.java index 40e094528b..68fa3d8738 100644 --- a/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseContainerLiveTest.java +++ b/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseContainerLiveTest.java @@ -38,18 +38,18 @@ public class BaseContainerLiveTest extends BaseBlobStoreIntegrationTest { public void testPublicAccess() throws InterruptedException, MalformedURLException, IOException { final String containerName = getScratchContainerName(); try { - context.getBlobStore().createContainerInLocation(null, containerName, publicRead()); + view.getBlobStore().createContainerInLocation(null, containerName, publicRead()); assertConsistencyAwareContainerSize(containerName, 0); - context.getBlobStore().putBlob(containerName, - context.getBlobStore().blobBuilder("hello").payload(TEST_STRING).build()); + view.getBlobStore().putBlob(containerName, + view.getBlobStore().blobBuilder("hello").payload(TEST_STRING).build()); assertConsistencyAwareContainerSize(containerName, 1); - BlobMetadata metadata = context.getBlobStore().blobMetadata(containerName, "hello"); + BlobMetadata metadata = view.getBlobStore().blobMetadata(containerName, "hello"); assert metadata.getPublicUri() != null : metadata; - assertEquals(Strings2.toStringAndClose(context.utils().http().get(metadata.getPublicUri())), TEST_STRING); + assertEquals(Strings2.toStringAndClose(view.utils().http().get(metadata.getPublicUri())), TEST_STRING); } finally { // this container is now public, so we can't reuse it directly diff --git a/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseInputStreamMapIntegrationTest.java b/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseInputStreamMapIntegrationTest.java index 085b0d7fc9..153a4118d1 100644 --- a/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseInputStreamMapIntegrationTest.java +++ b/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseInputStreamMapIntegrationTest.java @@ -53,7 +53,7 @@ public abstract class BaseInputStreamMapIntegrationTest extends BaseMapIntegrati public void testValues() throws InterruptedException, IOException { String containerName = getContainerName(); try { - Map map = createMap(context, containerName); + Map map = createMap(view, containerName); map.putAll(this.fiveInputs); // this will cause us to block until the bucket updates. assertConsistencyAwareMapSize(map, 5); @@ -74,7 +74,7 @@ public abstract class BaseInputStreamMapIntegrationTest extends BaseMapIntegrati public void testPutMoreThanSingleListing() throws InterruptedException, ExecutionException, TimeoutException { String containerName = getContainerName(); try { - InputStreamMap map = createMap(context, containerName); + InputStreamMap map = createMap(view, containerName); Set keySet = Sets.newLinkedHashSet(); for (int i = 0; i < maxResultsForTestListings() + 1; i++) { keySet.add(i + ""); @@ -100,7 +100,7 @@ public abstract class BaseInputStreamMapIntegrationTest extends BaseMapIntegrati public void testRemove() throws InterruptedException, IOException { String containerName = getContainerName(); try { - Map map = createMap(context, containerName); + Map map = createMap(view, containerName); putStringWithMD5(map, "one", "two"); InputStream old = map.remove("one"); assertEquals(Strings2.toStringAndClose(old), "two"); @@ -120,7 +120,7 @@ public abstract class BaseInputStreamMapIntegrationTest extends BaseMapIntegrati public void testEntrySet() throws InterruptedException, IOException { String containerName = getContainerName(); try { - Map map = createMap(context, containerName); + Map map = createMap(view, containerName); ((InputStreamMap) map).putAllStrings(this.fiveStrings); // this will cause us to block until the bucket updates. assertConsistencyAwareKeySize(map, 5); @@ -143,7 +143,7 @@ public abstract class BaseInputStreamMapIntegrationTest extends BaseMapIntegrati public void testContainsStringValue() throws InterruptedException, ExecutionException, TimeoutException { String containerName = getContainerName(); try { - Map map = createMap(context, containerName); + Map map = createMap(view, containerName); ((InputStreamMap) map).putString("one", String.format(XML_STRING_FORMAT, "apple")); assertConsistencyAwareContainsValue(map, fiveStrings.get("one")); } finally { @@ -155,7 +155,7 @@ public abstract class BaseInputStreamMapIntegrationTest extends BaseMapIntegrati public void testContainsFileValue() throws InterruptedException, ExecutionException, TimeoutException { String containerName = getContainerName(); try { - Map map = createMap(context, containerName); + Map map = createMap(view, containerName); ((InputStreamMap) map).putString("one", String.format(XML_STRING_FORMAT, "apple")); assertConsistencyAwareContainsValue(map, fiveFiles.get("one")); } finally { @@ -167,7 +167,7 @@ public abstract class BaseInputStreamMapIntegrationTest extends BaseMapIntegrati public void testContainsInputStreamValue() throws InterruptedException, ExecutionException, TimeoutException { String containerName = getContainerName(); try { - Map map = createMap(context, containerName); + Map map = createMap(view, containerName); ((InputStreamMap) map).putString("one", String.format(XML_STRING_FORMAT, "apple")); assertConsistencyAwareContainsValue(map, this.fiveInputs.get("one")); } finally { @@ -179,7 +179,7 @@ public abstract class BaseInputStreamMapIntegrationTest extends BaseMapIntegrati public void testContainsBytesValue() throws InterruptedException, ExecutionException, TimeoutException { String containerName = getContainerName(); try { - Map map = createMap(context, containerName); + Map map = createMap(view, containerName); ((InputStreamMap) map).putString("one", String.format(XML_STRING_FORMAT, "apple")); assertConsistencyAwareContainsValue(map, this.fiveBytes.get("one")); } finally { @@ -192,7 +192,7 @@ public abstract class BaseInputStreamMapIntegrationTest extends BaseMapIntegrati public void testPutAll() throws InterruptedException { String containerName = getContainerName(); try { - Map map = createMap(context, containerName); + Map map = createMap(view, containerName); map.putAll(this.fiveInputs); assertConsistencyAwareMapSize(map, 5); assertConsistencyAwareKeySetEquals(map, new TreeSet(fiveInputs.keySet())); @@ -206,7 +206,7 @@ public abstract class BaseInputStreamMapIntegrationTest extends BaseMapIntegrati public void testPutAllBytes() throws InterruptedException { String containerName = getContainerName(); try { - Map map = createMap(context, containerName); + Map map = createMap(view, containerName); ((InputStreamMap) map).putAllBytes(this.fiveBytes); assertConsistencyAwareMapSize(map, 5); @@ -221,7 +221,7 @@ public abstract class BaseInputStreamMapIntegrationTest extends BaseMapIntegrati public void testPutAllFiles() throws InterruptedException { String containerName = getContainerName(); try { - Map map = createMap(context, containerName); + Map map = createMap(view, containerName); ((InputStreamMap) map).putAllFiles(this.fiveFiles); assertConsistencyAwareMapSize(map, 5); @@ -236,7 +236,7 @@ public abstract class BaseInputStreamMapIntegrationTest extends BaseMapIntegrati public void testPutAllStrings() throws InterruptedException { String containerName = getContainerName(); try { - Map map = createMap(context, containerName); + Map map = createMap(view, containerName); ((InputStreamMap) map).putAllStrings(this.fiveStrings); assertConsistencyAwareMapSize(map, 5); @@ -251,7 +251,7 @@ public abstract class BaseInputStreamMapIntegrationTest extends BaseMapIntegrati public void testPutString() throws InterruptedException, IOException { String containerName = getContainerName(); try { - Map map = createMap(context, containerName); + Map map = createMap(view, containerName); InputStream old = ((InputStreamMap) map).putString("one", fiveStrings.get("one")); getOneReturnsAppleAndOldValueIsNull(map, old); @@ -280,7 +280,7 @@ public abstract class BaseInputStreamMapIntegrationTest extends BaseMapIntegrati public void testPutFile() throws IOException, InterruptedException { String containerName = getContainerName(); try { - Map map = createMap(context, containerName); + Map map = createMap(view, containerName); InputStream old = ((InputStreamMap) map).putFile("one", fiveFiles.get("one")); getOneReturnsAppleAndOldValueIsNull(map, old); @@ -295,7 +295,7 @@ public abstract class BaseInputStreamMapIntegrationTest extends BaseMapIntegrati public void testPutBytes() throws InterruptedException, IOException { String containerName = getContainerName(); try { - Map map = createMap(context, containerName); + Map map = createMap(view, containerName); InputStream old = ((InputStreamMap) map).putBytes("one", fiveBytes.get("one")); getOneReturnsAppleAndOldValueIsNull(map, old); @@ -310,7 +310,7 @@ public abstract class BaseInputStreamMapIntegrationTest extends BaseMapIntegrati public void testPut() throws InterruptedException, IOException { String containerName = getContainerName(); try { - Map map = createMap(context, containerName); + Map map = createMap(view, containerName); InputStream old = map.put("one", fiveInputs.get("one")); getOneReturnsAppleAndOldValueIsNull(map, old); diff --git a/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseMapIntegrationTest.java b/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseMapIntegrationTest.java index 6e59bd2a58..b85a3a6dc9 100644 --- a/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseMapIntegrationTest.java +++ b/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseMapIntegrationTest.java @@ -106,7 +106,7 @@ public abstract class BaseMapIntegrationTest extends BaseBlobStoreIntegration public void testClear() throws InterruptedException, ExecutionException, TimeoutException, IOException { String containerNameName = getContainerName(); try { - Map map = createMap(context, containerNameName); + Map map = createMap(view, containerNameName); assertConsistencyAwareMapSize(map, 0); putStringWithMD5(map, "one", "apple"); assertConsistencyAwareMapSize(map, 1); @@ -124,7 +124,7 @@ public abstract class BaseMapIntegrationTest extends BaseBlobStoreIntegration public void testKeySet() throws InterruptedException, ExecutionException, TimeoutException, IOException { String containerNameName = getContainerName(); try { - Map map = createMap(context, containerNameName); + Map map = createMap(view, containerNameName); assertConsistencyAwareKeySize(map, 0); putStringWithMD5(map, "one", "two"); assertConsistencyAwareKeySize(map, 1); @@ -136,15 +136,15 @@ public abstract class BaseMapIntegrationTest extends BaseBlobStoreIntegration protected void addTenObjectsUnderPrefix(String containerName, String prefix) throws InterruptedException { for (int i = 0; i < 10; i++) { - context.getBlobStore().putBlob(containerName, - context.getBlobStore().blobBuilder(prefix + "/" + i).payload(i + "content").build()); + view.getBlobStore().putBlob(containerName, + view.getBlobStore().blobBuilder(prefix + "/" + i).payload(i + "content").build()); } } protected void addTenObjectsUnderRoot(String containerName) throws InterruptedException { for (int i = 0; i < 10; i++) { - context.getBlobStore().putBlob(containerName, - context.getBlobStore().blobBuilder(i + "").payload(i + "content").build()); + view.getBlobStore().putBlob(containerName, + view.getBlobStore().blobBuilder(i + "").payload(i + "content").build()); } } @@ -152,13 +152,13 @@ public abstract class BaseMapIntegrationTest extends BaseBlobStoreIntegration public void testDirectory() throws InterruptedException { String containerName = getContainerName(); String directory = "apps"; - Map rootMap = createMap(context, containerName); - Map rootRecursiveMap = createMap(context, containerName, recursive()); - Map inDirectoryMap = createMap(context, containerName, inDirectory(directory)); - Map inDirectoryRecursiveMap = createMap(context, containerName, inDirectory(directory).recursive()); + Map rootMap = createMap(view, containerName); + Map rootRecursiveMap = createMap(view, containerName, recursive()); + Map inDirectoryMap = createMap(view, containerName, inDirectory(directory)); + Map inDirectoryRecursiveMap = createMap(view, containerName, inDirectory(directory).recursive()); try { - context.getBlobStore().createDirectory(containerName, directory); + view.getBlobStore().createDirectory(containerName, directory); addTenObjectsUnderRoot(containerName); assertEquals(rootMap.size(), 10); assertEquals(ImmutableSortedSet.copyOf(rootMap.keySet()), @@ -184,7 +184,7 @@ public abstract class BaseMapIntegrationTest extends BaseBlobStoreIntegration assertEquals(ImmutableSortedSet.copyOf(inDirectoryRecursiveMap.keySet()), ImmutableSortedSet.of("0", "1", "2", "3", "4", "5", "6", "7", "8", "9")); - context.getBlobStore().createDirectory(containerName, directory + "/" + directory); + view.getBlobStore().createDirectory(containerName, directory + "/" + directory); assertEquals(rootMap.size(), 10); assertEquals(rootRecursiveMap.size(), 20); assertEquals(inDirectoryMap.size(), 10); @@ -252,7 +252,7 @@ public abstract class BaseMapIntegrationTest extends BaseBlobStoreIntegration public void testContainsKey() throws InterruptedException, ExecutionException, TimeoutException, IOException { String containerNameName = getContainerName(); try { - Map map = createMap(context, containerNameName); + Map map = createMap(view, containerNameName); assertConsistencyAwareDoesntContainKey(map); putStringWithMD5(map, "one", "apple"); assertConsistencyAwareContainsKey(map); @@ -294,7 +294,7 @@ public abstract class BaseMapIntegrationTest extends BaseBlobStoreIntegration public void testIsEmpty() throws InterruptedException, ExecutionException, TimeoutException, IOException { String containerNameName = getContainerName(); try { - Map map = createMap(context, containerNameName); + Map map = createMap(view, containerNameName); assertConsistencyAwareEmpty(map); putStringWithMD5(map, "one", "apple"); assertConsistencyAwareNotEmpty(map); @@ -343,7 +343,7 @@ public abstract class BaseMapIntegrationTest extends BaseBlobStoreIntegration public void testListContainer() throws InterruptedException, ExecutionException, TimeoutException { String containerNameName = getContainerName(); try { - ListableMap map = (ListableMap) createMap(context, containerNameName); + ListableMap map = (ListableMap) createMap(view, containerNameName); assertConsistencyAwareListContainer(map, containerNameName); } finally { returnContainer(containerNameName); diff --git a/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseServiceIntegrationTest.java b/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseServiceIntegrationTest.java index 43a5abb102..3e61b5f821 100644 --- a/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseServiceIntegrationTest.java +++ b/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseServiceIntegrationTest.java @@ -41,24 +41,24 @@ public class BaseServiceIntegrationTest extends BaseBlobStoreIntegrationTest { @Test(groups = { "integration", "live" }) void containerDoesntExist() { - Set list = context.getBlobStore().list(); + Set list = view.getBlobStore().list(); assert !list.contains(new MutableStorageMetadataImpl()); } @Test(groups = { "integration", "live" }) public void testAllLocations() throws InterruptedException { - for (final Location location : context.getBlobStore().listAssignableLocations()) { + for (final Location location : view.getBlobStore().listAssignableLocations()) { final String containerName = getScratchContainerName(); try { System.err.printf(" >> creating container in location %s%n", location); - context.getBlobStore().createContainerInLocation(location, containerName); + view.getBlobStore().createContainerInLocation(location, containerName); System.err.printf(" << call complete.. checking%n"); assertConsistencyAware(new Runnable() { @Override public void run() { - PageSet list = context.getBlobStore().list(); + PageSet list = view.getBlobStore().list(); assert Iterables.any(list, new Predicate() { public boolean apply(StorageMetadata md) { return containerName.equals(md.getName()) && location.equals(md.getLocation()); @@ -79,9 +79,9 @@ public class BaseServiceIntegrationTest extends BaseBlobStoreIntegrationTest { @Test(groups = { "integration", "live" }) public void testGetAssignableLocations() throws Exception { - if (context.unwrap() instanceof Location) - assertProvider(Location.class.cast(context.unwrap())); - for (Location location : context.getBlobStore().listAssignableLocations()) { + if (view.unwrap() instanceof Location) + assertProvider(Location.class.cast(view.unwrap())); + for (Location location : view.getBlobStore().listAssignableLocations()) { System.err.printf("location %s%n", location); assert location.getId() != null : location; assert location != location.getParent() : location; diff --git a/blobstore/src/test/java/org/jclouds/blobstore/internal/BaseBlobMapTest.java b/blobstore/src/test/java/org/jclouds/blobstore/internal/BaseBlobMapTest.java index baa5e6309c..de972ccbd6 100644 --- a/blobstore/src/test/java/org/jclouds/blobstore/internal/BaseBlobMapTest.java +++ b/blobstore/src/test/java/org/jclouds/blobstore/internal/BaseBlobMapTest.java @@ -53,8 +53,7 @@ public class BaseBlobMapTest { public void testTypes() { TypeLiteral>> type0 = new TypeLiteral>>() { }; - @SuppressWarnings("rawtypes") - TypeLiteral type1 = TypeLiteral.get(Types.newParameterizedType(Map.class, String.class, + TypeLiteral type1 = TypeLiteral.get(Types.newParameterizedType(Map.class, String.class, Types.newParameterizedType(Map.class, String.class, Blob.class))); assertEquals(type0, type1); diff --git a/blobstore/src/test/java/org/jclouds/blobstore/internal/BaseBlobStoreApiMetadataTest.java b/blobstore/src/test/java/org/jclouds/blobstore/internal/BaseBlobStoreApiMetadataTest.java index fcb31cdbe3..541aa86c08 100644 --- a/blobstore/src/test/java/org/jclouds/blobstore/internal/BaseBlobStoreApiMetadataTest.java +++ b/blobstore/src/test/java/org/jclouds/blobstore/internal/BaseBlobStoreApiMetadataTest.java @@ -18,7 +18,7 @@ */ package org.jclouds.blobstore.internal; -import org.jclouds.Wrapper; +import org.jclouds.View; import org.jclouds.apis.ApiMetadata; import org.jclouds.apis.internal.BaseApiMetadataTest; import org.jclouds.blobstore.BlobStoreContext; @@ -35,7 +35,7 @@ import com.google.common.reflect.TypeToken; public abstract class BaseBlobStoreApiMetadataTest extends BaseApiMetadataTest { public BaseBlobStoreApiMetadataTest(ApiMetadata toTest) { - super(toTest, ImmutableSet.>of(TypeToken.of(BlobStoreContext.class))); + super(toTest, ImmutableSet.>of(TypeToken.of(BlobStoreContext.class))); } } \ No newline at end of file diff --git a/common/azure/src/main/java/org/jclouds/azure/storage/filters/SharedKeyLiteAuthentication.java b/common/azure/src/main/java/org/jclouds/azure/storage/filters/SharedKeyLiteAuthentication.java index a6c38634f9..e722db87c0 100644 --- a/common/azure/src/main/java/org/jclouds/azure/storage/filters/SharedKeyLiteAuthentication.java +++ b/common/azure/src/main/java/org/jclouds/azure/storage/filters/SharedKeyLiteAuthentication.java @@ -43,6 +43,8 @@ import org.jclouds.http.internal.SignatureWire; import org.jclouds.http.utils.ModifyRequest; import org.jclouds.io.InputSuppliers; import org.jclouds.logging.Logger; +import org.jclouds.rest.annotations.Credential; +import org.jclouds.rest.annotations.Identity; import org.jclouds.util.Strings2; import com.google.common.annotations.VisibleForTesting; @@ -75,8 +77,8 @@ public class SharedKeyLiteAuthentication implements HttpRequestFilter { Logger signatureLog = Logger.NULL; @Inject - public SharedKeyLiteAuthentication(SignatureWire signatureWire, @Named(Constants.PROPERTY_IDENTITY) String identity, - @Named(Constants.PROPERTY_CREDENTIAL) String encodedKey, @TimeStamp Provider timeStampProvider, + public SharedKeyLiteAuthentication(SignatureWire signatureWire, @Identity String identity, + @Credential String encodedKey, @TimeStamp Provider timeStampProvider, Crypto crypto, HttpUtils utils) { this.crypto = crypto; this.utils = utils; diff --git a/common/trmk/src/main/java/org/jclouds/trmk/vcloud_0_8/config/DefaultVCloudReferencesModule.java b/common/trmk/src/main/java/org/jclouds/trmk/vcloud_0_8/config/DefaultVCloudReferencesModule.java index ec96dfd891..e37f5eb34a 100644 --- a/common/trmk/src/main/java/org/jclouds/trmk/vcloud_0_8/config/DefaultVCloudReferencesModule.java +++ b/common/trmk/src/main/java/org/jclouds/trmk/vcloud_0_8/config/DefaultVCloudReferencesModule.java @@ -18,14 +18,12 @@ */ package org.jclouds.trmk.vcloud_0_8.config; -import static org.jclouds.Constants.PROPERTY_IDENTITY; - import java.net.URI; import java.util.Map; -import javax.inject.Named; import javax.inject.Singleton; +import org.jclouds.rest.annotations.Identity; import org.jclouds.trmk.vcloud_0_8.domain.Catalog; import org.jclouds.trmk.vcloud_0_8.domain.ReferenceType; @@ -55,7 +53,7 @@ public class DefaultVCloudReferencesModule extends AbstractModule { @org.jclouds.trmk.vcloud_0_8.endpoints.Org @Singleton protected Supplier provideDefaultOrg(DefaultOrgForUser defaultOrgURIForUser, - @Named(PROPERTY_IDENTITY) String user) { + @Identity String user) { return defaultOrgURIForUser.apply(user); } diff --git a/common/trmk/src/main/java/org/jclouds/trmk/vcloud_0_8/config/TerremarkVCloudRestClientModule.java b/common/trmk/src/main/java/org/jclouds/trmk/vcloud_0_8/config/TerremarkVCloudRestClientModule.java index 37de990fd3..848eab3d46 100644 --- a/common/trmk/src/main/java/org/jclouds/trmk/vcloud_0_8/config/TerremarkVCloudRestClientModule.java +++ b/common/trmk/src/main/java/org/jclouds/trmk/vcloud_0_8/config/TerremarkVCloudRestClientModule.java @@ -25,7 +25,6 @@ import static com.google.common.collect.Iterables.getLast; import static com.google.common.collect.Iterables.transform; import static com.google.common.collect.Maps.transformValues; import static com.google.common.collect.Maps.uniqueIndex; -import static org.jclouds.Constants.PROPERTY_API_VERSION; import static org.jclouds.Constants.PROPERTY_SESSION_INTERVAL; import static org.jclouds.rest.config.BinderUtils.bindClientAndAsyncClient; import static org.jclouds.trmk.vcloud_0_8.reference.VCloudConstants.PROPERTY_VCLOUD_TIMEOUT_TASK_COMPLETED; @@ -50,6 +49,7 @@ import org.jclouds.location.suppliers.ImplicitLocationSupplier; import org.jclouds.location.suppliers.LocationsSupplier; import org.jclouds.predicates.RetryablePredicate; import org.jclouds.rest.AuthorizationException; +import org.jclouds.rest.annotations.ApiVersion; import org.jclouds.rest.config.RestClientModule; import org.jclouds.rest.suppliers.MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier; import org.jclouds.trmk.vcloud_0_8.TerremarkVCloudClient; @@ -311,7 +311,7 @@ public class TerremarkVCloudRestClientModule extends RestClientModule provideAuthenticationURI(final TerremarkVCloudVersionsClient versionService, - @Named(PROPERTY_API_VERSION) final String version) { + @ApiVersion final String version) { return new Supplier() { @Override diff --git a/common/trmk/src/main/java/org/jclouds/trmk/vcloud_0_8/internal/TerremarkVCloudApiMetadata.java b/common/trmk/src/main/java/org/jclouds/trmk/vcloud_0_8/internal/TerremarkVCloudApiMetadata.java index cf132779ed..b35140b7d1 100644 --- a/common/trmk/src/main/java/org/jclouds/trmk/vcloud_0_8/internal/TerremarkVCloudApiMetadata.java +++ b/common/trmk/src/main/java/org/jclouds/trmk/vcloud_0_8/internal/TerremarkVCloudApiMetadata.java @@ -56,7 +56,7 @@ public abstract class TerremarkVCloudApiMetadata extends BaseRestApiMetadata { .credentialName("Password") .version("0.8") .defaultProperties(TerremarkVCloudApiMetadata.defaultProperties()) - .wrapper(ComputeServiceContext.class); + .view(ComputeServiceContext.class); } @Override diff --git a/common/trmk/src/test/java/org/jclouds/trmk/vcloud_0_8/TerremarkClientLiveTest.java b/common/trmk/src/test/java/org/jclouds/trmk/vcloud_0_8/TerremarkClientLiveTest.java index c193253b2b..f6308b9841 100644 --- a/common/trmk/src/test/java/org/jclouds/trmk/vcloud_0_8/TerremarkClientLiveTest.java +++ b/common/trmk/src/test/java/org/jclouds/trmk/vcloud_0_8/TerremarkClientLiveTest.java @@ -482,7 +482,7 @@ public abstract class TerremarkClientLiveTest(injector.getInstance(SocketOpen.class), 300, 10, TimeUnit.SECONDS);// make @@ -492,7 +492,7 @@ public abstract class TerremarkClientLiveTest(injector.getInstance(TaskSuccess.class), 650, 10, TimeUnit.SECONDS); - connection = (S) RestContext.class.cast(context.unwrap()).getApi(); + connection = (S) RestContext.class.cast(view.unwrap()).getApi(); orgs = listOrgs(); } @@ -514,7 +514,7 @@ public abstract class TerremarkClientLiveTest newContext = null; try { - newContext = createContext( + newContext = createView( overrideDefaults(ImmutableMap.of(VCloudConstants.PROPERTY_VCLOUD_DEFAULT_ORG, org.getName())), setupModules()).unwrap(); assertEquals(newContext.getApi().findOrgNamed(null), org); @@ -549,7 +549,7 @@ public abstract class TerremarkClientLiveTest newContext = null; try { - newContext = createContext( + newContext = createView( overrideDefaults(ImmutableMap.of(VCloudConstants.PROPERTY_VCLOUD_DEFAULT_ORG, org.getName(), VCloudConstants.PROPERTY_VCLOUD_DEFAULT_CATALOG, cat.getName())), setupModules()) .unwrap(); @@ -592,7 +592,7 @@ public abstract class TerremarkClientLiveTest newContext = null; try { - newContext = createContext( + newContext = createView( overrideDefaults(ImmutableMap.of(VCloudConstants.PROPERTY_VCLOUD_DEFAULT_ORG, org.getName(), VCloudConstants.PROPERTY_VCLOUD_DEFAULT_VDC, vdc.getName(), VCloudConstants.PROPERTY_VCLOUD_DEFAULT_NETWORK, net.getName())), setupModules()) @@ -671,7 +671,7 @@ public abstract class TerremarkClientLiveTest newContext = null; try { - newContext = createContext( + newContext = createView( overrideDefaults(ImmutableMap.of(VCloudConstants.PROPERTY_VCLOUD_DEFAULT_ORG, org.getName(), VCloudConstants.PROPERTY_VCLOUD_DEFAULT_VDC, vdc.getName())), setupModules()) .unwrap(); @@ -703,7 +703,7 @@ public abstract class TerremarkClientLiveTest newContext = null; try { - newContext = createContext( + newContext = createView( overrideDefaults(ImmutableMap.of(VCloudConstants.PROPERTY_VCLOUD_DEFAULT_ORG, org.getName(), VCloudConstants.PROPERTY_VCLOUD_DEFAULT_TASKSLIST, tasksList.getName())), setupModules()) .unwrap(); @@ -737,7 +737,7 @@ public abstract class TerremarkClientLiveTest listOrgs() { diff --git a/common/trmk/src/test/java/org/jclouds/trmk/vcloud_0_8/compute/suppliers/VAppTemplatesInOrgsLiveTest.java b/common/trmk/src/test/java/org/jclouds/trmk/vcloud_0_8/compute/suppliers/VAppTemplatesInOrgsLiveTest.java index 181712e8c3..b5f931d3c4 100644 --- a/common/trmk/src/test/java/org/jclouds/trmk/vcloud_0_8/compute/suppliers/VAppTemplatesInOrgsLiveTest.java +++ b/common/trmk/src/test/java/org/jclouds/trmk/vcloud_0_8/compute/suppliers/VAppTemplatesInOrgsLiveTest.java @@ -54,7 +54,7 @@ extends BaseComputeServiceContextLiveTest { @BeforeClass(groups = { "integration", "live" }) public void setupContext() { super.setupContext(); - Injector injector = context.utils().injector(); + Injector injector = view.utils().injector(); tmClient = injector.getInstance(TerremarkVCloudClient.class); allCatalogItemsInOrg = injector.getInstance(AllCatalogItemsInOrg.class); diff --git a/common/trmk/src/test/java/org/jclouds/trmk/vcloud_0_8/internal/BaseTerremarkClientLiveTest.java b/common/trmk/src/test/java/org/jclouds/trmk/vcloud_0_8/internal/BaseTerremarkClientLiveTest.java index 453b394d0e..2d16b21584 100644 --- a/common/trmk/src/test/java/org/jclouds/trmk/vcloud_0_8/internal/BaseTerremarkClientLiveTest.java +++ b/common/trmk/src/test/java/org/jclouds/trmk/vcloud_0_8/internal/BaseTerremarkClientLiveTest.java @@ -60,10 +60,10 @@ public abstract class BaseTerremarkClientLiveTest(new InetSocketAddressConnect(), 300, 1, TimeUnit.SECONDS); sshFactory = injector.getInstance(Factory.class); - connection = (S) RestContext.class.cast(context.unwrap()).getApi(); + connection = (S) RestContext.class.cast(view.unwrap()).getApi(); } protected Module getSshModule() { diff --git a/compute/src/main/java/org/jclouds/compute/ComputeServiceContext.java b/compute/src/main/java/org/jclouds/compute/ComputeServiceContext.java index 1d0b93fd5e..df6f6d3152 100644 --- a/compute/src/main/java/org/jclouds/compute/ComputeServiceContext.java +++ b/compute/src/main/java/org/jclouds/compute/ComputeServiceContext.java @@ -21,7 +21,7 @@ package org.jclouds.compute; import java.io.Closeable; import java.util.Map; -import org.jclouds.Wrapper; +import org.jclouds.View; import org.jclouds.compute.internal.ComputeServiceContextImpl; import org.jclouds.domain.Credentials; import org.jclouds.rest.RestContext; @@ -37,32 +37,25 @@ import com.google.inject.ImplementedBy; * */ @ImplementedBy(ComputeServiceContextImpl.class) -public interface ComputeServiceContext extends Closeable, Wrapper { +public interface ComputeServiceContext extends Closeable, View { ComputeService getComputeService(); /** - * retrieves a list of credentials for resources created within this context, keyed on {@code id} - * of the resource with a namespace prefix (ex. {@code node#}. We are testing this approach for - * resources such as compute nodes, where you could access this externally. - *

- *

accessing credentials for a node

- *

- * the key is in the form {@code node#id}. - *

    - *
  • if the node id is {@code 8}, then the key will be {@code node#8}
  • - *
  • if the node id is {@code us-east-1/i-asdfdas}, then the key will be {@code - * node#us-east-1/i-asdfdas}
  • - *
  • if the node id is {@code http://cloud/instances/1}, then the key will be {@code - * node#http://cloud/instances/1}
  • - *
+ * will be removed in jclouds 1.6 + * + * @see Utils#getCredentialStore() */ + @Deprecated @Beta Map getCredentialStore(); /** - * @see ComputeServiceContext#getCredentialStore + * will be removed in jclouds 1.6 + * + * @see Utils#credentialStore() */ + @Deprecated @Beta Map credentialStore(); @@ -72,12 +65,12 @@ public interface ComputeServiceContext extends Closeable, Wrapper { * @see #getUtils */ Utils utils(); - + /** * will be removed in jclouds 1.6 * - * @see Wrapper#getInputType - * @see Wrapper#unwrap + * @see View#getInputType + * @see View#unwrap */ @Deprecated RestContext getProviderSpecificContext(); diff --git a/compute/src/main/java/org/jclouds/compute/Utils.java b/compute/src/main/java/org/jclouds/compute/Utils.java index d8dc073fc2..0ace4655d2 100644 --- a/compute/src/main/java/org/jclouds/compute/Utils.java +++ b/compute/src/main/java/org/jclouds/compute/Utils.java @@ -42,5 +42,5 @@ public interface Utils extends org.jclouds.rest.Utils { * @return function that gets an ssh client for a node that is available via ssh. */ Function sshForNode(); - + } diff --git a/compute/src/main/java/org/jclouds/compute/config/BaseComputeServiceContextModule.java b/compute/src/main/java/org/jclouds/compute/config/BaseComputeServiceContextModule.java index a522f13116..da2c3c3cab 100644 --- a/compute/src/main/java/org/jclouds/compute/config/BaseComputeServiceContextModule.java +++ b/compute/src/main/java/org/jclouds/compute/config/BaseComputeServiceContextModule.java @@ -227,14 +227,14 @@ public abstract class BaseComputeServiceContextModule extends AbstractModule { @Memoized protected Supplier> supplyImageCache(AtomicReference authException, @Named(PROPERTY_SESSION_INTERVAL) long seconds, final Supplier> imageSupplier, Injector injector) { - if (shouldParseImagesOnDemand(injector)) { + if (shouldEagerlyParseImages(injector)) { return supplyImageCache(authException, seconds, imageSupplier); } else { return supplyNonParsingImageCache(authException, seconds, imageSupplier, injector); } } - protected boolean shouldParseImagesOnDemand(Injector injector) { + protected boolean shouldEagerlyParseImages(Injector injector) { return true; } diff --git a/compute/src/main/java/org/jclouds/compute/internal/ComputeServiceContextImpl.java b/compute/src/main/java/org/jclouds/compute/internal/ComputeServiceContextImpl.java index dfcfdfdb8f..a2c3235bdd 100644 --- a/compute/src/main/java/org/jclouds/compute/internal/ComputeServiceContextImpl.java +++ b/compute/src/main/java/org/jclouds/compute/internal/ComputeServiceContextImpl.java @@ -20,45 +20,54 @@ package org.jclouds.compute.internal; import static com.google.common.base.Preconditions.checkNotNull; -import java.io.Closeable; import java.util.Map; import javax.inject.Inject; import javax.inject.Singleton; +import org.jclouds.Context; import org.jclouds.compute.ComputeService; import org.jclouds.compute.ComputeServiceContext; import org.jclouds.compute.Utils; import org.jclouds.domain.Credentials; -import org.jclouds.internal.BaseWrapper; +import org.jclouds.internal.BaseView; import org.jclouds.location.Provider; import org.jclouds.rest.RestContext; -import com.google.common.io.Closeables; import com.google.common.reflect.TypeToken; /** * @author Adrian Cole */ @Singleton -public class ComputeServiceContextImpl extends BaseWrapper implements ComputeServiceContext { +public class ComputeServiceContextImpl extends BaseView implements ComputeServiceContext { private final ComputeService computeService; private final Utils utils; - private final Map credentialStore; @Inject - public ComputeServiceContextImpl(@Provider Closeable wrapped, @Provider TypeToken wrappedType, - ComputeService computeService, Map credentialStore, Utils utils) { - super(wrapped, wrappedType); - this.credentialStore = credentialStore; - this.utils = utils; + public ComputeServiceContextImpl(@Provider Context backend, @Provider TypeToken backendType, + ComputeService computeService, Utils utils) { + super(backend, backendType); this.computeService = checkNotNull(computeService, "computeService"); + this.utils = checkNotNull(utils, "utils"); } - + + @Override public ComputeService getComputeService() { return computeService; } + @SuppressWarnings("unchecked") + @Override + public RestContext getProviderSpecificContext() { + return (RestContext) delegate(); + } + + @Override + public void close() { + delegate().close(); + } + @Override public Utils getUtils() { return utils(); @@ -69,39 +78,14 @@ public class ComputeServiceContextImpl extends BaseWrapper implements ComputeSer return utils; } - @Override - public Map getCredentialStore() { - return credentialStore; - } - @Override public Map credentialStore() { - return credentialStore; - } - - @SuppressWarnings("unchecked") - @Override - public RestContext getProviderSpecificContext() { - return (RestContext) getWrapped(); + return utils().credentialStore(); } @Override - public void close() { - Closeables.closeQuietly(getWrapped()); - } - - public int hashCode() { - return getWrapped().hashCode(); - } - - @Override - public String toString() { - return getWrapped().toString(); - } - - @Override - public boolean equals(Object obj) { - return getWrapped().equals(obj); + public Map getCredentialStore() { + return utils().credentialStore(); } } 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 c360046f68..903c4dd880 100644 --- a/compute/src/main/java/org/jclouds/compute/internal/UtilsImpl.java +++ b/compute/src/main/java/org/jclouds/compute/internal/UtilsImpl.java @@ -18,6 +18,7 @@ */ package org.jclouds.compute.internal; +import java.util.Map; import java.util.concurrent.ExecutorService; import javax.inject.Named; @@ -28,6 +29,7 @@ import org.jclouds.compute.Utils; import org.jclouds.compute.domain.NodeMetadata; import org.jclouds.crypto.Crypto; import org.jclouds.date.DateService; +import org.jclouds.domain.Credentials; import org.jclouds.json.Json; import org.jclouds.logging.Logger.LoggerFactory; import org.jclouds.rest.HttpAsyncClient; @@ -53,11 +55,12 @@ 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, - LoggerFactory loggerFactory, Function sshForNode) { + Crypto encryption, DateService date, @Named(Constants.PROPERTY_USER_THREADS) ExecutorService userThreads, + @Named(Constants.PROPERTY_IO_WORKER_THREADS) ExecutorService ioThreads, EventBus eventBus, + Map credentialStore, LoggerFactory loggerFactory, + Function sshForNode) { super(injector, json, xml, simpleClient, simpleAsyncClient, encryption, date, userThreads, ioThreads, eventBus, - loggerFactory); + credentialStore, loggerFactory); this.sshForNode = sshForNode; } diff --git a/compute/src/main/java/org/jclouds/compute/stub/StubApiMetadata.java b/compute/src/main/java/org/jclouds/compute/stub/StubApiMetadata.java index c08c89ab6f..c746563a21 100644 --- a/compute/src/main/java/org/jclouds/compute/stub/StubApiMetadata.java +++ b/compute/src/main/java/org/jclouds/compute/stub/StubApiMetadata.java @@ -62,7 +62,7 @@ public class StubApiMetadata extends BaseApiMetadata { .defaultCredential("stub") .defaultEndpoint("stub") .documentation(URI.create("http://www.jclouds.org/documentation/userguide/compute")) - .wrapper(ComputeServiceContext.class) + .view(ComputeServiceContext.class) .defaultModule(StubComputeServiceContextModule.class); } diff --git a/compute/src/test/java/org/jclouds/compute/internal/BaseComputeServiceApiMetadataTest.java b/compute/src/test/java/org/jclouds/compute/internal/BaseComputeServiceApiMetadataTest.java index 2079f0ef67..8766df08bd 100644 --- a/compute/src/test/java/org/jclouds/compute/internal/BaseComputeServiceApiMetadataTest.java +++ b/compute/src/test/java/org/jclouds/compute/internal/BaseComputeServiceApiMetadataTest.java @@ -1,6 +1,6 @@ package org.jclouds.compute.internal; -import org.jclouds.Wrapper; +import org.jclouds.View; import org.jclouds.apis.ApiMetadata; import org.jclouds.apis.internal.BaseApiMetadataTest; import org.jclouds.compute.ComputeServiceContext; @@ -17,7 +17,7 @@ import com.google.common.reflect.TypeToken; public abstract class BaseComputeServiceApiMetadataTest extends BaseApiMetadataTest { public BaseComputeServiceApiMetadataTest(ApiMetadata toTest) { - super(toTest, ImmutableSet.>of(TypeToken.of(ComputeServiceContext.class))); + super(toTest, ImmutableSet.>of(TypeToken.of(ComputeServiceContext.class))); } } \ No newline at end of file diff --git a/compute/src/test/java/org/jclouds/compute/internal/BaseComputeServiceContextLiveTest.java b/compute/src/test/java/org/jclouds/compute/internal/BaseComputeServiceContextLiveTest.java index c1c4f90d21..c6db584d3b 100644 --- a/compute/src/test/java/org/jclouds/compute/internal/BaseComputeServiceContextLiveTest.java +++ b/compute/src/test/java/org/jclouds/compute/internal/BaseComputeServiceContextLiveTest.java @@ -18,70 +18,18 @@ */ package org.jclouds.compute.internal; -import java.io.InputStream; -import java.util.Properties; -import java.util.concurrent.ConcurrentHashMap; - -import org.jclouds.apis.BaseContextLiveTest; import org.jclouds.compute.ComputeServiceContext; -import org.jclouds.domain.LoginCredentials; -import org.jclouds.domain.LoginCredentials.Builder; -import org.jclouds.io.CopyInputStreamInputSupplierMap; -import org.jclouds.rest.config.CredentialStoreModule; -import com.google.common.base.Splitter; -import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Iterables; -import com.google.common.io.InputSupplier; import com.google.common.reflect.TypeToken; -import com.google.inject.Module; -import com.google.inject.util.Modules; /** * @author Jason King, Adrian Cole */ -public abstract class BaseComputeServiceContextLiveTest extends BaseContextLiveTest { +public abstract class BaseComputeServiceContextLiveTest extends BaseGenericComputeServiceContextLiveTest { - protected String imageId; - protected String loginUser; - protected String authenticateSudo; - protected LoginCredentials loginCredentials = LoginCredentials.builder().user("root").build(); - - // isolate tests from eachother, as default credentialStore is static - protected Module credentialStoreModule = new CredentialStoreModule(new CopyInputStreamInputSupplierMap( - new ConcurrentHashMap>())); - @Override - protected TypeToken contextType() { + protected TypeToken viewType() { return TypeToken.of(ComputeServiceContext.class); } - @Override - protected Properties setupProperties() { - Properties overrides = super.setupProperties(); - imageId = setIfTestSystemPropertyPresent(overrides, provider + ".image-id"); - loginUser = setIfTestSystemPropertyPresent(overrides, provider + ".image.login-user"); - authenticateSudo = setIfTestSystemPropertyPresent(overrides, provider + ".image.authenticate-sudo"); - - if (loginUser != null) { - Iterable userPass = Splitter.on(':').split(loginUser); - Builder loginCredentialsBuilder = LoginCredentials.builder(); - loginCredentialsBuilder.user(Iterables.get(userPass, 0)); - if (Iterables.size(userPass) == 2) - loginCredentialsBuilder.password(Iterables.get(userPass, 1)); - if (authenticateSudo != null) - loginCredentialsBuilder.authenticateSudo(Boolean.valueOf(authenticateSudo)); - loginCredentials = loginCredentialsBuilder.build(); - } - return overrides; - } - - @Override - protected Iterable setupModules() { - return ImmutableSet. of(getLoggingModule(), credentialStoreModule, getSshModule()); - } - - protected Module getSshModule() { - return Modules.EMPTY_MODULE; - } } 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 eff4c31be0..33fa6243d6 100644 --- a/compute/src/test/java/org/jclouds/compute/internal/BaseComputeServiceLiveTest.java +++ b/compute/src/test/java/org/jclouds/compute/internal/BaseComputeServiceLiveTest.java @@ -31,7 +31,6 @@ import static com.google.common.collect.Sets.newTreeSet; import static java.lang.String.format; import static java.lang.System.currentTimeMillis; import static java.util.logging.Logger.getAnonymousLogger; -import static org.jclouds.compute.RunScriptData.JBOSS7_URL; import static org.jclouds.compute.RunScriptData.JBOSS_HOME; import static org.jclouds.compute.RunScriptData.installAdminUserJBossAndOpenPorts; import static org.jclouds.compute.RunScriptData.startJBoss; @@ -49,8 +48,6 @@ import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertNotNull; import java.io.IOException; -import java.io.InputStream; -import java.net.URI; import java.util.Collection; import java.util.Map; import java.util.NoSuchElementException; @@ -91,7 +88,6 @@ import org.jclouds.net.IPSocket; import org.jclouds.predicates.RetryablePredicate; import org.jclouds.predicates.SocketOpen; import org.jclouds.rest.AuthorizationException; -import org.jclouds.scriptbuilder.domain.SaveHttpResponseTo; import org.jclouds.scriptbuilder.domain.Statements; import org.jclouds.scriptbuilder.statements.java.InstallJDK; import org.jclouds.scriptbuilder.statements.login.AdminAccess; @@ -109,9 +105,7 @@ import com.google.common.base.Stopwatch; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Iterables; -import com.google.common.net.InetAddresses; import com.google.common.util.concurrent.ListenableFuture; -import com.google.gson.annotations.SerializedName; import com.google.inject.Module; /** @@ -156,7 +150,7 @@ public abstract class BaseComputeServiceLiveTest extends BaseComputeServiceConte protected void buildSocketTester() { - SocketOpen socketOpen = context.utils().injector().getInstance(SocketOpen.class); + SocketOpen socketOpen = view.utils().injector().getInstance(SocketOpen.class); socketTester = new RetryablePredicate(socketOpen, 60, 1, TimeUnit.SECONDS); // wait a maximum of 60 seconds for port 8080 to open. long maxWait = TimeUnit.SECONDS.toMillis(60); @@ -168,7 +162,7 @@ public abstract class BaseComputeServiceLiveTest extends BaseComputeServiceConte @Override protected void initializeContext() { super.initializeContext(); - client = context.getComputeService(); + client = view.getComputeService(); } // wait up to 5 seconds for an auth exception @@ -326,7 +320,7 @@ public abstract class BaseComputeServiceLiveTest extends BaseComputeServiceConte } protected void checkHttpGet(NodeMetadata node) { - ComputeTestUtils.checkHttpGet(context.utils().http(), node, 8080); + ComputeTestUtils.checkHttpGet(view.utils().http(), node, 8080); } @Test(enabled = true, dependsOnMethods = "testCompareSizes") @@ -422,7 +416,7 @@ public abstract class BaseComputeServiceLiveTest extends BaseComputeServiceConte public void testCredentialsCache() throws Exception { initializeContext(); for (NodeMetadata node : nodes) - assert (context.getCredentialStore().get("node#" + node.getId()) != null) : "credentials for " + node.getId(); + assert (view.utils().credentialStore().get("node#" + node.getId()) != null) : "credentials for " + node.getId(); } protected Map runScriptWithCreds(final String group, OperatingSystem os, @@ -437,7 +431,7 @@ public abstract class BaseComputeServiceLiveTest extends BaseComputeServiceConte assertNotNull(node.getGroup()); assertEquals(node.getGroup(), group); assertEquals(node.getState(), NodeState.RUNNING); - Credentials fromStore = context.getCredentialStore().get("node#" + node.getId()); + Credentials fromStore = view.utils().credentialStore().get("node#" + node.getId()); assertEquals(fromStore, node.getCredentials()); assert node.getPublicAddresses().size() >= 1 || node.getPrivateAddresses().size() >= 1 : "no ips in" + node; assertNotNull(node.getCredentials()); @@ -554,7 +548,7 @@ public abstract class BaseComputeServiceLiveTest extends BaseComputeServiceConte assertEquals(toDestroy, destroyed.size()); for (NodeMetadata node : filter(client.listNodesDetailsMatching(all()), inGroup(group))) { assert node.getState() == NodeState.TERMINATED : node; - assert context.getCredentialStore().get("node#" + node.getId()) == null : "credential should have been null for " + assert view.utils().credentialStore().get("node#" + node.getId()) == null : "credential should have been null for " + "node#" + node.getId(); } } @@ -608,21 +602,6 @@ public abstract class BaseComputeServiceLiveTest extends BaseComputeServiceConte // started in 6462ms - public static final Pattern JBOSS_PATTERN = Pattern.compile("started in ([0-9]+)ms -"); - private static class FreeGeoIPLocation { - private String ip; - @SerializedName("countrycode") - private String countryCode; - @SerializedName("regioncode") - private String regionCode; - private String city; - - @Override - public String toString() { - return format("FreeGeoIPLocation [ip=%s, countryCode=%s, regionCode=%s, city=%s]", ip, countryCode, - regionCode, city); - } - } - @Test(enabled = true) public void testCreateAndRunAService() throws Exception { @@ -671,33 +650,7 @@ public abstract class BaseComputeServiceLiveTest extends BaseComputeServiceConte format("ls %s/bundles/org/jboss/as/osgi/configadmin/main|sed -e 's/.*-//g' -e 's/.jar//g'", JBOSS_HOME)), configureSeconds)); - for (Entry download : ImmutableMap. of("jboss7", JBOSS7_URL, "jdk7", - URI.create("http://download.oracle.com/otn-pub/java/jdk/7/jdk-7-linux-x64.tar.gz")).entrySet()) { - // note we cannot use nslookup until we've configured the system, as - // it may have not been present checking the address of the download - // host using the local node's DNS config - String downloadSourceIp = exec( - nodeId, - format("nslookup -query=a -timeout=5 %s|grep Address|tail -1|sed 's/.* //g'", download.getValue() - .getHost())); - if (InetAddresses.isInetAddress(downloadSourceIp)) { - getAnonymousLogger().info( - format("<< location of %s(%s) from perpective of node(%s): %s", download.getKey(), download - .getValue().getHost(), nodeId, getLocationForIp(downloadSourceIp))); - } - } - - // the current IP configuration could show NAT destinations, as opposed - // to the real ip address of the host, so we'll use checkip to see what - // the world view this host as. - String nodeIp = exec(nodeId, SaveHttpResponseTo.CURL + " http://checkip.amazonaws.com/"); - if (InetAddresses.isInetAddress(nodeIp)) { - getAnonymousLogger() - .info(format("<< location of node(%s) from perspective of amazonaws: %s", nodeId, - getLocationForIp(nodeIp))); - } - - trackAvailabilityOfProcessOnNode(context.utils().userExecutor().submit(new Callable() { + trackAvailabilityOfProcessOnNode(view.utils().userExecutor().submit(new Callable() { @Override public ExecResponse call() { return client.runScriptOnNode(nodeId, startJBoss(configuration), runAsRoot(false).blockOnComplete(false) @@ -713,7 +666,7 @@ public abstract class BaseComputeServiceLiveTest extends BaseComputeServiceConte client.runScriptOnNode(nodeId, "/tmp/init-jboss stop", runAsRoot(false).wrapInInitScript(false)); - trackAvailabilityOfProcessOnNode(context.utils().userExecutor().submit(new Callable() { + trackAvailabilityOfProcessOnNode(view.utils().userExecutor().submit(new Callable() { @Override public ExecResponse call() { @@ -733,17 +686,6 @@ public abstract class BaseComputeServiceLiveTest extends BaseComputeServiceConte } - protected String getLocationForIp(String ip) throws IOException { - InputStream json = context.utils().http().get(URI.create("http://freegeoip.appspot.com/" + ip)); - String text = null; - if (json != null && (text = Strings2.toStringAndClose(json)).indexOf("}") != -1) { - return context.utils().json().fromJson(text, FreeGeoIPLocation.class).toString(); - } else { - getAnonymousLogger().warning("could not get info on ip " + ip + "; check freegeoip"); - } - return ip; - } - protected String exec(final String nodeId, String command) { return client.runScriptOnNode(nodeId, command, runAsRoot(false).wrapInInitScript(false)).getOutput().trim(); } @@ -872,7 +814,7 @@ public abstract class BaseComputeServiceLiveTest extends BaseComputeServiceConte } protected void doCheckJavaIsInstalledViaSsh(NodeMetadata node, String taskName) throws IOException { - SshClient ssh = context.utils().sshForNode().apply(node); + SshClient ssh = view.utils().sshForNode().apply(node); try { ssh.connect(); ExecResponse hello = ssh.exec("echo hello"); diff --git a/compute/src/test/java/org/jclouds/compute/internal/BaseGenericComputeServiceContextLiveTest.java b/compute/src/test/java/org/jclouds/compute/internal/BaseGenericComputeServiceContextLiveTest.java new file mode 100644 index 0000000000..c26b11f93d --- /dev/null +++ b/compute/src/test/java/org/jclouds/compute/internal/BaseGenericComputeServiceContextLiveTest.java @@ -0,0 +1,81 @@ +/** + * 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.compute.internal; + +import java.io.InputStream; +import java.util.Properties; +import java.util.concurrent.ConcurrentHashMap; + +import org.jclouds.apis.BaseViewLiveTest; +import org.jclouds.compute.ComputeServiceContext; +import org.jclouds.domain.LoginCredentials; +import org.jclouds.domain.LoginCredentials.Builder; +import org.jclouds.io.CopyInputStreamInputSupplierMap; +import org.jclouds.rest.config.CredentialStoreModule; + +import com.google.common.base.Splitter; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Iterables; +import com.google.common.io.InputSupplier; +import com.google.inject.Module; +import com.google.inject.util.Modules; + +/** + * @author Jason King, Adrian Cole + */ +public abstract class BaseGenericComputeServiceContextLiveTest extends BaseViewLiveTest { + + protected String imageId; + protected String loginUser; + protected String authenticateSudo; + protected LoginCredentials loginCredentials = LoginCredentials.builder().user("root").build(); + + // isolate tests from eachother, as default credentialStore is static + protected Module credentialStoreModule = new CredentialStoreModule(new CopyInputStreamInputSupplierMap( + new ConcurrentHashMap>())); + + @Override + protected Properties setupProperties() { + Properties overrides = super.setupProperties(); + imageId = setIfTestSystemPropertyPresent(overrides, provider + ".image-id"); + loginUser = setIfTestSystemPropertyPresent(overrides, provider + ".image.login-user"); + authenticateSudo = setIfTestSystemPropertyPresent(overrides, provider + ".image.authenticate-sudo"); + + if (loginUser != null) { + Iterable userPass = Splitter.on(':').split(loginUser); + Builder loginCredentialsBuilder = LoginCredentials.builder(); + loginCredentialsBuilder.user(Iterables.get(userPass, 0)); + if (Iterables.size(userPass) == 2) + loginCredentialsBuilder.password(Iterables.get(userPass, 1)); + if (authenticateSudo != null) + loginCredentialsBuilder.authenticateSudo(Boolean.valueOf(authenticateSudo)); + loginCredentials = loginCredentialsBuilder.build(); + } + return overrides; + } + + @Override + protected Iterable setupModules() { + return ImmutableSet. of(getLoggingModule(), credentialStoreModule, getSshModule()); + } + + protected Module getSshModule() { + return Modules.EMPTY_MODULE; + } +} diff --git a/compute/src/test/java/org/jclouds/compute/internal/BaseImageExtensionLiveTest.java b/compute/src/test/java/org/jclouds/compute/internal/BaseImageExtensionLiveTest.java index 896e1ffdf4..3bb31df3bf 100644 --- a/compute/src/test/java/org/jclouds/compute/internal/BaseImageExtensionLiveTest.java +++ b/compute/src/test/java/org/jclouds/compute/internal/BaseImageExtensionLiveTest.java @@ -53,13 +53,13 @@ public abstract class BaseImageExtensionLiveTest extends BaseComputeServiceConte * @return */ public Template getNodeTemplate() { - return context.getComputeService().templateBuilder().any().build(); + return view.getComputeService().templateBuilder().any().build(); } @Test(groups = { "integration", "live" }, singleThreaded = true) public void testCreateImage() throws RunNodesException, InterruptedException { - ComputeService computeService = context.getComputeService(); + ComputeService computeService = view.getComputeService(); Optional imageExtension = computeService.getImageExtension(); assertTrue("image extension was not present", imageExtension.isPresent()); @@ -87,20 +87,20 @@ public abstract class BaseImageExtensionLiveTest extends BaseComputeServiceConte @Test(groups = { "integration", "live" }, singleThreaded = true, dependsOnMethods = "testCreateImage") public void testSpawnNodeFromImage() throws RunNodesException { - ComputeService computeService = context.getComputeService(); + ComputeService computeService = view.getComputeService(); Template template = computeService.templateBuilder().fromImage(getImage().get()).build(); NodeMetadata node = Iterables.getOnlyElement(computeService.createNodesInGroup("test-create-image", 1, template)); - SshClient client = context.utils().sshForNode().apply(node); + SshClient client = view.utils().sshForNode().apply(node); client.connect(); ExecResponse hello = client.exec("echo hello"); assertEquals(hello.getOutput().trim(), "hello"); - context.getComputeService().destroyNode(node.getId()); + view.getComputeService().destroyNode(node.getId()); } @@ -108,7 +108,7 @@ public abstract class BaseImageExtensionLiveTest extends BaseComputeServiceConte "testSpawnNodeFromImage" }) public void testDeleteImage() { - ComputeService computeService = context.getComputeService(); + ComputeService computeService = view.getComputeService(); Optional imageExtension = computeService.getImageExtension(); assertTrue("image extension was not present", imageExtension.isPresent()); @@ -123,7 +123,7 @@ public abstract class BaseImageExtensionLiveTest extends BaseComputeServiceConte } private Optional getImage() { - return Iterables.tryFind(context.getComputeService().listImages(), new Predicate() { + return Iterables.tryFind(view.getComputeService().listImages(), new Predicate() { @Override public boolean apply(Image input) { return input.getId().contains("test-create-image"); diff --git a/compute/src/test/java/org/jclouds/compute/internal/BaseTemplateBuilderLiveTest.java b/compute/src/test/java/org/jclouds/compute/internal/BaseTemplateBuilderLiveTest.java index 51fe154b80..d79e9e5ea0 100644 --- a/compute/src/test/java/org/jclouds/compute/internal/BaseTemplateBuilderLiveTest.java +++ b/compute/src/test/java/org/jclouds/compute/internal/BaseTemplateBuilderLiveTest.java @@ -63,15 +63,14 @@ import com.google.inject.Module; * @author Adrian Cole */ @Test(groups = "integration,live") -public abstract class BaseTemplateBuilderLiveTest extends - BaseComputeServiceContextLiveTest { +public abstract class BaseTemplateBuilderLiveTest extends BaseComputeServiceContextLiveTest { public void testCompareSizes() throws Exception { - Hardware defaultSize = context.getComputeService().templateBuilder().build().getHardware(); + Hardware defaultSize = view.getComputeService().templateBuilder().build().getHardware(); - Hardware smallest = context.getComputeService().templateBuilder().smallest().build().getHardware(); - Hardware fastest = context.getComputeService().templateBuilder().fastest().build().getHardware(); - Hardware biggest = context.getComputeService().templateBuilder().biggest().build().getHardware(); + Hardware smallest = view.getComputeService().templateBuilder().smallest().build().getHardware(); + Hardware fastest = view.getComputeService().templateBuilder().fastest().build().getHardware(); + Hardware biggest = view.getComputeService().templateBuilder().biggest().build().getHardware(); System.out.printf("smallest %s%n", smallest); System.out.printf("fastest %s%n", fastest); @@ -90,8 +89,8 @@ public abstract class BaseTemplateBuilderLiveTest extends } public void testFromTemplate() { - Template defaultTemplate = context.getComputeService().templateBuilder().build(); - assertEquals(context.getComputeService().templateBuilder().fromTemplate(defaultTemplate).build().toString(), + Template defaultTemplate = view.getComputeService().templateBuilder().build(); + assertEquals(view.getComputeService().templateBuilder().fromTemplate(defaultTemplate).build().toString(), defaultTemplate.toString()); } @@ -135,7 +134,7 @@ public abstract class BaseTemplateBuilderLiveTest extends @Test(dataProvider = "osSupported") public void testTemplateBuilderCanFind(OsFamilyVersion64Bit matrix) throws InterruptedException { - TemplateBuilder builder = context.getComputeService().templateBuilder().osFamily(matrix.family) + TemplateBuilder builder = view.getComputeService().templateBuilder().osFamily(matrix.family) .os64Bit(matrix.is64Bit); if (!matrix.version.equals("")) builder.osVersionMatches("^" + matrix.version + "$"); @@ -148,7 +147,7 @@ public abstract class BaseTemplateBuilderLiveTest extends @Test(dataProvider = "osNotSupported", expectedExceptions = NoSuchElementException.class) public void testTemplateBuilderCannotFind(OsFamilyVersion64Bit matrix) throws InterruptedException { - TemplateBuilder builder = context.getComputeService().templateBuilder().osFamily(matrix.family) + TemplateBuilder builder = view.getComputeService().templateBuilder().osFamily(matrix.family) .os64Bit(matrix.is64Bit); if (!matrix.version.equals("")) builder.osVersionMatches("^" + matrix.version + "$"); @@ -157,18 +156,18 @@ public abstract class BaseTemplateBuilderLiveTest extends @Test public void testTemplateBuilderCanUseImageId() throws Exception { - Template defaultTemplate = context.getComputeService().templateBuilder().build(); - context.close(); + Template defaultTemplate = view.getComputeService().templateBuilder().build(); + view.close(); setupContext(); - Template template = context.getComputeService().templateBuilder().imageId(defaultTemplate.getImage().getId()) + Template template = view.getComputeService().templateBuilder().imageId(defaultTemplate.getImage().getId()) .locationId(defaultTemplate.getLocation().getId()).build(); assertEquals(template.getImage(), defaultTemplate.getImage()); } @Test public void testDefaultTemplateBuilder() throws IOException { - Template defaultTemplate = context.getComputeService().templateBuilder().build(); + Template defaultTemplate = view.getComputeService().templateBuilder().build(); assert defaultTemplate.getImage().getOperatingSystem().getVersion().matches("1[012].[10][04]") : defaultTemplate .getImage().getOperatingSystem().getVersion(); assertEquals(defaultTemplate.getImage().getOperatingSystem().is64Bit(), true); @@ -180,9 +179,8 @@ public abstract class BaseTemplateBuilderLiveTest extends @Test(groups = { "integration", "live" }) public void testGetAssignableLocations() throws Exception { - if (context.unwrap() instanceof Location) - assertProvider(Location.class.cast(context.unwrap())); - for (Location location : context.getComputeService().listAssignableLocations()) { + assertProvider(view.unwrap()); + for (Location location : view.getComputeService().listAssignableLocations()) { System.err.printf("location %s%n", location); assert location.getId() != null : location; assert location != location.getParent() : location; @@ -220,14 +218,14 @@ public abstract class BaseTemplateBuilderLiveTest extends @Test public void testTemplateBuilderWithImageIdSpecified() throws IOException { - Template defaultTemplate = context.getComputeService().templateBuilder().build(); + Template defaultTemplate = view.getComputeService().templateBuilder().build(); ComputeServiceContext context = null; try { Properties overrides = setupProperties(); overrides.setProperty("jclouds.image-id", defaultTemplate.getImage().getId()); - context = createContext(overrides, setupModules()); + context = createView(overrides, setupModules()); assertEquals(context.getComputeService().templateBuilder().build().toString(), defaultTemplate.toString()); } finally { @@ -240,7 +238,7 @@ public abstract class BaseTemplateBuilderLiveTest extends Properties overrides = setupProperties(); overrides.setProperty(provider + ".image-id", defaultTemplate.getImage().getId()); - context = createContext(overrides, setupModules()); + context = createView(overrides, setupModules()); assertEquals(context.getComputeService().templateBuilder().build().toString(), defaultTemplate.toString()); } finally { @@ -268,7 +266,7 @@ public abstract class BaseTemplateBuilderLiveTest extends boolean auth = authenticateSudo != null ? Boolean.valueOf(authenticateSudo) : true; overrides.setProperty(propertyKey + ".image.authenticate-sudo", auth + ""); - context = createContext(overrides, ImmutableSet.of(credentialStoreModule)); + context = createView(overrides, ImmutableSet.of(credentialStoreModule)); Iterable userPass = Splitter.on(':').split(login); String user = Iterables.get(userPass, 0); diff --git a/compute/src/test/resources/initscript_with_java.sh b/compute/src/test/resources/initscript_with_java.sh index d7bbeed3ea..093c4c2c2f 100644 --- a/compute/src/test/resources/initscript_with_java.sh +++ b/compute/src/test/resources/initscript_with_java.sh @@ -90,7 +90,7 @@ function ensure_cmd_or_install_package_apt(){ local cmd=$1 local pkg=$2 - hash $cmd 2>/dev/null || apt-get-install $pkg || ( apt-get-update && apt-get-install $pkg ) + hash $cmd 2>/dev/null || ( apt-get-update && apt-get-install $pkg ) } function ensure_cmd_or_install_package_yum(){ @@ -155,7 +155,7 @@ END_OF_JCLOUDS_FILE function installOpenJDK() { if hash apt-get 2>/dev/null; then export JAVA_HOME=${JAVA_HOME:-/usr/lib/jvm/java-6-openjdk} - test -d $JAVA_HOME || apt-get-install openjdk-6-jdk || ( apt-get-update && apt-get-install openjdk-6-jdk ) + test -d $JAVA_HOME || ( apt-get-update && apt-get-install openjdk-6-jdk ) elif hash yum 2>/dev/null; then export pkg=java-1.6.0-openjdk-devel yum --nogpgcheck -y install $pkg && diff --git a/compute/src/test/resources/initscript_with_jboss.sh b/compute/src/test/resources/initscript_with_jboss.sh index edec50effd..f9bd79504b 100644 --- a/compute/src/test/resources/initscript_with_jboss.sh +++ b/compute/src/test/resources/initscript_with_jboss.sh @@ -90,7 +90,7 @@ function ensure_cmd_or_install_package_apt(){ local cmd=$1 local pkg=$2 - hash $cmd 2>/dev/null || apt-get-install $pkg || ( apt-get-update && apt-get-install $pkg ) + hash $cmd 2>/dev/null || ( apt-get-update && apt-get-install $pkg ) } function ensure_cmd_or_install_package_yum(){ @@ -155,7 +155,7 @@ END_OF_JCLOUDS_FILE function installOpenJDK() { if hash apt-get 2>/dev/null; then export JAVA_HOME=${JAVA_HOME:-/usr/lib/jvm/java-6-openjdk} - test -d $JAVA_HOME || apt-get-install openjdk-6-jdk || ( apt-get-update && apt-get-install openjdk-6-jdk ) + test -d $JAVA_HOME || ( apt-get-update && apt-get-install openjdk-6-jdk ) elif hash yum 2>/dev/null; then export pkg=java-1.6.0-openjdk-devel yum --nogpgcheck -y install $pkg && diff --git a/compute/src/test/resources/runscript.sh b/compute/src/test/resources/runscript.sh index 1c45816838..44d5880cde 100644 --- a/compute/src/test/resources/runscript.sh +++ b/compute/src/test/resources/runscript.sh @@ -90,7 +90,7 @@ function ensure_cmd_or_install_package_apt(){ local cmd=$1 local pkg=$2 - hash $cmd 2>/dev/null || apt-get-install $pkg || ( apt-get-update && apt-get-install $pkg ) + hash $cmd 2>/dev/null || ( apt-get-update && apt-get-install $pkg ) } function ensure_cmd_or_install_package_yum(){ @@ -155,7 +155,7 @@ END_OF_JCLOUDS_FILE function installOpenJDK() { if hash apt-get 2>/dev/null; then export JAVA_HOME=${JAVA_HOME:-/usr/lib/jvm/java-6-openjdk} - test -d $JAVA_HOME || apt-get-install openjdk-6-jdk || ( apt-get-update && apt-get-install openjdk-6-jdk ) + test -d $JAVA_HOME || ( apt-get-update && apt-get-install openjdk-6-jdk ) elif hash yum 2>/dev/null; then export pkg=java-1.6.0-openjdk-devel yum --nogpgcheck -y install $pkg && diff --git a/core/src/main/java/org/jclouds/Context.java b/core/src/main/java/org/jclouds/Context.java new file mode 100644 index 0000000000..2e70b8732d --- /dev/null +++ b/core/src/main/java/org/jclouds/Context.java @@ -0,0 +1,119 @@ +/** + * 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; + +import java.io.Closeable; +import java.net.URI; +import java.util.Map; + +import org.jclouds.apis.ApiMetadata; +import org.jclouds.domain.Credentials; +import org.jclouds.domain.Location; +import org.jclouds.internal.ContextImpl; +import org.jclouds.javax.annotation.Nullable; +import org.jclouds.providers.ProviderMetadata; +import org.jclouds.rest.Utils; + +import com.google.common.annotations.Beta; +import com.google.inject.ImplementedBy; + +/** + * Represents an authenticated context to the cloud. + * + *

Note

Please issue {@link #close()} when you are finished with this context in order to + * release resources. + * + * + * @author Adrian Cole + * + */ +@ImplementedBy(ContextImpl.class) +public interface Context extends Location, Closeable { + + /** + * will be removed in jclouds 1.6 + * + * @see Utils#getCredentialStore() + */ + @Deprecated + @Beta + Map getCredentialStore(); + + /** + * will be removed in jclouds 1.6 + * + * @see Utils#credentialStore() + */ + @Deprecated + @Beta + Map credentialStore(); + + /** + * @return the providerMetadata used to create this context + * @see ContextBuilder#newBuilder(org.jclouds.providers.ProviderMetadata) + */ + ProviderMetadata getProviderMetadata(); + + /** + * @return the current login user, access key, email, or whatever the 'identity' field was building the context. + * @see ApiMetadata#getDefaultIdentity + */ + String getIdentity(); + + /** + * will be removed in jclouds 1.6 + * @see #getProviderMetadata() + * @see ProviderMetadata#getEndpoint() + */ + @Deprecated + URI getEndpoint(); + + /** + * will be removed in jclouds 1.6 + * @see #getProviderMetadata() + * @see ProviderMetadata#getApiMetadata() + * @see ApiMetadata#getVersion() + */ + @Deprecated + String getApiVersion(); + + /** + * will be removed in jclouds 1.6 + * @see #getProviderMetadata() + * @see ProviderMetadata#getApiMetadata() + * @see ApiMetadata#getBuildVersion() + */ + @Deprecated + @Nullable + String getBuildVersion(); + + Utils getUtils(); + + /** + * @see #getUtils + */ + Utils utils(); + + /** + * Closes all connections, including executor service + */ + @Override + void close(); + +} \ No newline at end of file diff --git a/core/src/main/java/org/jclouds/ContextBuilder.java b/core/src/main/java/org/jclouds/ContextBuilder.java index b57dd40359..eed4b9c408 100644 --- a/core/src/main/java/org/jclouds/ContextBuilder.java +++ b/core/src/main/java/org/jclouds/ContextBuilder.java @@ -19,9 +19,17 @@ package org.jclouds; import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.base.Predicates.containsPattern; import static com.google.common.base.Predicates.instanceOf; +import static com.google.common.base.Predicates.not; +import static com.google.common.base.Predicates.notNull; +import static com.google.common.base.Throwables.propagate; import static com.google.common.collect.Iterables.addAll; import static com.google.common.collect.Iterables.any; +import static com.google.common.collect.Iterables.filter; +import static com.google.common.collect.Iterables.find; +import static com.google.common.collect.Iterables.transform; +import static com.google.common.collect.Lists.newArrayList; import static org.jclouds.Constants.PROPERTY_API; import static org.jclouds.Constants.PROPERTY_API_VERSION; import static org.jclouds.Constants.PROPERTY_BUILD_VERSION; @@ -32,14 +40,12 @@ import static org.jclouds.Constants.PROPERTY_ISO3166_CODES; import static org.jclouds.Constants.PROPERTY_PROVIDER; import static org.jclouds.util.Throwables2.propagateAuthorizationOrOriginalException; -import java.io.Closeable; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.NoSuchElementException; import java.util.Properties; - -import javax.inject.Singleton; +import java.util.Set; import org.jclouds.apis.ApiMetadata; import org.jclouds.apis.Apis; @@ -47,6 +53,9 @@ import org.jclouds.concurrent.MoreExecutors; import org.jclouds.concurrent.SingleThreaded; import org.jclouds.concurrent.config.ConfiguresExecutorService; import org.jclouds.concurrent.config.ExecutorServiceModule; +import org.jclouds.config.BindPropertiesToExpandedValues; +import org.jclouds.config.BindRestContextWithWildcardExtendsExplicitAndRawType; +import org.jclouds.domain.Credentials; import org.jclouds.events.config.ConfiguresEventBus; import org.jclouds.events.config.EventBusModule; import org.jclouds.http.config.ConfiguresHttpCommandExecutorService; @@ -54,48 +63,40 @@ import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule; import org.jclouds.javax.annotation.Nullable; import org.jclouds.lifecycle.Closer; import org.jclouds.lifecycle.config.LifeCycleModule; -import org.jclouds.location.Provider; import org.jclouds.logging.config.LoggingModule; import org.jclouds.logging.jdk.config.JDKLoggingModule; -import org.jclouds.providers.AnonymousProviderMetadata; import org.jclouds.providers.ProviderMetadata; import org.jclouds.providers.Providers; +import org.jclouds.providers.config.BindProviderMetadataContextAndCredentials; +import org.jclouds.providers.internal.UpdateProviderMetadataFromProperties; import org.jclouds.rest.ConfiguresCredentialStore; import org.jclouds.rest.ConfiguresRestClient; import org.jclouds.rest.RestApiMetadata; import org.jclouds.rest.RestContext; -import org.jclouds.rest.config.BindPropertiesToAnnotations; import org.jclouds.rest.config.CredentialStoreModule; import org.jclouds.rest.config.RestClientModule; import org.jclouds.rest.config.RestModule; -import org.jclouds.rest.internal.BaseRestApiMetadata; -import org.jclouds.rest.internal.RestContextImpl; -import org.nnsoft.guice.rocoto.Rocoto; -import org.nnsoft.guice.rocoto.configuration.ConfigurationModule; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Function; import com.google.common.base.Joiner; import com.google.common.base.Objects; +import com.google.common.base.Optional; import com.google.common.base.Predicate; -import com.google.common.base.Predicates; -import com.google.common.base.Throwables; +import com.google.common.base.Splitter; +import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMultimap; -import com.google.common.collect.Iterables; -import com.google.common.collect.Lists; +import com.google.common.collect.ImmutableSet; import com.google.common.collect.Maps; import com.google.common.collect.ImmutableMultimap.Builder; import com.google.common.reflect.TypeToken; import com.google.common.util.concurrent.ExecutionList; -import com.google.inject.AbstractModule; import com.google.inject.Guice; import com.google.inject.Injector; import com.google.inject.Key; import com.google.inject.Module; -import com.google.inject.Provides; import com.google.inject.Stage; import com.google.inject.TypeLiteral; -import com.google.inject.util.Types; /** * Creates {@link RestContext} or {@link Injector} instances based on the most commonly requested @@ -110,54 +111,7 @@ import com.google.inject.util.Types; * @author Adrian Cole, Andrew Newdigate * @see RestContext */ -public final class ContextBuilder { - - static class ResolveRestContextModule extends AbstractModule { - private final RestApiMetadata restApiMetadata; - - ResolveRestContextModule(RestApiMetadata restApiMetadata) { - this.restApiMetadata = restApiMetadata; - } - - @SuppressWarnings("unchecked") - @Override - protected void configure() { - if (restApiMetadata.getContext().getRawType().equals(RestContext.class)) { - TypeToken concreteType = BaseRestApiMetadata.contextToken(TypeToken.of(restApiMetadata.getApi()), TypeToken - .of(restApiMetadata.getAsyncApi())); - // bind explicit type - bind(TypeLiteral.get(concreteType.getType())).to( - (TypeLiteral) TypeLiteral.get(Types.newParameterizedType(RestContextImpl.class, restApiMetadata - .getApi(), restApiMetadata.getAsyncApi()))); - // bind potentially wildcard type - if (!concreteType.equals(restApiMetadata.getContext())) { - bind(TypeLiteral.get(restApiMetadata.getContext().getType())).to( - (TypeLiteral) TypeLiteral.get(Types.newParameterizedType(RestContextImpl.class, restApiMetadata - .getApi(), restApiMetadata.getAsyncApi()))); - } - // bind w/o types - bind(TypeLiteral.get(RestContext.class)).to( - (TypeLiteral) TypeLiteral.get(Types.newParameterizedType(RestContextImpl.class, restApiMetadata - .getApi(), restApiMetadata.getAsyncApi()))); - } - } - } - - private final class BindDefaultContextQualifiedToProvider extends AbstractModule { - @Override - protected void configure() { - bind(new TypeLiteral>() { - }).annotatedWith(Provider.class).toInstance(apiMetadata.getContext()); - } - - @SuppressWarnings("unused") - @Provides - @Provider - @Singleton - protected Closeable wrapped(Injector i, @Provider TypeToken wrappedType) { - return (Closeable) i.getInstance(Key.get(TypeLiteral.get(wrappedType.getType()))); - } - } +public class ContextBuilder { /** * looks up a provider or api with the given id @@ -177,8 +131,8 @@ public final class ContextBuilder { } } catch (NoSuchElementException e) { Builder builder = ImmutableMultimap. builder(); - builder.putAll("providers", Iterables.transform(Providers.all(), Providers.idFunction())); - builder.putAll("apis", Iterables.transform(Apis.all(), Apis.idFunction())); + builder.putAll("providers", transform(Providers.all(), Providers.idFunction())); + builder.putAll("apis", transform(Apis.all(), Apis.idFunction())); throw new NoSuchElementException(String.format("key [%s] not in the list of providers or apis: %s", providerOrApi, builder.build())); } @@ -200,14 +154,16 @@ public final class ContextBuilder { } } - protected ProviderMetadata providerMetadata; - protected String endpoint; - protected String identity; + protected Optional providerMetadata = Optional.absent(); + protected final String providerId; + protected Optional endpoint = Optional.absent(); + protected Optional identity = Optional.absent(); + @Nullable protected String credential; protected ApiMetadata apiMetadata; protected String apiVersion; protected String buildVersion; - protected Properties overrides = new Properties();; + protected Optional overrides = Optional.absent(); protected List modules = new ArrayList(3); @Override @@ -217,36 +173,37 @@ public final class ContextBuilder { } protected ContextBuilder(ProviderMetadata providerMetadata) { - this(providerMetadata, providerMetadata.getApiMetadata()); + this(providerMetadata, checkNotNull(providerMetadata, "providerMetadata").getApiMetadata()); } protected ContextBuilder(@Nullable ProviderMetadata providerMetadata, ApiMetadata apiMetadata) { this.apiMetadata = checkNotNull(apiMetadata, "apiMetadata"); - this.providerMetadata = providerMetadata; - if (providerMetadata != null) - this.endpoint = providerMetadata.getEndpoint(); - if (apiMetadata.getDefaultIdentity().isPresent()) - identity = apiMetadata.getDefaultIdentity().get(); - if (apiMetadata.getDefaultCredential().isPresent()) - credential = apiMetadata.getDefaultCredential().get(); + if (providerMetadata != null) { + this.providerMetadata = Optional.of(providerMetadata); + this.endpoint = Optional.of(providerMetadata.getEndpoint()); + this.providerId = providerMetadata.getId(); + } else { + this.endpoint = apiMetadata.getDefaultEndpoint(); + this.providerId = apiMetadata.getId(); + } + this.identity = apiMetadata.getDefaultIdentity(); + this.credential = apiMetadata.getDefaultCredential().orNull(); this.apiVersion = apiMetadata.getVersion(); this.buildVersion = apiMetadata.getBuildVersion().or(""); - if (endpoint == null) - endpoint = apiMetadata.getDefaultEndpoint().orNull(); } public ContextBuilder(ApiMetadata apiMetadata) { this(null, apiMetadata); } - public ContextBuilder credentials(String identity, String credential) { - this.identity = identity; + public ContextBuilder credentials(String identity, @Nullable String credential) { + this.identity = Optional.of(checkNotNull(identity, "identity")); this.credential = credential; return this; } public ContextBuilder endpoint(String endpoint) { - this.endpoint = endpoint; + this.endpoint = Optional.of(checkNotNull(endpoint, "endpoint")); return this; } @@ -261,102 +218,136 @@ public final class ContextBuilder { } public ContextBuilder modules(Iterable modules) { - addAll(this.modules, modules); + addAll(this.modules, checkNotNull(modules, "modules")); return this; } public ContextBuilder overrides(Properties overrides) { - this.overrides.putAll(overrides); + this.overrides = Optional.of(checkNotNull(overrides, "overrides")); return this; } - /** - * @throws NoSuchElementException - */ - public static String searchPropertiesForProviderScopedProperty(Properties overrides, String prov, String key, - String defaultVal) { + public static String searchPropertiesForProviderScopedProperty(Properties mutable, String prov, String key) throws NoSuchElementException { try { - return Iterables.find(Lists.newArrayList(overrides.getProperty(prov + "." + key), overrides - .getProperty("jclouds." + key), defaultVal), Predicates.notNull()); - } catch (NoSuchElementException e) { - throw new NoSuchElementException("no " + key + " configured for provider: " + prov); + return find(newArrayList(mutable.getProperty(prov + "." + key), mutable.getProperty("jclouds." + key)), + notNull()); + } finally { + mutable.remove(prov + "." + key); + mutable.remove("jclouds." + key); } } public Injector buildInjector() { - checkNotNull(modules, "modules"); - checkNotNull(overrides, "overrides"); - checkNotNull(apiMetadata, "api"); - final Properties mutable = new Properties(); - mutable.putAll(apiMetadata.getDefaultProperties()); - String providerId; - if (providerMetadata != null) { - mutable.putAll(providerMetadata.getDefaultProperties()); - mutable.setProperty(PROPERTY_PROVIDER, providerId = providerMetadata.getId()); - mutable.setProperty(PROPERTY_ISO3166_CODES, Joiner.on(',').join(providerMetadata.getIso3166Codes())); - } else { - mutable.setProperty(PROPERTY_PROVIDER, providerId = apiMetadata.getId()); - } - mutable.putAll(checkNotNull(overrides, "overrides")); - mutable.putAll(propertiesPrefixedWithJcloudsApiOrProviderId(System.getProperties(), providerId)); + Properties unexpanded = currentStateToUnexpandedProperties(); - mutable.setProperty(PROPERTY_ENDPOINT, searchPropertiesForProviderScopedProperty(mutable, providerId, "endpoint", - endpoint)); - mutable.setProperty(PROPERTY_API, searchPropertiesForProviderScopedProperty(mutable, providerId, "api", - apiMetadata.getName())); - mutable.setProperty(PROPERTY_API_VERSION, searchPropertiesForProviderScopedProperty(mutable, providerId, - "api-version", apiVersion)); - mutable.setProperty(PROPERTY_BUILD_VERSION, searchPropertiesForProviderScopedProperty(mutable, providerId, - "build-version", buildVersion)); - mutable.setProperty(PROPERTY_IDENTITY, searchPropertiesForProviderScopedProperty(mutable, providerId, "identity", - identity)); + ImmutableSet keysToResolve = ImmutableSet.of(PROPERTY_ENDPOINT, PROPERTY_IDENTITY, PROPERTY_CREDENTIAL, + PROPERTY_API, PROPERTY_API_VERSION, PROPERTY_BUILD_VERSION); + + ImmutableSet optionalKeys = apiMetadata.getCredentialName().isPresent() ? ImmutableSet. of() + : ImmutableSet.of(PROPERTY_CREDENTIAL); + + Properties resolved = resolveProperties(unexpanded, providerId, keysToResolve, optionalKeys); + + Properties expanded = expandProperties(resolved); + + Credentials creds = new Credentials(getAndRemove(expanded, PROPERTY_IDENTITY), getAndRemove(expanded, + PROPERTY_CREDENTIAL)); + + ProviderMetadata providerMetadata = new UpdateProviderMetadataFromProperties(apiMetadata, this.providerMetadata).apply(expanded); + + return buildInjector(providerMetadata, creds, modules); + } + + private static String getAndRemove(Properties expanded, String key) { try { - mutable.setProperty(PROPERTY_CREDENTIAL, searchPropertiesForProviderScopedProperty(mutable, providerId, - "credential", credential)); - } catch (NoSuchElementException e) { - if (apiMetadata.getCredentialName().isPresent()) - throw e; + return expanded.getProperty(key); + } finally { + expanded.remove(key); } - if (providerMetadata == null) - providerMetadata = AnonymousProviderMetadata.forApiWithEndpoint(apiMetadata, mutable - .getProperty(PROPERTY_ENDPOINT)); + } + + private Properties currentStateToUnexpandedProperties() { + Properties defaults = new Properties(); + defaults.putAll(apiMetadata.getDefaultProperties()); + defaults.setProperty(PROPERTY_PROVIDER,providerId); + if (providerMetadata.isPresent()) { + defaults.putAll(providerMetadata.get().getDefaultProperties()); + defaults.setProperty(PROPERTY_ISO3166_CODES, Joiner.on(',').join(providerMetadata.get().getIso3166Codes())); + } + if (endpoint.isPresent()) + defaults.setProperty(PROPERTY_ENDPOINT, endpoint.get()); + defaults.setProperty(PROPERTY_API, apiMetadata.getName()); + defaults.setProperty(PROPERTY_API_VERSION, apiVersion); + defaults.setProperty(PROPERTY_BUILD_VERSION, buildVersion); + if (identity.isPresent()) + defaults.setProperty(PROPERTY_IDENTITY, identity.get()); + if (credential != null) + defaults.setProperty(PROPERTY_CREDENTIAL, credential); + if (overrides.isPresent()) + defaults.putAll(checkNotNull(overrides.get(), "overrides")); + defaults.putAll(propertiesPrefixedWithJcloudsApiOrProviderId(getSystemProperties(), apiMetadata.getId(), providerId)); + return defaults; + } - modules.add(Rocoto.expandVariables(new ConfigurationModule() { + @VisibleForTesting + protected Properties getSystemProperties() { + return System.getProperties(); + } - @Override - protected void bindConfigurations() { - bindProperties(mutable); - } - })); + private Properties expandProperties(final Properties resolved) { + return Guice.createInjector(new BindPropertiesToExpandedValues(resolved)).getInstance(Properties.class); + } - boolean restModuleSpecifiedByUser = restClientModulePresent(modules); - Iterable defaultModules = ifSpecifiedByUserDontIncludeDefaultRestModule(restModuleSpecifiedByUser); - Iterables.addAll(modules, defaultModules); - addClientModuleIfNotPresent(modules); - addRestContextBinding(); + public static Injector buildInjector(ProviderMetadata providerMetadata, Credentials creds, List inputModules) { + List modules = newArrayList(); + modules.addAll(inputModules); + boolean restModuleSpecifiedByUser = restClientModulePresent(inputModules); + Iterable defaultModules = ifSpecifiedByUserDontIncludeDefaultRestModule( + providerMetadata.getApiMetadata(), restModuleSpecifiedByUser); + addAll(modules, defaultModules); + addClientModuleIfNotPresent(providerMetadata.getApiMetadata(), modules); + addRestContextBinding(providerMetadata.getApiMetadata(), modules); addLoggingModuleIfNotPresent(modules); addHttpModuleIfNeededAndNotPresent(modules); addExecutorServiceIfNotPresent(modules); addEventBusIfNotPresent(modules); addCredentialStoreIfNotPresent(modules); modules.add(new LifeCycleModule()); - modules.add(new BindPropertiesToAnnotations()); - modules.add(new BindDefaultContextQualifiedToProvider()); + modules.add(new BindProviderMetadataContextAndCredentials(providerMetadata, creds)); Injector returnVal = Guice.createInjector(Stage.PRODUCTION, modules); returnVal.getInstance(ExecutionList.class).execute(); return returnVal; } - void addRestContextBinding() { + static Properties resolveProperties(Properties mutable, String providerId, Set keys, Set optionalKeys) throws NoSuchElementException { + for (String key : keys){ + try { + String scopedProperty = ImmutableList.copyOf(Splitter.on('.').split(key)).get(1); + mutable.setProperty(key, searchPropertiesForProviderScopedProperty(mutable, providerId,scopedProperty)); + } catch (NoSuchElementException e){ + if (!optionalKeys.contains(key)) + throw e; + } + } + return mutable; + } + + static void addRestContextBinding(ApiMetadata apiMetadata, List modules) { if (apiMetadata instanceof RestApiMetadata) { - modules.add(new ResolveRestContextModule(RestApiMetadata.class.cast(apiMetadata))); + try { + modules.add(new BindRestContextWithWildcardExtendsExplicitAndRawType(RestApiMetadata.class + .cast(apiMetadata))); + } catch (IllegalArgumentException e) { + + } } } - private Iterable ifSpecifiedByUserDontIncludeDefaultRestModule(boolean restModuleSpecifiedByUser) { - Iterable defaultModules = Iterables.transform(apiMetadata.getDefaultModules(), + static Iterable ifSpecifiedByUserDontIncludeDefaultRestModule(ApiMetadata apiMetadata, + boolean restModuleSpecifiedByUser) { + Iterable defaultModules = transform(apiMetadata.getDefaultModules(), new Function, Module>() { @Override @@ -364,37 +355,38 @@ public final class ContextBuilder { try { return arg0.newInstance(); } catch (InstantiationException e) { - throw Throwables.propagate(e); + throw propagate(e); } catch (IllegalAccessException e) { - throw Throwables.propagate(e); + throw propagate(e); } } }); if (restModuleSpecifiedByUser) - defaultModules = Iterables.filter(defaultModules, Predicates.not(configuresRest)); + defaultModules = filter(defaultModules, not(configuresRest)); return defaultModules; } @SuppressWarnings( { "unchecked" }) - Map propertiesPrefixedWithJcloudsApiOrProviderId(Properties properties, String providerId) { - return Maps.filterKeys((Map) System.getProperties(), Predicates.containsPattern("^(jclouds|" + providerId + "|" - + apiMetadata.getId() + ").*")); + static Map propertiesPrefixedWithJcloudsApiOrProviderId(Properties properties, String apiId, + String providerId) { + return Maps.filterKeys((Map) properties, containsPattern("^(jclouds|" + providerId + "|" + apiId + + ").*")); } @VisibleForTesting - protected void addLoggingModuleIfNotPresent(List modules) { + static void addLoggingModuleIfNotPresent(List modules) { if (!any(modules, instanceOf(LoggingModule.class))) modules.add(new JDKLoggingModule()); } @VisibleForTesting - void addHttpModuleIfNeededAndNotPresent(List modules) { + static void addHttpModuleIfNeededAndNotPresent(List modules) { if (nothingConfiguresAnHttpService(modules)) modules.add(new JavaUrlHttpCommandExecutorServiceModule()); } - private boolean nothingConfiguresAnHttpService(List modules) { + static boolean nothingConfiguresAnHttpService(List modules) { return (!any(modules, new Predicate() { public boolean apply(Module input) { return input.getClass().isAnnotationPresent(ConfiguresHttpCommandExecutorService.class); @@ -404,25 +396,25 @@ public final class ContextBuilder { } @VisibleForTesting - protected void addClientModuleIfNotPresent(List modules) { + static void addClientModuleIfNotPresent(ApiMetadata apiMetadata, List modules) { if (!restClientModulePresent(modules)) { - addClientModule(modules); + addClientModule(apiMetadata, modules); } } - Predicate configuresRest = new Predicate() { + static Predicate configuresRest = new Predicate() { public boolean apply(Module input) { return input.getClass().isAnnotationPresent(ConfiguresRestClient.class); } }; - private boolean restClientModulePresent(List modules) { + static boolean restClientModulePresent(List modules) { return any(modules, configuresRest); } @SuppressWarnings("unchecked") - protected void addClientModule(List modules) { + static void addClientModule(ApiMetadata apiMetadata, List modules) { // TODO: move this up if (apiMetadata instanceof RestApiMetadata) { RestApiMetadata rest = RestApiMetadata.class.cast(apiMetadata); @@ -431,9 +423,9 @@ public final class ContextBuilder { modules.add(new RestModule()); } } - + @VisibleForTesting - protected void addEventBusIfNotPresent(List modules) { + static void addEventBusIfNotPresent(List modules) { if (!any(modules, new Predicate() { public boolean apply(Module input) { return input.getClass().isAnnotationPresent(ConfiguresEventBus.class); @@ -446,7 +438,7 @@ public final class ContextBuilder { } @VisibleForTesting - protected void addExecutorServiceIfNotPresent(List modules) { + static void addExecutorServiceIfNotPresent(List modules) { if (!any(modules, new Predicate() { public boolean apply(Module input) { return input.getClass().isAnnotationPresent(ConfiguresExecutorService.class); @@ -468,7 +460,7 @@ public final class ContextBuilder { } @VisibleForTesting - protected void addCredentialStoreIfNotPresent(List modules) { + static void addCredentialStoreIfNotPresent(List modules) { if (!any(modules, new Predicate() { public boolean apply(Module input) { return input.getClass().isAnnotationPresent(ConfiguresCredentialStore.class); @@ -489,40 +481,55 @@ public final class ContextBuilder { * @see #build(TypeToken) */ @SuppressWarnings("unchecked") - public C build() { + public C build() { return (C) build(apiMetadata.getContext()); } /** - * @see #build(TypeToken) + * @see #buildView(Class) */ - public C build(Class contextType) { - return build(TypeToken.of(checkNotNull(contextType, "contextType"))); + public V build(Class viewType) { + return buildView(checkNotNull(viewType, "viewType")); } /** - * this will build any context supported by the ApiMetadata. This includes the base - * {@link ApiMetadata#getContext() context}, or any {@link ApiMetadata#getWrappers() wrapper} it - * supports. + * @see #buildView(TypeToken) + */ + public V buildView(Class viewType) { + return buildView(TypeToken.of(checkNotNull(viewType, "viewType"))); + } + + /** + * this will build any {@link ApiMetadata#getViews() view} supported by the ApiMetadata. * * ex. {@code builder.build(BlobStoreContext.class) } will work, if {@code TypeToken} - * is a configured {@link ApiMetadata#getWrappers() wrapper} of this api. - * + * is a configured {@link ApiMetadata#getViews() view} of this api. * */ @SuppressWarnings("unchecked") - public C build(final TypeToken contextType) { + public V buildView(TypeToken viewType) { + TypeToken returnType; + try { + returnType = (TypeToken) Apis.findView(apiMetadata, checkNotNull(viewType, "viewType")); + } catch (NoSuchElementException e) { + throw new IllegalArgumentException(String.format( + "api %s not wrappable as %s; context: %s, views: %s", apiMetadata, + viewType, apiMetadata.getContext(), apiMetadata.getViews())); + } + return (V) buildInjector().getInstance(Key.get(TypeLiteral.get(returnType.getType()))); + } + + /** + * this will build the {@link ApiMetadata#getContext() context} supported by the current ApiMetadata. + */ + @SuppressWarnings("unchecked") + public C build(TypeToken contextType) { TypeToken returnType = null; if (contextType.isAssignableFrom(apiMetadata.getContext())) returnType = (TypeToken) apiMetadata.getContext(); else - try { - returnType = (TypeToken) Apis.findWrapper(apiMetadata, contextType); - } catch (NoSuchElementException e) { - throw new IllegalArgumentException(String.format( - "api %s not assignable from or transformable to %s; context: %s, wrappers: %s", apiMetadata, - contextType, apiMetadata.getContext(), apiMetadata.getWrappers())); - } + throw new IllegalArgumentException(String.format("api %s not assignable from %s; context: %s", apiMetadata, + contextType, apiMetadata.getContext())); return (C) buildInjector().getInstance(Key.get(TypeLiteral.get(returnType.getType()))); } diff --git a/core/src/main/java/org/jclouds/Wrapper.java b/core/src/main/java/org/jclouds/View.java similarity index 58% rename from core/src/main/java/org/jclouds/Wrapper.java rename to core/src/main/java/org/jclouds/View.java index d80839f894..e61a51a599 100644 --- a/core/src/main/java/org/jclouds/Wrapper.java +++ b/core/src/main/java/org/jclouds/View.java @@ -18,54 +18,59 @@ */ package org.jclouds; -import java.io.Closeable; - import com.google.common.annotations.Beta; import com.google.common.reflect.TypeToken; /** - * + * {@link View} allows access to the provider-specific, or library-driven api + * behind an abstraction. One backend context can support multiple views. + *

+ * For example, the {@code CloudStackContext} can be backend by both + * {@code ComputeServiceContext} and {@code LoadBalancerServiceContext}, as the + * api covers these features. * * @author Adrian Cole * */ @Beta -public interface Wrapper { +public interface View { /** * * @return type of the context powering the current one. */ - TypeToken getWrappedType(); + TypeToken getBackendType(); /** - * Return an object of the specified type to allow access to the wrapped context. If the wrapped - * context is not assignable from the supplied type, an {@link IllegalArgumentException} is - * thrown. + * Return an object of the specified type to allow access to the backend + * context. If the backend context is not assignable from the supplied type, + * an {@link IllegalArgumentException} is thrown. * * @param type - * the type of the context to be returned. The wrapped context must be assignable from - * this type. + * the type of the context to be returned. The backend context must + * be assignable from this type. * @return an instance of the specified type * @throws IllegalArgumentException - * if the wrapped context is not assignable from the specified class. - * @see #getWrappedType() + * if the backend context is not assignable from the specified + * class. + * @see #getBackendType() */ - C unwrap(TypeToken type) throws IllegalArgumentException; - + C unwrap(TypeToken type) throws IllegalArgumentException; + /** * shortcut for {@code unwrap(TypeToken.of(clazz))} + * * @see #unwrap(TypeToken) */ - C unwrap(Class clazz) throws IllegalArgumentException; - + C unwrap(Class clazz) throws IllegalArgumentException; + /** * shortcut for {@code unwrap(getWrappedType())} * * @throws ClassCastException * if the user supplied {@code C} param is not assignableFrom - * {@link #getWrappedType()} + * {@link #getBackendType()} */ - C unwrap() throws ClassCastException; + C unwrap() throws ClassCastException; } \ No newline at end of file diff --git a/core/src/main/java/org/jclouds/apis/ApiMetadata.java b/core/src/main/java/org/jclouds/apis/ApiMetadata.java index 736a0fcdfc..4798c0dcc5 100644 --- a/core/src/main/java/org/jclouds/apis/ApiMetadata.java +++ b/core/src/main/java/org/jclouds/apis/ApiMetadata.java @@ -18,13 +18,13 @@ */ package org.jclouds.apis; -import java.io.Closeable; import java.io.Serializable; import java.net.URI; import java.util.Properties; import java.util.Set; -import org.jclouds.Wrapper; +import org.jclouds.Context; +import org.jclouds.View; import org.jclouds.javax.annotation.Nullable; import com.google.common.annotations.Beta; @@ -56,22 +56,22 @@ public interface ApiMetadata extends Serializable { /** * @see ApiMetadata#getContext() */ - Builder context(TypeToken context); + Builder context(TypeToken context); /** - * @see ApiMetadata#getWrappers() + * @see ApiMetadata#getViews() */ - Builder wrapper(Class wrapper); + Builder view(Class view); /** - * @see ApiMetadata#getWrappers() + * @see ApiMetadata#getViews() */ - Builder wrapper(TypeToken wrapper); + Builder view(TypeToken view); /** - * @see ApiMetadata#getWrappers() + * @see ApiMetadata#getViews() */ - Builder wrappers(Set> wrappers); + Builder views(Set> views); /** * @see ApiMetadata#getEndpointName() @@ -262,11 +262,11 @@ public interface ApiMetadata extends Serializable { /** * @return the primary context of this api, for example {@code RestContext} */ - TypeToken getContext(); + TypeToken getContext(); /** * @return types of contexts this can be transformed into, for example {@code BlobStoreContext} */ - Set> getWrappers(); + Set> getViews(); } \ No newline at end of file diff --git a/core/src/main/java/org/jclouds/apis/ApiPredicates.java b/core/src/main/java/org/jclouds/apis/ApiPredicates.java index 2e9327ec5f..45fbc620a8 100644 --- a/core/src/main/java/org/jclouds/apis/ApiPredicates.java +++ b/core/src/main/java/org/jclouds/apis/ApiPredicates.java @@ -20,7 +20,7 @@ package org.jclouds.apis; import static com.google.common.base.Preconditions.checkNotNull; -import org.jclouds.Wrapper; +import org.jclouds.View; import org.jclouds.rest.RestApiMetadata; import org.jclouds.util.Preconditions2; @@ -139,7 +139,7 @@ public class ApiPredicates { * * @return the apis with contexts transformable to the given type */ - public static Predicate contextWrappableAs(final TypeToken type) { + public static Predicate viewableAs(final TypeToken type) { checkNotNull(type, "context must be defined"); return new Predicate() { /** @@ -147,7 +147,7 @@ public class ApiPredicates { */ @Override public boolean apply(ApiMetadata apiMetadata) { - for (TypeToken to : apiMetadata.getWrappers()) + for (TypeToken to : apiMetadata.getViews()) if (type.isAssignableFrom(to)) return true; return false; @@ -158,7 +158,7 @@ public class ApiPredicates { */ @Override public String toString() { - return "contextWrappableAs(" + type + ")"; + return "viewableAs(" + type + ")"; } }; } diff --git a/core/src/main/java/org/jclouds/apis/Apis.java b/core/src/main/java/org/jclouds/apis/Apis.java index 35e36af2d9..fbb4c14282 100644 --- a/core/src/main/java/org/jclouds/apis/Apis.java +++ b/core/src/main/java/org/jclouds/apis/Apis.java @@ -25,7 +25,7 @@ import static com.google.common.collect.Iterables.find; import java.util.NoSuchElementException; import java.util.ServiceLoader; -import org.jclouds.Wrapper; +import org.jclouds.View; import com.google.common.base.Function; import com.google.common.base.Predicate; @@ -107,12 +107,12 @@ public class Apis { * * @return the apis with contexts assignable from given type */ - public static Iterable contextWrappableAs(TypeToken type) { - return filter(all(), ApiPredicates.contextWrappableAs(type)); + public static Iterable viewableAs(TypeToken type) { + return filter(all(), ApiPredicates.viewableAs(type)); } - public static Iterable contextWrappableAs(Class type) { - return filter(all(), ApiPredicates.contextWrappableAs(TypeToken.of(type))); + public static Iterable viewableAs(Class type) { + return filter(all(), ApiPredicates.viewableAs(TypeToken.of(type))); } /** @@ -123,15 +123,15 @@ public class Apis { * * @return the apis with contexts transformable to the given type */ - public static TypeToken findWrapper(final ApiMetadata apiMetadata, final TypeToken wrapper) + public static TypeToken findView(final ApiMetadata apiMetadata, final TypeToken view) throws NoSuchElementException { checkNotNull(apiMetadata, "apiMetadata must be defined"); - checkNotNull(wrapper, "context must be defined"); - return Iterables.find(apiMetadata.getWrappers(), new Predicate>() { + checkNotNull(view, "context must be defined"); + return Iterables.find(apiMetadata.getViews(), new Predicate>() { @Override public boolean apply(TypeToken input) { - return wrapper.isAssignableFrom(input); + return view.isAssignableFrom(input); } }); diff --git a/core/src/main/java/org/jclouds/apis/internal/BaseApiMetadata.java b/core/src/main/java/org/jclouds/apis/internal/BaseApiMetadata.java index 861948c39e..0864370f23 100644 --- a/core/src/main/java/org/jclouds/apis/internal/BaseApiMetadata.java +++ b/core/src/main/java/org/jclouds/apis/internal/BaseApiMetadata.java @@ -28,19 +28,18 @@ import static org.jclouds.Constants.PROPERTY_MAX_CONNECTIONS_PER_HOST; import static org.jclouds.Constants.PROPERTY_MAX_CONNECTION_REUSE; import static org.jclouds.Constants.PROPERTY_MAX_SESSION_FAILURES; import static org.jclouds.Constants.PROPERTY_PRETTY_PRINT_PAYLOADS; +import static org.jclouds.Constants.PROPERTY_SCHEDULER_THREADS; import static org.jclouds.Constants.PROPERTY_SESSION_INTERVAL; import static org.jclouds.Constants.PROPERTY_SO_TIMEOUT; import static org.jclouds.Constants.PROPERTY_USER_THREADS; -import static org.jclouds.Constants.PROPERTY_SCHEDULER_THREADS; -import java.io.Closeable; import java.net.URI; import java.util.Properties; import java.util.Set; -import org.jclouds.Wrapper; +import org.jclouds.Context; +import org.jclouds.View; import org.jclouds.apis.ApiMetadata; -import org.jclouds.lifecycle.Closer; import com.google.common.base.Objects; import com.google.common.base.Optional; @@ -83,7 +82,7 @@ public abstract class BaseApiMetadata implements ApiMetadata { public static class Builder implements ApiMetadata.Builder { protected String id; protected String name; - protected Set> wrappers = ImmutableSet.of(); + protected Set> views = ImmutableSet.of(); protected String endpointName = "https endpoint"; protected String identityName; protected Optional credentialName = Optional.absent(); @@ -95,7 +94,7 @@ public abstract class BaseApiMetadata implements ApiMetadata { protected Properties defaultProperties = BaseApiMetadata.defaultProperties(); protected URI documentation; // - protected TypeToken context = TypeToken.of(Closer.class); + protected TypeToken context = TypeToken.of(Context.class); protected Set> defaultModules = ImmutableSet.of(); /** @@ -120,24 +119,24 @@ public abstract class BaseApiMetadata implements ApiMetadata { * {@inheritDoc} */ @Override - public Builder wrapper(Class wrapper) { - return wrapper(TypeToken.of(checkNotNull(wrapper, "wrapper"))); + public Builder view(Class view) { + return view(TypeToken.of(checkNotNull(view, "view"))); } /** * {@inheritDoc} */ @Override - public Builder wrapper(TypeToken wrapper) { - return wrappers(ImmutableSet.>of(checkNotNull(wrapper, "wrapper"))); + public Builder view(TypeToken view) { + return views(ImmutableSet.>of(checkNotNull(view, "view"))); } /** * {@inheritDoc} */ @Override - public Builder wrappers(Set> wrappers) { - this.wrappers = ImmutableSet.copyOf(checkNotNull(wrappers, "wrappers")); + public Builder views(Set> views) { + this.views = ImmutableSet.copyOf(checkNotNull(views, "views")); return this; } @@ -235,7 +234,7 @@ public abstract class BaseApiMetadata implements ApiMetadata { * {@inheritDoc} */ @Override - public Builder context(TypeToken context) { + public Builder context(TypeToken context) { this.context = checkNotNull(context, "context"); return this; } @@ -258,7 +257,7 @@ public abstract class BaseApiMetadata implements ApiMetadata { } public Builder fromApiMetadata(ApiMetadata in) { - return id(in.getId()).wrappers(in.getWrappers()).name(in.getName()).endpointName(in.getEndpointName()).identityName( + return id(in.getId()).views(in.getViews()).name(in.getName()).endpointName(in.getEndpointName()).identityName( in.getIdentityName()).credentialName(in.getCredentialName().orNull()).version(in.getVersion()) .buildVersion(in.getBuildVersion().orNull()).defaultEndpoint(in.getDefaultEndpoint().orNull()) .defaultIdentity(in.getDefaultIdentity().orNull()).defaultCredential( @@ -278,7 +277,7 @@ public abstract class BaseApiMetadata implements ApiMetadata { protected final String id; protected final String name; - protected final Set> wrappers; + protected final Set> views; protected final String endpointName; protected final String identityName; protected final Optional credentialName; @@ -289,24 +288,24 @@ public abstract class BaseApiMetadata implements ApiMetadata { protected final Optional defaultCredential; protected final Properties defaultProperties; protected final URI documentation; - protected final TypeToken context; + protected final TypeToken context; protected final Set> defaultModules; protected BaseApiMetadata(Builder builder) { - this(builder.id, builder.name, builder.wrappers, builder.endpointName, builder.identityName, builder.credentialName, + this(builder.id, builder.name, builder.views, builder.endpointName, builder.identityName, builder.credentialName, builder.version, builder.buildVersion, builder.defaultEndpoint, builder.defaultIdentity, builder.defaultCredential, builder.defaultProperties, builder.documentation, builder.context, builder.defaultModules); } - public BaseApiMetadata(String id, String name, Set> wrappers, String endpointName, String identityName, + public BaseApiMetadata(String id, String name, Set> views, String endpointName, String identityName, Optional credentialName, String version, Optional buildVersion, Optional defaultEndpoint, Optional defaultIdentity, Optional defaultCredential, - Properties defaultProperties, URI documentation, TypeToken context, + Properties defaultProperties, URI documentation, TypeToken context, Set> defaultModules) { this.id = checkNotNull(id, "id"); this.name = checkNotNull(name, "name"); - this.wrappers = ImmutableSet.copyOf(checkNotNull(wrappers, "wrappers")); + this.views = ImmutableSet.copyOf(checkNotNull(views, "views")); this.endpointName = checkNotNull(endpointName, "endpointName"); this.identityName = checkNotNull(identityName, "identityName"); this.credentialName = checkNotNull(credentialName, "credentialName"); @@ -331,12 +330,12 @@ public abstract class BaseApiMetadata implements ApiMetadata { return false; ApiMetadata that = ApiMetadata.class.cast(o); return equal(this.getId(), that.getId()) && equal(this.getName(), that.getName()) - && equal(this.getWrappers(), that.getWrappers()); + && equal(this.getViews(), that.getViews()); } @Override public int hashCode() { - return Objects.hashCode(getId(), getName(), getWrappers()); + return Objects.hashCode(getId(), getName(), getViews()); } @Override @@ -345,7 +344,7 @@ public abstract class BaseApiMetadata implements ApiMetadata { } protected ToStringHelper string() { - return Objects.toStringHelper("").add("id", getId()).add("name", getName()).add("wrappers", getWrappers()).add( + return Objects.toStringHelper("").add("id", getId()).add("name", getName()).add("views", getViews()).add( "endpointName", getEndpointName()).add("identityName", getIdentityName()).add("credentialName", getCredentialName()).add("documentation", getDocumentation()); } @@ -370,8 +369,8 @@ public abstract class BaseApiMetadata implements ApiMetadata { * {@inheritDoc} */ @Override - public Set> getWrappers() { - return wrappers; + public Set> getViews() { + return views; } /** @@ -458,7 +457,7 @@ public abstract class BaseApiMetadata implements ApiMetadata { * {@inheritDoc} */ @Override - public TypeToken getContext() { + public TypeToken getContext() { return context; } diff --git a/core/src/main/java/org/jclouds/config/BindPropertiesToExpandedValues.java b/core/src/main/java/org/jclouds/config/BindPropertiesToExpandedValues.java new file mode 100644 index 0000000000..aadab59c40 --- /dev/null +++ b/core/src/main/java/org/jclouds/config/BindPropertiesToExpandedValues.java @@ -0,0 +1,67 @@ +/** + * 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.config; + +import static com.google.common.base.Preconditions.checkNotNull; + +import java.util.Properties; + +import javax.inject.Singleton; + +import org.jclouds.internal.FilterStringsBoundToInjectorByName; +import org.nnsoft.guice.rocoto.Rocoto; +import org.nnsoft.guice.rocoto.configuration.ConfigurationModule; + +import com.google.common.base.Predicates; +import com.google.inject.AbstractModule; +import com.google.inject.Provides; + +/** + * expands properties. + * + * @author Adrian Cole + */ +public class BindPropertiesToExpandedValues extends AbstractModule { + private final Properties resolved; + + public BindPropertiesToExpandedValues(Properties resolved) { + this.resolved = checkNotNull(resolved, "resolved"); + } + + @Override + protected void configure() { + install(Rocoto.expandVariables(new ConfigurationModule() { + + @Override + protected void bindConfigurations() { + bindProperties(resolved); + } + + @SuppressWarnings("unused") + @Provides + @Singleton + protected Properties expanded(FilterStringsBoundToInjectorByName filterStringsBoundByName) { + Properties props = new Properties(); + props.putAll(filterStringsBoundByName.apply(Predicates. alwaysTrue())); + return props; + } + })); + } + +} \ No newline at end of file diff --git a/core/src/main/java/org/jclouds/config/BindRestContextWithWildcardExtendsExplicitAndRawType.java b/core/src/main/java/org/jclouds/config/BindRestContextWithWildcardExtendsExplicitAndRawType.java new file mode 100644 index 0000000000..6f7cd9eadd --- /dev/null +++ b/core/src/main/java/org/jclouds/config/BindRestContextWithWildcardExtendsExplicitAndRawType.java @@ -0,0 +1,69 @@ +/** + * 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.config; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; + +import org.jclouds.rest.RestApiMetadata; +import org.jclouds.rest.RestContext; +import org.jclouds.rest.internal.BaseRestApiMetadata; +import org.jclouds.rest.internal.RestContextImpl; + +import com.google.common.reflect.TypeToken; +import com.google.inject.AbstractModule; +import com.google.inject.TypeLiteral; +import com.google.inject.util.Types; + +/** + * Allows you to lookup the {@link RestApiMetadata#getContext()} as {@link RestContext}, {@code RestContext}, and {@code + * + * @author Adrian Cole + */ +public class BindRestContextWithWildcardExtendsExplicitAndRawType extends AbstractModule { + private final RestApiMetadata restApiMetadata; + + public BindRestContextWithWildcardExtendsExplicitAndRawType(RestApiMetadata restApiMetadata) + throws IllegalArgumentException { + this.restApiMetadata = checkNotNull(restApiMetadata, "restApiMetadata"); + checkArgument(restApiMetadata.getContext().getRawType().equals(RestContext.class), + "this does not work as %s raw type is not RestContext", restApiMetadata.getContext()); + } + + @SuppressWarnings("unchecked") + @Override + protected void configure() { + TypeToken concreteType = BaseRestApiMetadata.contextToken(TypeToken.of(restApiMetadata.getApi()), TypeToken + .of(restApiMetadata.getAsyncApi())); + // bind explicit type + bind(TypeLiteral.get(concreteType.getType())).to( + (TypeLiteral) TypeLiteral.get(Types.newParameterizedType(RestContextImpl.class, + restApiMetadata.getApi(), restApiMetadata.getAsyncApi()))); + // bind potentially wildcard type + if (!concreteType.equals(restApiMetadata.getContext())) { + bind(TypeLiteral.get(restApiMetadata.getContext().getType())).to( + (TypeLiteral) TypeLiteral.get(Types.newParameterizedType(RestContextImpl.class, restApiMetadata + .getApi(), restApiMetadata.getAsyncApi()))); + } + // bind w/o types + bind(TypeLiteral.get(RestContext.class)).to( + (TypeLiteral) TypeLiteral.get(Types.newParameterizedType(RestContextImpl.class, + restApiMetadata.getApi(), restApiMetadata.getAsyncApi()))); + } +} \ No newline at end of file diff --git a/core/src/main/java/org/jclouds/config/ValueOfConfigurationKeyOrNull.java b/core/src/main/java/org/jclouds/config/ValueOfConfigurationKeyOrNull.java index ab50c64deb..1f6335f272 100644 --- a/core/src/main/java/org/jclouds/config/ValueOfConfigurationKeyOrNull.java +++ b/core/src/main/java/org/jclouds/config/ValueOfConfigurationKeyOrNull.java @@ -19,7 +19,6 @@ package org.jclouds.config; import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.base.Strings.emptyToNull; import static com.google.inject.name.Names.named; import javax.inject.Inject; @@ -47,7 +46,7 @@ public class ValueOfConfigurationKeyOrNull implements Function { public String apply(String configurationKey) { checkNotNull(configurationKey, "configurationKey"); try { - return emptyToNull(injector.getInstance(Key.get(String.class, named(configurationKey)))); + return injector.getInstance(Key.get(String.class, named(configurationKey))); } catch (ConfigurationException e) { return null; } diff --git a/core/src/main/java/org/jclouds/date/internal/SimpleDateFormatDateService.java b/core/src/main/java/org/jclouds/date/internal/SimpleDateFormatDateService.java index 78b54a24d6..b6a0108dc8 100644 --- a/core/src/main/java/org/jclouds/date/internal/SimpleDateFormatDateService.java +++ b/core/src/main/java/org/jclouds/date/internal/SimpleDateFormatDateService.java @@ -157,6 +157,8 @@ public class SimpleDateFormatDateService implements DateService { toParse = trimToMillis(toParse); toParse = trimTZ(toParse); toParse += tz; + if (toParse.charAt(10) == ' ') + toParse = new StringBuilder(toParse).replace(10, 11, "T").toString(); synchronized (iso8601SecondsSimpleDateFormat) { try { return iso8601SecondsSimpleDateFormat.parse(toParse); diff --git a/core/src/main/java/org/jclouds/http/filters/BasicAuthentication.java b/core/src/main/java/org/jclouds/http/filters/BasicAuthentication.java index ce411075eb..d87ab918f1 100644 --- a/core/src/main/java/org/jclouds/http/filters/BasicAuthentication.java +++ b/core/src/main/java/org/jclouds/http/filters/BasicAuthentication.java @@ -19,13 +19,8 @@ package org.jclouds.http.filters; import static com.google.common.base.Preconditions.checkNotNull; -import static org.jclouds.Constants.PROPERTY_CREDENTIAL; -import static org.jclouds.Constants.PROPERTY_IDENTITY; - -import java.io.UnsupportedEncodingException; import javax.inject.Inject; -import javax.inject.Named; import javax.inject.Singleton; import javax.ws.rs.core.HttpHeaders; @@ -35,6 +30,8 @@ import org.jclouds.http.HttpException; import org.jclouds.http.HttpRequest; import org.jclouds.http.HttpRequestFilter; import org.jclouds.http.utils.ModifyRequest; +import org.jclouds.rest.annotations.Credential; +import org.jclouds.rest.annotations.Identity; /** * Uses Basic Authentication to sign the request. @@ -49,11 +46,10 @@ public class BasicAuthentication implements HttpRequestFilter { private final String header; @Inject - public BasicAuthentication(@Named(PROPERTY_IDENTITY) String user, @Named(PROPERTY_CREDENTIAL) String password, - Crypto crypto) throws UnsupportedEncodingException { + public BasicAuthentication(@Identity String user, @Credential String password, Crypto crypto) { this.header = "Basic " - + CryptoStreams.base64(String.format("%s:%s", checkNotNull(user, "user"), - checkNotNull(password, "password")).getBytes("UTF-8")); + + CryptoStreams.base64(String.format("%s:%s", checkNotNull(user, "user"), + checkNotNull(password, "password")).getBytes()); } @Override diff --git a/core/src/main/java/org/jclouds/internal/BaseWrapper.java b/core/src/main/java/org/jclouds/internal/BaseView.java similarity index 59% rename from core/src/main/java/org/jclouds/internal/BaseWrapper.java rename to core/src/main/java/org/jclouds/internal/BaseView.java index d93ac915a7..b58ebd32a4 100644 --- a/core/src/main/java/org/jclouds/internal/BaseWrapper.java +++ b/core/src/main/java/org/jclouds/internal/BaseView.java @@ -21,57 +21,57 @@ import static com.google.common.base.Objects.equal; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; -import java.io.Closeable; - import javax.inject.Singleton; -import org.jclouds.Wrapper; +import org.jclouds.Context; +import org.jclouds.View; import org.jclouds.location.Provider; import com.google.common.base.Objects; import com.google.common.base.Objects.ToStringHelper; +import com.google.common.collect.ForwardingObject; import com.google.common.reflect.TypeToken; /** * @author Adrian Cole */ @Singleton -public abstract class BaseWrapper implements Wrapper { +public abstract class BaseView extends ForwardingObject implements View { - private final Closeable wrapped; - private final TypeToken wrappedType; + private final Context backend; + private final TypeToken backendType; - - protected BaseWrapper(@Provider Closeable wrapped, @Provider TypeToken wrappedType) { - this.wrapped = checkNotNull(wrapped, "wrapped"); - this.wrappedType = checkNotNull(wrappedType, "wrappedType"); + protected BaseView(@Provider Context backend, @Provider TypeToken backendType) { + this.backend = checkNotNull(backend, "backend"); + this.backendType = checkNotNull(backendType, "backendType"); } - + @SuppressWarnings("unchecked") @Override - public C unwrap(TypeToken type) { - checkArgument(checkNotNull(type, "type").isAssignableFrom(wrappedType), "wrapped type: %s not assignable from %s", wrappedType, type); - return (C) wrapped; + public C unwrap(TypeToken type) { + checkArgument(checkNotNull(type, "type").isAssignableFrom(backendType), "backend type: %s not assignable from %s", backendType, type); + return (C) backend; } @Override - public C unwrap(Class clazz) { + public C unwrap(Class clazz) { return unwrap (TypeToken.of(checkNotNull(clazz, "clazz"))); } @Override - public TypeToken getWrappedType() { - return wrappedType; + public TypeToken getBackendType() { + return backendType; } @SuppressWarnings("unchecked") @Override - public C unwrap() throws ClassCastException { - return (C) unwrap(getWrappedType()); + public C unwrap() throws ClassCastException { + return (C) unwrap(getBackendType()); } - public Closeable getWrapped() { - return wrapped; + @Override + protected Context delegate() { + return backend; } @Override @@ -80,13 +80,13 @@ public abstract class BaseWrapper implements Wrapper { return true; if (o == null || getClass() != o.getClass()) return false; - BaseWrapper that = BaseWrapper.class.cast(o); - return equal(this.getWrapped(), that.getWrapped()) && equal(this.getWrappedType(), that.getWrappedType()); + BaseView that = BaseView.class.cast(o); + return equal(this.delegate(), that.delegate()) && equal(this.getBackendType(), that.getBackendType()); } @Override public int hashCode() { - return Objects.hashCode(getWrapped(), getWrappedType()); + return Objects.hashCode(delegate(), getBackendType()); } @Override @@ -95,8 +95,7 @@ public abstract class BaseWrapper implements Wrapper { } protected ToStringHelper string() { - return Objects.toStringHelper("").add("wrapped", getWrapped()).add("wrappedType", getWrappedType()); + return Objects.toStringHelper("").add("backend", delegate()).add("backendType", getBackendType()); } - } diff --git a/core/src/main/java/org/jclouds/internal/ContextImpl.java b/core/src/main/java/org/jclouds/internal/ContextImpl.java new file mode 100644 index 0000000000..114b24917e --- /dev/null +++ b/core/src/main/java/org/jclouds/internal/ContextImpl.java @@ -0,0 +1,220 @@ +/** + * 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.internal; + +import static com.google.common.base.Preconditions.checkNotNull; + +import java.net.URI; +import java.util.Map; +import java.util.Set; + +import javax.inject.Inject; + +import org.jclouds.Context; +import org.jclouds.domain.Credentials; +import org.jclouds.domain.Location; +import org.jclouds.domain.LocationScope; +import org.jclouds.lifecycle.Closer; +import org.jclouds.providers.ProviderMetadata; +import org.jclouds.rest.Utils; +import org.jclouds.rest.annotations.Identity; + +import com.google.common.base.Objects; +import com.google.common.collect.ImmutableMap; +import com.google.common.io.Closeables; +import com.google.inject.Singleton; + +/** + * @author Adrian Cole + */ +@Singleton +public class ContextImpl implements Context { + + private final ProviderMetadata providerMetadata; + private final String identity; + private final Utils utils; + private final Closer closer; + + @Inject + protected ContextImpl(ProviderMetadata providerMetadata, @Identity String identity, Utils utils, Closer closer) { + this.providerMetadata = checkNotNull(providerMetadata, "providerMetadata"); + this.identity = checkNotNull(identity, "identity"); + this.utils = checkNotNull(utils, "utils"); + this.closer = checkNotNull(closer, "closer"); + } + + /** + * {@inheritDoc} + */ + @Override + public void close() { + Closeables.closeQuietly(closer); + } + + /** + * {@inheritDoc} + */ + @Override + public ProviderMetadata getProviderMetadata() { + return providerMetadata; + } + + /** + * {@inheritDoc} + */ + @Override + public String getIdentity() { + return identity; + } + + /** + * {@inheritDoc} + */ + @Override + public URI getEndpoint() { + return URI.create(providerMetadata.getEndpoint()); + } + + /** + * {@inheritDoc} + */ + @Override + public Utils getUtils() { + return utils(); + } + + @Override + public Utils utils() { + return utils; + } + + /** + * {@inheritDoc} + */ + @Override + public String getApiVersion() { + return providerMetadata.getApiMetadata().getVersion(); + } + + /** + * {@inheritDoc} + */ + @Override + public String getBuildVersion() { + return providerMetadata.getApiMetadata().getBuildVersion().orNull(); + } + + /** + * {@inheritDoc} + */ + @Override + public int hashCode() { + return Objects.hashCode(providerMetadata, identity); + } + + /** + * {@inheritDoc} + */ + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + ContextImpl that = ContextImpl.class.cast(obj); + return Objects.equal(this.providerMetadata, that.providerMetadata) && Objects.equal(this.identity, that.identity); + } + + /** + * {@inheritDoc} + */ + @Override + public String toString() { + return Objects.toStringHelper("").add("providerMetadata", providerMetadata).add("identity", identity).toString(); + } + + /** + * {@inheritDoc} + */ + @Override + public String getDescription() { + return providerMetadata.getName(); + } + + /** + * {@inheritDoc} + */ + @Override + public String getId() { + return providerMetadata.getId(); + } + + /** + * {@inheritDoc} + */ + @Override + public Set getIso3166Codes() { + return providerMetadata.getIso3166Codes(); + } + + /** + * {@inheritDoc} + */ + @Override + public Map getMetadata() { + return ImmutableMap. of("endpoint", URI.create(providerMetadata.getEndpoint()), "apiVersion", + providerMetadata.getApiMetadata().getVersion(), "buildVersion", providerMetadata.getApiMetadata() + .getBuildVersion().or(""), "identity", identity); + } + + /** + * {@inheritDoc} + */ + @Override + public Location getParent() { + return null; + } + + /** + * {@inheritDoc} + */ + @Override + public LocationScope getScope() { + return LocationScope.PROVIDER; + } + + /** + * {@inheritDoc} + */ + @Override + public Map credentialStore() { + return utils().credentialStore(); + } + + /** + * {@inheritDoc} + */ + @Override + public Map getCredentialStore() { + return utils().credentialStore(); + } + +} diff --git a/core/src/main/java/org/jclouds/location/functions/RegionToEndpoint.java b/core/src/main/java/org/jclouds/location/functions/RegionToEndpoint.java new file mode 100644 index 0000000000..f873e2e9e9 --- /dev/null +++ b/core/src/main/java/org/jclouds/location/functions/RegionToEndpoint.java @@ -0,0 +1,60 @@ +/** + * 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.location.functions; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.base.Preconditions.checkState; + +import java.net.URI; +import java.util.Map; + +import javax.inject.Inject; +import javax.inject.Singleton; + +import org.jclouds.javax.annotation.Nullable; +import org.jclouds.location.Region; + +import com.google.common.base.Function; +import com.google.common.base.Supplier; + +/** + * + * @author Adrian Cole + */ +@Singleton +public class RegionToEndpoint implements Function { + + private final Supplier>> regionToEndpointSupplier; + + @Inject + public RegionToEndpoint(@Region Supplier>> regionToEndpointSupplier) { + this.regionToEndpointSupplier = checkNotNull(regionToEndpointSupplier, "regionToEndpointSupplier"); + } + + @Override + public URI apply(@Nullable Object from) { + checkArgument(from != null && from instanceof String, "you must specify a region, as a String argument"); + Map> regionToEndpoint = regionToEndpointSupplier.get(); + checkState(regionToEndpoint.size() > 0, "no region name to endpoint mappings configured!"); + checkArgument(regionToEndpoint.containsKey(from), + "requested location %s, which is not in the configured locations: %s", from, regionToEndpoint); + return regionToEndpoint.get(from).get(); + } +} \ No newline at end of file diff --git a/core/src/main/java/org/jclouds/location/suppliers/ProviderURISupplier.java b/core/src/main/java/org/jclouds/location/suppliers/ProviderURISupplier.java index 079b586c8e..d0537691be 100644 --- a/core/src/main/java/org/jclouds/location/suppliers/ProviderURISupplier.java +++ b/core/src/main/java/org/jclouds/location/suppliers/ProviderURISupplier.java @@ -20,12 +20,12 @@ package org.jclouds.location.suppliers; import java.net.URI; -import org.jclouds.location.suppliers.fromconfig.ProviderURIFromConfiguration; +import org.jclouds.location.suppliers.fromconfig.ProviderURIFromProviderMetadata; import com.google.common.base.Supplier; import com.google.inject.ImplementedBy; -@ImplementedBy(ProviderURIFromConfiguration.class) +@ImplementedBy(ProviderURIFromProviderMetadata.class) public interface ProviderURISupplier extends Supplier { } \ No newline at end of file diff --git a/core/src/main/java/org/jclouds/location/suppliers/fromconfig/ProviderURIFromConfiguration.java b/core/src/main/java/org/jclouds/location/suppliers/fromconfig/ProviderURIFromProviderMetadata.java similarity index 74% rename from core/src/main/java/org/jclouds/location/suppliers/fromconfig/ProviderURIFromConfiguration.java rename to core/src/main/java/org/jclouds/location/suppliers/fromconfig/ProviderURIFromProviderMetadata.java index 8ac08ad01b..e1ac203739 100644 --- a/core/src/main/java/org/jclouds/location/suppliers/fromconfig/ProviderURIFromConfiguration.java +++ b/core/src/main/java/org/jclouds/location/suppliers/fromconfig/ProviderURIFromProviderMetadata.java @@ -18,22 +18,19 @@ */ package org.jclouds.location.suppliers.fromconfig; -import static com.google.common.base.Preconditions.checkNotNull; -import static org.jclouds.Constants.PROPERTY_ENDPOINT; - import javax.inject.Inject; -import javax.inject.Named; import javax.inject.Singleton; import org.jclouds.location.suppliers.ProviderURISupplier; +import org.jclouds.providers.ProviderMetadata; import org.jclouds.rest.suppliers.URIFromStringSupplier; @Singleton -public class ProviderURIFromConfiguration extends URIFromStringSupplier implements +public class ProviderURIFromProviderMetadata extends URIFromStringSupplier implements ProviderURISupplier { @Inject - protected ProviderURIFromConfiguration(@Named(PROPERTY_ENDPOINT) String endpoint) { - super(checkNotNull(endpoint, PROPERTY_ENDPOINT)); + protected ProviderURIFromProviderMetadata(ProviderMetadata in) { + super(in.getEndpoint()); } } \ No newline at end of file diff --git a/core/src/main/java/org/jclouds/providers/ProviderPredicates.java b/core/src/main/java/org/jclouds/providers/ProviderPredicates.java index a36636226d..8bb7899139 100644 --- a/core/src/main/java/org/jclouds/providers/ProviderPredicates.java +++ b/core/src/main/java/org/jclouds/providers/ProviderPredicates.java @@ -18,9 +18,8 @@ */ package org.jclouds.providers; -import java.io.Closeable; - -import org.jclouds.Wrapper; +import org.jclouds.Context; +import org.jclouds.View; import org.jclouds.apis.ApiMetadata; import org.jclouds.apis.ApiPredicates; import org.jclouds.util.Preconditions2; @@ -38,9 +37,9 @@ import com.google.common.reflect.TypeToken; public class ProviderPredicates { public static class ContextAssignableFrom implements Predicate { - private final TypeToken type; + private final TypeToken type; - public ContextAssignableFrom(TypeToken type) { + public ContextAssignableFrom(TypeToken type) { Preconditions.checkNotNull(type, "context must be defined"); this.type = type; } @@ -63,9 +62,9 @@ public class ProviderPredicates { } public static class TransformableTo implements Predicate { - private final TypeToken type; + private final TypeToken type; - public TransformableTo(TypeToken type) { + public TransformableTo(TypeToken type) { Preconditions.checkNotNull(type, "context must be defined"); this.type = type; } @@ -75,7 +74,7 @@ public class ProviderPredicates { */ @Override public boolean apply(ProviderMetadata providerMetadata) { - return ApiPredicates.contextWrappableAs(type).apply(providerMetadata.getApiMetadata()); + return ApiPredicates.viewableAs(type).apply(providerMetadata.getApiMetadata()); } /** @@ -83,7 +82,7 @@ public class ProviderPredicates { */ @Override public String toString() { - return "contextWrappableAs(" + type + ")"; + return "viewableAs(" + type + ")"; } } @@ -261,7 +260,7 @@ public class ProviderPredicates { * * @return the providers with an context assignable from the given type. */ - public static Predicate contextAssignableFrom(final TypeToken type) { + public static Predicate contextAssignableFrom(final TypeToken type) { return new ContextAssignableFrom(type); } @@ -273,7 +272,7 @@ public class ProviderPredicates { * * @return the providers with an context transformable to from the given type. */ - public static Predicate contextWrappableAs(final TypeToken type) { + public static Predicate viewableAs(final TypeToken type) { return new TransformableTo(type); } diff --git a/core/src/main/java/org/jclouds/providers/Providers.java b/core/src/main/java/org/jclouds/providers/Providers.java index b866e699ba..da69a11e63 100644 --- a/core/src/main/java/org/jclouds/providers/Providers.java +++ b/core/src/main/java/org/jclouds/providers/Providers.java @@ -21,11 +21,11 @@ package org.jclouds.providers; import static com.google.common.collect.Iterables.filter; import static com.google.common.collect.Iterables.find; -import java.io.Closeable; import java.util.NoSuchElementException; import java.util.ServiceLoader; -import org.jclouds.Wrapper; +import org.jclouds.Context; +import org.jclouds.View; import org.jclouds.apis.ApiMetadata; import com.google.common.base.Function; @@ -101,19 +101,19 @@ public class Providers { } /** - * Returns the providers that are of the provided contextWrappableAs. + * Returns the providers that are of the provided viewableAs. * - * @param contextWrappableAs - * the contextWrappableAs to providers to return + * @param viewableAs + * the viewableAs to providers to return * - * @return the providers of the provided contextWrappableAs + * @return the providers of the provided viewableAs */ - public static Iterable contextWrappableAs(TypeToken contextWrappableAs) { - return filter(all(), ProviderPredicates.contextWrappableAs(contextWrappableAs)); + public static Iterable viewableAs(TypeToken viewableAs) { + return filter(all(), ProviderPredicates.viewableAs(viewableAs)); } - public static Iterable contextWrappableAs(Class contextWrappableAs) { - return filter(all(), ProviderPredicates.contextWrappableAs(TypeToken.of(contextWrappableAs))); + public static Iterable viewableAs(Class viewableAs) { + return filter(all(), ProviderPredicates.viewableAs(TypeToken.of(viewableAs))); } /** @@ -137,15 +137,15 @@ public class Providers { * * @return the providers of the provided context */ - public static Iterable contextAssignableFrom( - TypeToken context) { + public static Iterable contextAssignableFrom( + TypeToken context) { Preconditions.checkNotNull(context, "context must be defined"); return filter(all(), new ProviderPredicates.ContextAssignableFrom(context)); } /** * Returns the providers that are bound to the same location as the given ISO 3166 code - * regardless of contextWrappableAs. + * regardless of viewableAs. * * @param isoCode * the ISO 3166 code to filter providers by @@ -158,29 +158,29 @@ public class Providers { /** * Returns the providers that are bound to the same location as the given ISO 3166 code and of - * the given contextWrappableAs. + * the given viewableAs. * * @param iso3166Code * the ISO 3166 code to filter providers by - * @param contextWrappableAs - * the contextWrappableAs to filter providers by + * @param viewableAs + * the viewableAs to filter providers by * - * @return the providers bound by the given ISO 3166 code and of the proper contextWrappableAs + * @return the providers bound by the given ISO 3166 code and of the proper viewableAs */ public static Iterable boundedByIso3166Code(String iso3166Code, - TypeToken contextWrappableAs) { + TypeToken viewableAs) { return filter(all(), Predicates.and(ProviderPredicates.boundedByIso3166Code(iso3166Code), ProviderPredicates - .contextWrappableAs(contextWrappableAs))); + .viewableAs(viewableAs))); } public static Iterable boundedByIso3166Code(String iso3166Code, - Class contextWrappableAs) { - return boundedByIso3166Code(iso3166Code, TypeToken.of(contextWrappableAs)); + Class viewableAs) { + return boundedByIso3166Code(iso3166Code, TypeToken.of(viewableAs)); } /** * Returns the providers that have at least one common ISO 3166 code in common regardless of - * contextWrappableAs. + * viewableAs. * * @param providerMetadata * the provider metadata to use to filter providers by @@ -193,24 +193,24 @@ public class Providers { /** * Returns the providers that have at least one common ISO 3166 code and are of the given - * contextWrappableAs. + * viewableAs. * * @param providerMetadata * the provider metadata to use to filter providers by - * @param contextWrappableAs - * the contextWrappableAs to filter providers by + * @param viewableAs + * the viewableAs to filter providers by * * @return the providers that share at least one common ISO 3166 code and of the given - * contextWrappableAs + * viewableAs */ public static Iterable collocatedWith(ProviderMetadata providerMetadata, - TypeToken contextWrappableAs) { + TypeToken viewableAs) { return filter(all(), Predicates.and(ProviderPredicates.intersectingIso3166Code(providerMetadata), - ProviderPredicates.contextWrappableAs(contextWrappableAs))); + ProviderPredicates.viewableAs(viewableAs))); } public static Iterable collocatedWith(ProviderMetadata providerMetadata, - Class contextWrappableAs) { - return collocatedWith(providerMetadata, TypeToken.of(contextWrappableAs)); + Class viewableAs) { + return collocatedWith(providerMetadata, TypeToken.of(viewableAs)); } } diff --git a/core/src/main/java/org/jclouds/providers/config/BindProviderMetadataContextAndCredentials.java b/core/src/main/java/org/jclouds/providers/config/BindProviderMetadataContextAndCredentials.java new file mode 100644 index 0000000000..cbba82f485 --- /dev/null +++ b/core/src/main/java/org/jclouds/providers/config/BindProviderMetadataContextAndCredentials.java @@ -0,0 +1,97 @@ +/** + * 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.providers.config; + +import static com.google.common.base.Preconditions.checkNotNull; + +import java.util.Properties; +import java.util.Set; + +import javax.inject.Singleton; + +import org.jclouds.Context; +import org.jclouds.domain.Credentials; +import org.jclouds.location.Iso3166; +import org.jclouds.location.Provider; +import org.jclouds.providers.ProviderMetadata; +import org.jclouds.rest.annotations.Api; +import org.jclouds.rest.annotations.ApiVersion; +import org.jclouds.rest.annotations.BuildVersion; +import org.jclouds.rest.annotations.Credential; +import org.jclouds.rest.annotations.Identity; + +import com.google.common.reflect.TypeToken; +import com.google.inject.AbstractModule; +import com.google.inject.Injector; +import com.google.inject.Key; +import com.google.inject.Provides; +import com.google.inject.TypeLiteral; +import com.google.inject.name.Names; + +/** + * Binds data inside {@link ProviderMetadata} to types with scopes qualified with annotations in the + * {@code org.jclouds.location} and {@code org.jclouds.rest.annotations} packages. It also binds the + * properties specified in {@link ProviderMetadata#getDefaultProperties()} {@link ProviderMetadata} + * explicitly. Finally, it bind the context type so that it can be looked up later. + * + * + * @author Adrian Cole + */ +public class BindProviderMetadataContextAndCredentials extends AbstractModule { + + private final ProviderMetadata providerMetadata; + private final Credentials creds; + + public BindProviderMetadataContextAndCredentials(ProviderMetadata providerMetadata, Credentials creds) { + this.providerMetadata = checkNotNull(providerMetadata, "providerMetadata"); + this.creds = checkNotNull(creds, "creds"); + } + + @Override + protected void configure() { + bind(ProviderMetadata.class).toInstance(providerMetadata); + Properties toBind = new Properties(); + toBind.putAll(providerMetadata.getApiMetadata().getDefaultProperties()); + toBind.putAll(providerMetadata.getDefaultProperties()); + Names.bindProperties(binder(), toBind); + bind(Credentials.class).annotatedWith(Provider.class).toInstance(creds); + bindConstant().annotatedWith(Identity.class).to(creds.identity); + // nullable + bind(String.class).annotatedWith(Credential.class).toProvider( + com.google.inject.util.Providers.of(creds.credential)); + bindConstant().annotatedWith(Provider.class).to(providerMetadata.getId()); + bind(new TypeLiteral>() { + }).annotatedWith(Iso3166.class).toInstance(providerMetadata.getIso3166Codes()); + bindConstant().annotatedWith(Api.class).to(providerMetadata.getApiMetadata().getId()); + bindConstant().annotatedWith(ApiVersion.class).to(providerMetadata.getApiMetadata().getVersion()); + // nullable + bind(String.class).annotatedWith(BuildVersion.class).toProvider( + com.google.inject.util.Providers.of(providerMetadata.getApiMetadata().getBuildVersion().orNull())); + bind(new TypeLiteral>() { + }).annotatedWith(Provider.class).toInstance(providerMetadata.getApiMetadata().getContext()); + } + + @Provides + @Provider + @Singleton + protected Context backend(Injector i, @Provider TypeToken backendType) { + return Context.class.cast(i.getInstance(Key.get(TypeLiteral.get(backendType.getType())))); + } + +} \ No newline at end of file diff --git a/core/src/main/java/org/jclouds/providers/internal/UpdateProviderMetadataFromProperties.java b/core/src/main/java/org/jclouds/providers/internal/UpdateProviderMetadataFromProperties.java new file mode 100644 index 0000000000..7fd5ee6b95 --- /dev/null +++ b/core/src/main/java/org/jclouds/providers/internal/UpdateProviderMetadataFromProperties.java @@ -0,0 +1,102 @@ +/** + * 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.providers.internal; + +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.base.Predicates.equalTo; +import static com.google.common.base.Predicates.not; +import static com.google.common.collect.Iterables.filter; +import static org.jclouds.Constants.PROPERTY_API; +import static org.jclouds.Constants.PROPERTY_API_VERSION; +import static org.jclouds.Constants.PROPERTY_BUILD_VERSION; +import static org.jclouds.Constants.PROPERTY_ENDPOINT; +import static org.jclouds.Constants.PROPERTY_ISO3166_CODES; +import static org.jclouds.Constants.PROPERTY_PROVIDER; + +import java.util.Properties; + +import org.jclouds.apis.ApiMetadata; +import org.jclouds.providers.AnonymousProviderMetadata; +import org.jclouds.providers.ProviderMetadata; + +import com.google.common.base.Function; +import com.google.common.base.Joiner; +import com.google.common.base.Optional; +import com.google.common.base.Splitter; + +/** + * Updates {@link ProviderMetadata} carrying over the input {@code Properties}, filtering out those which are typed fields in {@link ProviderMetadata} or {@link ApiMetadata} + * + * @author Adrian Cole + */ +public class UpdateProviderMetadataFromProperties implements Function { + private final ApiMetadata apiMetadata; + private final Optional providerMetadata; + + public UpdateProviderMetadataFromProperties(ProviderMetadata providerMetadata) { + this(checkNotNull(providerMetadata, "providerMetadata").getApiMetadata(), Optional.of(providerMetadata)); + } + + public UpdateProviderMetadataFromProperties(ApiMetadata apiMetadata) { + this(checkNotNull(apiMetadata, "apiMetadata"), Optional. absent()); + } + + public UpdateProviderMetadataFromProperties(ApiMetadata apiMetadata, Optional providerMetadata) { + this.apiMetadata = checkNotNull(apiMetadata, "apiMetadata"); + this.providerMetadata = checkNotNull(providerMetadata, "providerMetadata"); + } + + @Override + public ProviderMetadata apply(Properties input) { + Properties mutable = new Properties(); + mutable.putAll(input); + ApiMetadata apiMetadata = this.apiMetadata.toBuilder() + .name(getAndRemove(mutable, PROPERTY_API, this.apiMetadata.getName())) + .version(getAndRemove(mutable, PROPERTY_API_VERSION, this.apiMetadata.getVersion())) + .buildVersion(getAndRemove(mutable, PROPERTY_BUILD_VERSION, this.apiMetadata.getBuildVersion().orNull())).build(); + + String endpoint = getAndRemove(mutable, PROPERTY_ENDPOINT, providerMetadata.isPresent() ? providerMetadata.get() + .getEndpoint() : null); + + String providerId = getAndRemove(mutable, PROPERTY_PROVIDER, providerMetadata.isPresent() ? providerMetadata.get() + .getId() : apiMetadata.getId()); + + String isoCodes = getAndRemove(mutable, PROPERTY_ISO3166_CODES, providerMetadata.isPresent() ? Joiner.on(',').join(providerMetadata.get() + .getIso3166Codes()) : ""); + + ProviderMetadata providerMetadata = this.providerMetadata + .or(AnonymousProviderMetadata.forApiWithEndpoint(apiMetadata, checkNotNull(endpoint, PROPERTY_ENDPOINT))) + .toBuilder() + .apiMetadata(apiMetadata) + .id(providerId) + .iso3166Codes(filter(Splitter.on(',').split(isoCodes), not(equalTo("")))) + .endpoint(endpoint).defaultProperties(mutable).build(); + + return providerMetadata; + } + + private static String getAndRemove(Properties expanded, String key, String defaultVal) { + try { + return expanded.getProperty(key, defaultVal); + } finally { + expanded.remove(key); + } + } + +} \ No newline at end of file diff --git a/core/src/main/java/org/jclouds/rest/Providers.java b/core/src/main/java/org/jclouds/rest/Providers.java index 7056cfceec..200aef7f63 100644 --- a/core/src/main/java/org/jclouds/rest/Providers.java +++ b/core/src/main/java/org/jclouds/rest/Providers.java @@ -18,9 +18,8 @@ */ package org.jclouds.rest; -import java.io.Closeable; - -import org.jclouds.Wrapper; +import org.jclouds.Context; +import org.jclouds.View; import org.jclouds.apis.Apis; import com.google.common.collect.ImmutableSet; @@ -40,7 +39,7 @@ public class Providers { * Gets a set of supported providers. Idea stolen from pallets (supported-clouds). */ public static Iterable getSupportedProviders() { - return getSupportedProvidersOfType(TypeToken.of(Wrapper.class)); + return getSupportedProvidersOfType(TypeToken.of(View.class)); } /** @@ -48,10 +47,10 @@ public class Providers { * (supported-clouds). * */ - public static Iterable getSupportedProvidersOfType(TypeToken type) { + public static Iterable getSupportedProvidersOfType(TypeToken type) { Builder builder = ImmutableSet. builder(); - builder.addAll(Iterables.transform(Apis.contextWrappableAs(type), Apis.idFunction())); - builder.addAll(Iterables.transform(org.jclouds.providers.Providers.contextWrappableAs(type), + builder.addAll(Iterables.transform(Apis.viewableAs(type), Apis.idFunction())); + builder.addAll(Iterables.transform(org.jclouds.providers.Providers.viewableAs(type), org.jclouds.providers.Providers.idFunction())); return builder.build(); } diff --git a/core/src/main/java/org/jclouds/rest/RestContext.java b/core/src/main/java/org/jclouds/rest/RestContext.java index f564ace886..4a43cafcaf 100644 --- a/core/src/main/java/org/jclouds/rest/RestContext.java +++ b/core/src/main/java/org/jclouds/rest/RestContext.java @@ -18,17 +18,11 @@ */ package org.jclouds.rest; -import java.io.Closeable; -import java.net.URI; -import java.util.Map; import java.util.concurrent.Future; -import org.jclouds.Constants; -import org.jclouds.domain.Credentials; -import org.jclouds.domain.Location; +import org.jclouds.Context; import org.jclouds.rest.internal.RestContextImpl; -import com.google.common.annotations.Beta; import com.google.inject.ImplementedBy; /** @@ -42,7 +36,7 @@ import com.google.inject.ImplementedBy; * */ @ImplementedBy(RestContextImpl.class) -public interface RestContext extends Location, Closeable { +public interface RestContext extends Context { /** * low-level api to the cloud. Threadsafe implementations will return a singleton. @@ -59,45 +53,4 @@ public interface RestContext extends Location, Closeable { */ S getApi(); - URI getEndpoint(); - - /** - * @return version of the api presented by this service - * @see Constants#PROPERTY_API_VERSION - */ - String getApiVersion(); - - /** - * @return version of software this service is running - * @see Constants#PROPERTY_BUILD_VERSION - */ - String getBuildVersion(); - - String getIdentity(); - - /** - * retrieves a list of credentials for resources created within this context, keyed on {@code id} - * of the resource. We are testing this approach for resources such as compute nodes, where you - * could access this externally. - * - */ - @Beta - Map getCredentialStore(); - - @Beta - Map credentialStore(); - - Utils getUtils(); - - /** - * @see #getUtils - */ - Utils utils(); - - /** - * Closes all connections to Cloud Files. - */ - @Override - void close(); - } \ No newline at end of file diff --git a/core/src/main/java/org/jclouds/rest/RestContextFactory.java b/core/src/main/java/org/jclouds/rest/RestContextFactory.java index b1f3ff0f98..49d3dbd698 100644 --- a/core/src/main/java/org/jclouds/rest/RestContextFactory.java +++ b/core/src/main/java/org/jclouds/rest/RestContextFactory.java @@ -22,7 +22,7 @@ import java.util.NoSuchElementException; import java.util.Properties; import org.jclouds.ContextBuilder; -import org.jclouds.Wrapper; +import org.jclouds.View; import org.jclouds.apis.Apis; import org.jclouds.javax.annotation.Nullable; import org.jclouds.providers.ProviderMetadata; @@ -122,8 +122,8 @@ public class RestContextFactory { Object context = builder.build(); if (context instanceof RestContext) { return RestContext.class.cast(context); - } else if (context instanceof Wrapper) { - Wrapper tctx = Wrapper.class.cast(context); + } else if (context instanceof View) { + View tctx = View.class.cast(context); return (RestContext) tctx.unwrap(TypeToken.of(RestContext.class)); } else { throw new IllegalArgumentException("provider " + providerOrApi + " contains an unknown context type: " diff --git a/core/src/main/java/org/jclouds/rest/Utils.java b/core/src/main/java/org/jclouds/rest/Utils.java index b3f0408987..5f233df8af 100644 --- a/core/src/main/java/org/jclouds/rest/Utils.java +++ b/core/src/main/java/org/jclouds/rest/Utils.java @@ -18,10 +18,12 @@ */ package org.jclouds.rest; +import java.util.Map; import java.util.concurrent.ExecutorService; import org.jclouds.crypto.Crypto; import org.jclouds.date.DateService; +import org.jclouds.domain.Credentials; import org.jclouds.json.Json; import org.jclouds.logging.Logger.LoggerFactory; import org.jclouds.rest.internal.UtilsImpl; @@ -41,6 +43,31 @@ import com.google.inject.Injector; @ImplementedBy(UtilsImpl.class) public interface Utils { + /** + * retrieves a list of credentials for resources created within this context, keyed on {@code id} + * of the resource with a namespace prefix (ex. {@code node#}. We are testing this approach for + * resources such as compute nodes, where you could access this externally. + *

+ *

accessing credentials for a node

+ *

+ * the key is in the form {@code node#id}. + *

    + *
  • if the node id is {@code 8}, then the key will be {@code node#8}
  • + *
  • if the node id is {@code us-east-1/i-asdfdas}, then the key will be {@code + * node#us-east-1/i-asdfdas}
  • + *
  • if the node id is {@code http://cloud/instances/1}, then the key will be {@code + * node#http://cloud/instances/1}
  • + *
+ */ + @Beta + Map getCredentialStore(); + + /** + * @see ComputeServiceContext#getCredentialStore + */ + @Beta + Map credentialStore(); + Json getJson(); /** diff --git a/core/src/main/java/org/jclouds/rest/config/BindPropertiesToAnnotations.java b/core/src/main/java/org/jclouds/rest/config/BindPropertiesToAnnotations.java deleted file mode 100644 index 76c8a954b9..0000000000 --- a/core/src/main/java/org/jclouds/rest/config/BindPropertiesToAnnotations.java +++ /dev/null @@ -1,159 +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.rest.config; - -import static com.google.common.base.Predicates.equalTo; -import static com.google.common.base.Predicates.not; -import static com.google.common.base.Splitter.on; -import static com.google.common.collect.Iterables.filter; -import static org.jclouds.Constants.PROPERTY_API; -import static org.jclouds.Constants.PROPERTY_API_VERSION; -import static org.jclouds.Constants.PROPERTY_BUILD_VERSION; -import static org.jclouds.Constants.PROPERTY_CREDENTIAL; -import static org.jclouds.Constants.PROPERTY_IDENTITY; -import static org.jclouds.Constants.PROPERTY_ISO3166_CODES; -import static org.jclouds.Constants.PROPERTY_PROVIDER; -import static org.jclouds.Constants.PROPERTY_TIMEOUTS_PREFIX; - -import java.util.Map; -import java.util.Set; - -import javax.inject.Named; -import javax.inject.Singleton; - -import org.jclouds.config.ValueOfConfigurationKeyOrNull; -import org.jclouds.domain.Credentials; -import org.jclouds.internal.FilterStringsBoundToInjectorByName; -import org.jclouds.javax.annotation.Nullable; -import org.jclouds.location.Iso3166; -import org.jclouds.location.Provider; -import org.jclouds.rest.annotations.Api; -import org.jclouds.rest.annotations.ApiVersion; -import org.jclouds.rest.annotations.BuildVersion; -import org.jclouds.rest.annotations.Credential; -import org.jclouds.rest.annotations.Identity; -import org.jclouds.util.Maps2; -import org.nnsoft.guice.rocoto.configuration.ConfigurationModule; - -import com.google.common.base.Function; -import com.google.common.base.Predicate; -import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Maps; -import com.google.inject.Provides; -import com.google.inject.TypeLiteral; - -public class BindPropertiesToAnnotations extends ConfigurationModule { - - @Provides - @Singleton - @Named("TIMEOUTS") - protected Map timeouts(Function, Map> filterStringsBoundByName) { - Map stringBoundWithTimeoutPrefix = filterStringsBoundByName.apply(new Predicate() { - - @Override - public boolean apply(String input) { - return input.startsWith(PROPERTY_TIMEOUTS_PREFIX); - } - - }); - - Map longsByName = Maps.transformValues(stringBoundWithTimeoutPrefix, new Function() { - - @Override - public Long apply(String input) { - return Long.valueOf(String.valueOf(input)); - } - - }); - return Maps2.transformKeys(longsByName, new Function() { - - @Override - public String apply(String input) { - return input.replaceFirst(PROPERTY_TIMEOUTS_PREFIX, ""); - } - - }); - - } - - @Provides - @Singleton - @Provider - protected String bindProvider(@Named(PROPERTY_PROVIDER) String in){ - return in; - } - - @Provides - @Singleton - @Iso3166 - protected Set bindIsoCodes(@Named(PROPERTY_ISO3166_CODES) String in){ - return ImmutableSet.copyOf(filter(on(',').split( in), - not(equalTo("")))); - } - - @Provides - @Singleton - @Api - protected String bindApi(@Named(PROPERTY_API) String in){ - return in; - } - - @Provides - @Singleton - @ApiVersion - protected String bindApiVersion(@Named(PROPERTY_API_VERSION) String in){ - return in; - } - - @Provides - @Singleton - @BuildVersion - protected String bindBuildVersion(@Named(PROPERTY_BUILD_VERSION) String in){ - return in; - } - - @Provides - @Singleton - @Identity - protected String bindIdentity(@Named(PROPERTY_IDENTITY) String in){ - return in; - } - - @Provides - @Singleton - @Credential - @Nullable - protected String bindCredential(ValueOfConfigurationKeyOrNull config){ - return config.apply(PROPERTY_CREDENTIAL); - } - - @Provides - @Singleton - @Provider - protected Credentials bindProviderCredentials(@Identity String identity, @Nullable @Credential String credential){ - return new Credentials(identity, credential); - } - - @Override - protected void bindConfigurations() { - bind(new TypeLiteral, Map>>() { - }).to(FilterStringsBoundToInjectorByName.class); - } - -} \ No newline at end of file diff --git a/core/src/main/java/org/jclouds/rest/config/RestModule.java b/core/src/main/java/org/jclouds/rest/config/RestModule.java index 429fd59571..4b5e19f829 100644 --- a/core/src/main/java/org/jclouds/rest/config/RestModule.java +++ b/core/src/main/java/org/jclouds/rest/config/RestModule.java @@ -18,6 +18,8 @@ */ package org.jclouds.rest.config; +import static org.jclouds.Constants.PROPERTY_TIMEOUTS_PREFIX; + import java.net.URI; import java.util.Map; import java.util.concurrent.atomic.AtomicReference; @@ -34,6 +36,7 @@ import org.jclouds.http.TransformingHttpCommandExecutorService; import org.jclouds.http.TransformingHttpCommandImpl; import org.jclouds.http.functions.config.SaxParserModule; import org.jclouds.internal.ClassMethodArgs; +import org.jclouds.internal.FilterStringsBoundToInjectorByName; import org.jclouds.json.config.GsonModule; import org.jclouds.location.config.LocationModule; import org.jclouds.rest.AsyncClientFactory; @@ -44,13 +47,16 @@ import org.jclouds.rest.binders.BindToJsonPayloadWrappedWith; import org.jclouds.rest.internal.AsyncRestClientProxy; import org.jclouds.rest.internal.RestAnnotationProcessor; import org.jclouds.rest.internal.SeedAnnotationCache; +import org.jclouds.util.Maps2; import com.google.common.base.Function; +import com.google.common.base.Predicate; import com.google.common.base.Supplier; import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheLoader; import com.google.common.cache.LoadingCache; import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Maps; import com.google.inject.AbstractModule; import com.google.inject.Inject; import com.google.inject.Injector; @@ -96,8 +102,42 @@ public class RestModule extends AbstractModule { // this will help short circuit scenarios that can otherwise lock out users bind(new TypeLiteral>() { }).toInstance(authException); + bind(new TypeLiteral, Map>>() { + }).to(FilterStringsBoundToInjectorByName.class); installLocations(); } + + @Provides + @Singleton + @Named("TIMEOUTS") + protected Map timeouts(Function, Map> filterStringsBoundByName) { + Map stringBoundWithTimeoutPrefix = filterStringsBoundByName.apply(new Predicate() { + + @Override + public boolean apply(String input) { + return input.startsWith(PROPERTY_TIMEOUTS_PREFIX); + } + + }); + + Map longsByName = Maps.transformValues(stringBoundWithTimeoutPrefix, new Function() { + + @Override + public Long apply(String input) { + return Long.valueOf(String.valueOf(input)); + } + + }); + return Maps2.transformKeys(longsByName, new Function() { + + @Override + public String apply(String input) { + return input.replaceFirst(PROPERTY_TIMEOUTS_PREFIX, ""); + } + + }); + + } @Provides @Singleton diff --git a/core/src/main/java/org/jclouds/rest/internal/AsyncRestClientProxy.java b/core/src/main/java/org/jclouds/rest/internal/AsyncRestClientProxy.java index 71ef6f089a..4a80df1814 100644 --- a/core/src/main/java/org/jclouds/rest/internal/AsyncRestClientProxy.java +++ b/core/src/main/java/org/jclouds/rest/internal/AsyncRestClientProxy.java @@ -99,7 +99,7 @@ public class AsyncRestClientProxy implements InvocationHandler { private final Factory commandFactory; /** - * maximum duration of an unwrapped http Request + * maximum duration of an unbackend http Request */ @Inject(optional = true) @Named(Constants.PROPERTY_REQUEST_TIMEOUT) diff --git a/core/src/main/java/org/jclouds/rest/internal/RestContextImpl.java b/core/src/main/java/org/jclouds/rest/internal/RestContextImpl.java index aff8b644cf..c592d98809 100644 --- a/core/src/main/java/org/jclouds/rest/internal/RestContextImpl.java +++ b/core/src/main/java/org/jclouds/rest/internal/RestContextImpl.java @@ -18,30 +18,17 @@ */ package org.jclouds.rest.internal; -import java.io.IOException; -import java.net.URI; -import java.util.Map; -import java.util.Set; +import static com.google.common.base.Preconditions.checkNotNull; -import javax.annotation.Resource; import javax.inject.Inject; -import org.jclouds.domain.Credentials; -import org.jclouds.domain.Location; -import org.jclouds.domain.LocationScope; +import org.jclouds.internal.ContextImpl; import org.jclouds.lifecycle.Closer; -import org.jclouds.location.Iso3166; -import org.jclouds.location.Provider; -import org.jclouds.logging.Logger; +import org.jclouds.providers.ProviderMetadata; import org.jclouds.rest.RestContext; import org.jclouds.rest.Utils; -import org.jclouds.rest.annotations.ApiVersion; -import org.jclouds.rest.annotations.BuildVersion; import org.jclouds.rest.annotations.Identity; -import com.google.common.base.Objects; -import com.google.common.base.Supplier; -import com.google.common.collect.ImmutableMap; import com.google.inject.Injector; import com.google.inject.Key; import com.google.inject.Singleton; @@ -51,57 +38,18 @@ import com.google.inject.TypeLiteral; * @author Adrian Cole */ @Singleton -public class RestContextImpl implements RestContext { +public class RestContextImpl extends ContextImpl implements RestContext { - @Resource - private Logger logger = Logger.NULL; private final A asyncApi; private final S syncApi; - private final Closer closer; - private final Supplier endpoint; - private final String identity; - private final String provider; - private final String apiVersion; - private final String buildVersion; - private final Utils utils; - private final Map credentialStore; - private final Set iso3166Codes; @Inject - protected RestContextImpl(Closer closer, Map credentialStore, Utils utils, Injector injector, - TypeLiteral syncApi, TypeLiteral
asyncApi, @Provider Supplier endpoint, @Provider String provider, - @Identity String identity, @ApiVersion String apiVersion, @BuildVersion String buildVersion, - @Iso3166 Set iso3166Codes) { - this.credentialStore = credentialStore; - this.utils = utils; - this.asyncApi = injector.getInstance(Key.get(asyncApi)); - this.syncApi = injector.getInstance(Key.get(syncApi)); - this.closer = closer; - this.endpoint = endpoint; - this.identity = identity; - this.provider = provider; - this.apiVersion = apiVersion; - this.buildVersion = buildVersion; - this.iso3166Codes = iso3166Codes; - } - - /** - * {@inheritDoc} - * - * @see Closer - */ - @Override - public void close() { - try { - closer.close(); - } catch (IOException e) { - logger.error(e, "error closing context"); - } - } - - @Override - public String getIdentity() { - return identity; + protected RestContextImpl(ProviderMetadata providerMetadata, @Identity String identity, Utils utils, Closer closer, + Injector injector, TypeLiteral syncApi, TypeLiteral asyncApi) { + super(providerMetadata, identity, utils, closer); + checkNotNull(injector, "injector"); + this.asyncApi = injector.getInstance(Key.get(checkNotNull(asyncApi, "asyncApi"))); + this.syncApi = injector.getInstance(Key.get(checkNotNull(syncApi, "syncApi"))); } @Override @@ -114,96 +62,4 @@ public class RestContextImpl implements RestContext { return syncApi; } - @Override - public URI getEndpoint() { - return endpoint.get(); - } - - @Override - public Utils getUtils() { - return utils(); - } - - @Override - public Utils utils() { - return utils; - } - - @Override - public String getApiVersion() { - return apiVersion; - } - - @Override - public String getBuildVersion() { - return buildVersion; - } - - - @Override - public int hashCode() { - return Objects.hashCode(provider, endpoint, apiVersion, buildVersion, identity); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - RestContextImpl that = (RestContextImpl) obj; - return Objects.equal(this.provider, that.provider) && Objects.equal(this.endpoint, that.endpoint) - && Objects.equal(this.apiVersion, that.apiVersion) - && Objects.equal(this.buildVersion, that.buildVersion) && Objects.equal(this.identity, that.identity); - } - - @Override - public String toString() { - return Objects.toStringHelper("").add("provider", provider).add("endpoint", endpoint).add("apiVersion", - apiVersion).add("buildVersion", buildVersion).add("identity", identity) - .add("iso3166Codes", iso3166Codes).toString(); - } - - @Override - public Map getCredentialStore() { - return credentialStore; - } - - @Override - public Map credentialStore() { - return credentialStore; - } - - @Override - public String getDescription() { - return null; - } - - @Override - public String getId() { - return provider; - } - - @Override - public Set getIso3166Codes() { - return iso3166Codes; - } - - @Override - public Map getMetadata() { - return ImmutableMap. of("endpoint", endpoint, "apiVersion", apiVersion, "buildVersion", - buildVersion, "identity", identity); - } - - @Override - public Location getParent() { - return null; - } - - @Override - public LocationScope getScope() { - return LocationScope.PROVIDER; - } } 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 4860bf94dc..d4af5d7fe4 100644 --- a/core/src/main/java/org/jclouds/rest/internal/UtilsImpl.java +++ b/core/src/main/java/org/jclouds/rest/internal/UtilsImpl.java @@ -18,6 +18,7 @@ */ package org.jclouds.rest.internal; +import java.util.Map; import java.util.concurrent.ExecutorService; import javax.inject.Inject; @@ -26,6 +27,7 @@ import javax.inject.Named; import org.jclouds.Constants; import org.jclouds.crypto.Crypto; import org.jclouds.date.DateService; +import org.jclouds.domain.Credentials; import org.jclouds.json.Json; import org.jclouds.logging.Logger.LoggerFactory; import org.jclouds.rest.HttpAsyncClient; @@ -52,6 +54,7 @@ public class UtilsImpl implements Utils { private final ExecutorService userExecutor; private final ExecutorService ioExecutor; private final EventBus eventBus; + private final Map credentialStore; private final LoggerFactory loggerFactory; private Injector injector; private XMLParser xml; @@ -59,8 +62,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, - LoggerFactory loggerFactory) { + @Named(Constants.PROPERTY_IO_WORKER_THREADS) ExecutorService ioThreads, EventBus eventBus, + Map credentialStore, LoggerFactory loggerFactory) { this.injector = injector; this.json = json; this.simpleClient = simpleClient; @@ -70,6 +73,7 @@ public class UtilsImpl implements Utils { this.userExecutor = userThreads; this.ioExecutor = ioThreads; this.eventBus = eventBus; + this.credentialStore = credentialStore; this.loggerFactory = loggerFactory; this.xml = xml; } @@ -186,4 +190,14 @@ public class UtilsImpl implements Utils { return xml; } + @Override + public Map credentialStore() { + return credentialStore; + } + + @Override + public Map getCredentialStore() { + return credentialStore; + } + } diff --git a/core/src/main/java/org/jclouds/util/ConcreteFunction.java b/core/src/main/java/org/jclouds/util/ConcreteFunction.java new file mode 100644 index 0000000000..27ac98c67d --- /dev/null +++ b/core/src/main/java/org/jclouds/util/ConcreteFunction.java @@ -0,0 +1,45 @@ +/** + * 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.util; + +import com.google.common.base.Function; + + +/** + * For wrapping covariant functions for passing to non-covariant methods + * + * @author danikov + */ +public class ConcreteFunction implements Function { + private final Function delegate; + + public static ConcreteFunction wrap(Function delegate) { + return new ConcreteFunction(delegate); + } + + public ConcreteFunction(Function delegate) { + this.delegate = delegate; + } + + @Override + public T apply(F input) { + return delegate.apply(input); + } + +} diff --git a/core/src/test/java/org/jclouds/ContextBuilderTest.java b/core/src/test/java/org/jclouds/ContextBuilderTest.java index 3d2d4a2ae0..4d9ea2788e 100644 --- a/core/src/test/java/org/jclouds/ContextBuilderTest.java +++ b/core/src/test/java/org/jclouds/ContextBuilderTest.java @@ -20,9 +20,12 @@ package org.jclouds; import static org.testng.Assert.assertEquals; +import java.net.URI; import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.Properties; +import java.util.Set; import org.jclouds.concurrent.config.ExecutorServiceModule; import org.jclouds.events.config.EventBusModule; @@ -30,17 +33,23 @@ import org.jclouds.http.IntegrationTestAsyncClient; import org.jclouds.http.IntegrationTestClient; import org.jclouds.http.config.ConfiguresHttpCommandExecutorService; import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule; +import org.jclouds.location.Provider; import org.jclouds.logging.config.LoggingModule; import org.jclouds.logging.config.NullLoggingModule; import org.jclouds.logging.jdk.config.JDKLoggingModule; import org.jclouds.providers.AnonymousProviderMetadata; +import org.jclouds.providers.ProviderMetadata; import org.jclouds.rest.ConfiguresRestClient; import org.jclouds.rest.config.CredentialStoreModule; import org.testng.annotations.Test; +import com.google.common.base.Supplier; +import com.google.common.collect.ImmutableSet; import com.google.inject.AbstractModule; import com.google.inject.Binder; +import com.google.inject.Key; import com.google.inject.Module; +import com.google.inject.TypeLiteral; /** * Tests behavior of modules configured in ContextBuilder @@ -63,13 +72,40 @@ public class ContextBuilderTest { return ContextBuilder.newBuilder(AnonymousProviderMetadata.forClientMappedToAsyncClientOnEndpoint( IntegrationTestClient.class, IntegrationTestAsyncClient.class, "http://localhost")); } + + @Test + public void testVariablesReplaceOnEndpoint() { + ContextBuilder withVariablesToReplace = testContextBuilder().endpoint("http://${jclouds.identity}.service.com") + .credentials("foo", "bar"); + URI endpoint = withVariablesToReplace.buildInjector().getInstance( + Key.get(new TypeLiteral>(){}, Provider.class)).get(); + assertEquals(endpoint, URI.create("http://foo.service.com")); + } + + @Test + public void testProviderMetadataBoundWithCorrectEndpoint() { + ContextBuilder withVariablesToReplace = testContextBuilder().endpoint("http://${jclouds.identity}.service.com") + .credentials("foo", "bar"); + String endpoint = withVariablesToReplace.buildInjector().getInstance(ProviderMetadata.class).getEndpoint(); + assertEquals(endpoint, "http://foo.service.com"); + } + + @Test + public void testProviderMetadataWithEmptyIsoCodePropertyHasEmptySet() { + Properties overrides = new Properties(); + overrides.setProperty(Constants.PROPERTY_ISO3166_CODES, ""); + ContextBuilder withVariablesToReplace = testContextBuilder().overrides(overrides).credentials("foo", "bar"); + Set codes = withVariablesToReplace.buildInjector().getInstance(ProviderMetadata.class).getIso3166Codes(); + assertEquals(codes, ImmutableSet. of()); + } + @Test public void testAddHttpModuleIfNotPresent() { List modules = new ArrayList(); HttpModule module = new HttpModule(); modules.add(module); - testContextBuilder().addHttpModuleIfNeededAndNotPresent(modules); + ContextBuilder.addHttpModuleIfNeededAndNotPresent(modules); assertEquals(modules.size(), 1); assertEquals(modules.remove(0), module); } @@ -79,7 +115,7 @@ public class ContextBuilderTest { List modules = new ArrayList(); LoggingModule module = new NullLoggingModule(); modules.add(module); - testContextBuilder().addLoggingModuleIfNotPresent(modules); + ContextBuilder.addLoggingModuleIfNotPresent(modules); assertEquals(modules.size(), 1); assertEquals(modules.remove(0), module); } @@ -89,7 +125,7 @@ public class ContextBuilderTest { List modules = new ArrayList(); EventBusModule module = new EventBusModule(); modules.add(module); - testContextBuilder().addEventBusIfNotPresent(modules); + ContextBuilder.addEventBusIfNotPresent(modules); assertEquals(modules.size(), 1); assertEquals(modules.remove(0), module); } @@ -99,7 +135,7 @@ public class ContextBuilderTest { List modules = new ArrayList(); ExecutorServiceModule module = new ExecutorServiceModule(); modules.add(module); - testContextBuilder().addExecutorServiceIfNotPresent(modules); + ContextBuilder.addExecutorServiceIfNotPresent(modules); assertEquals(modules.size(), 1); assertEquals(modules.remove(0), module); } @@ -109,7 +145,7 @@ public class ContextBuilderTest { List modules = new ArrayList(); CredentialStoreModule module = new CredentialStoreModule(); modules.add(module); - testContextBuilder().addCredentialStoreIfNotPresent(modules); + ContextBuilder.addCredentialStoreIfNotPresent(modules); assertEquals(modules.size(), 1); assertEquals(modules.remove(0), module); } @@ -121,9 +157,8 @@ public class ContextBuilderTest { modules.add(loggingModule); HttpModule httpModule = new HttpModule(); modules.add(httpModule); - ContextBuilder builder = testContextBuilder(); - builder.addHttpModuleIfNeededAndNotPresent(modules); - builder.addLoggingModuleIfNotPresent(modules); + ContextBuilder.addHttpModuleIfNeededAndNotPresent(modules); + ContextBuilder.addLoggingModuleIfNotPresent(modules); assertEquals(modules.size(), 2); assertEquals(modules.remove(0), loggingModule); assertEquals(modules.remove(0), httpModule); @@ -140,9 +175,8 @@ public class ContextBuilderTest { @Test public void testAddBothWhenDefault() { List modules = new ArrayList(); - ContextBuilder builder = testContextBuilder(); - builder.addHttpModuleIfNeededAndNotPresent(modules); - builder.addLoggingModuleIfNotPresent(modules); + ContextBuilder.addHttpModuleIfNeededAndNotPresent(modules); + ContextBuilder.addLoggingModuleIfNotPresent(modules); assertEquals(modules.size(), 2); assert modules.remove(0) instanceof JavaUrlHttpCommandExecutorServiceModule; assert modules.remove(0) instanceof JDKLoggingModule; @@ -151,9 +185,8 @@ public class ContextBuilderTest { @Test public void testAddBothWhenLive() { List modules = new ArrayList(); - ContextBuilder builder = testContextBuilder(); - builder.addHttpModuleIfNeededAndNotPresent(modules); - builder.addLoggingModuleIfNotPresent(modules); + ContextBuilder.addHttpModuleIfNeededAndNotPresent(modules); + ContextBuilder.addLoggingModuleIfNotPresent(modules); assertEquals(modules.size(), 2); assert modules.remove(0) instanceof JavaUrlHttpCommandExecutorServiceModule; assert modules.remove(0) instanceof JDKLoggingModule; diff --git a/core/src/test/java/org/jclouds/apis/ApisTest.java b/core/src/test/java/org/jclouds/apis/ApisTest.java index 211837360c..97a75c669c 100644 --- a/core/src/test/java/org/jclouds/apis/ApisTest.java +++ b/core/src/test/java/org/jclouds/apis/ApisTest.java @@ -55,13 +55,13 @@ public class ApisTest { @Test public void testTransformableTo() { - Iterable apisMetadata = Apis.contextWrappableAs(Storage.class); + Iterable apisMetadata = Apis.viewableAs(Storage.class); for (ApiMetadata apiMetadata : apisMetadata) { assertEquals(testBlobstoreApi, apiMetadata); } - apisMetadata = Apis.contextWrappableAs(Compute.class); + apisMetadata = Apis.viewableAs(Compute.class); for (ApiMetadata apiMetadata : apisMetadata) { if (apiMetadata.getName().equals(testComputeApi.getName())) { @@ -71,7 +71,7 @@ public class ApisTest { } } - apisMetadata = Apis.contextWrappableAs(Balancer.class); + apisMetadata = Apis.viewableAs(Balancer.class); assertEquals(false, apisMetadata.iterator().hasNext()); } diff --git a/core/src/test/java/org/jclouds/apis/Balancer.java b/core/src/test/java/org/jclouds/apis/Balancer.java index 1b6fe0be48..6fd42be146 100644 --- a/core/src/test/java/org/jclouds/apis/Balancer.java +++ b/core/src/test/java/org/jclouds/apis/Balancer.java @@ -18,9 +18,8 @@ */ package org.jclouds.apis; -import java.io.Closeable; - -import org.jclouds.internal.BaseWrapper; +import org.jclouds.Context; +import org.jclouds.internal.BaseView; import org.jclouds.location.Provider; import com.google.common.reflect.TypeToken; @@ -29,10 +28,10 @@ import com.google.inject.Inject; /** * For tests */ -public class Balancer extends BaseWrapper { +public class Balancer extends BaseView { @Inject - public Balancer(@Provider Closeable ctx, @Provider TypeToken inputType) { + public Balancer(@Provider Context ctx, @Provider TypeToken inputType) { super(ctx, inputType); } } diff --git a/core/src/test/java/org/jclouds/apis/BaseContextLiveTest.java b/core/src/test/java/org/jclouds/apis/BaseContextLiveTest.java index f71ac1e121..d8c2891598 100644 --- a/core/src/test/java/org/jclouds/apis/BaseContextLiveTest.java +++ b/core/src/test/java/org/jclouds/apis/BaseContextLiveTest.java @@ -20,15 +20,13 @@ package org.jclouds.apis; import static com.google.common.base.Preconditions.checkNotNull; -import java.io.Closeable; import java.util.NoSuchElementException; import java.util.Properties; import java.util.logging.Logger; import org.jclouds.Constants; +import org.jclouds.Context; import org.jclouds.ContextBuilder; -import org.jclouds.apis.ApiMetadata; -import org.jclouds.apis.Apis; import org.jclouds.logging.LoggingModules; import org.jclouds.logging.config.LoggingModule; import org.jclouds.providers.ProviderMetadata; @@ -45,7 +43,7 @@ import com.google.inject.Module; * * @author Adrian Cole */ -public abstract class BaseContextLiveTest { +public abstract class BaseContextLiveTest { protected String prefix = System.getProperty("user.name"); protected String provider; @@ -82,8 +80,7 @@ public abstract class BaseContextLiveTest { } protected void initializeContext() { - if (context != null) - Closeables.closeQuietly(context); + Closeables.closeQuietly(context); context = createContext(setupProperties(), setupModules()); } diff --git a/core/src/test/java/org/jclouds/apis/BaseViewLiveTest.java b/core/src/test/java/org/jclouds/apis/BaseViewLiveTest.java new file mode 100644 index 0000000000..b6513ca8c0 --- /dev/null +++ b/core/src/test/java/org/jclouds/apis/BaseViewLiveTest.java @@ -0,0 +1,56 @@ +/** + * 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.apis; + +import java.util.Properties; + +import org.jclouds.Context; +import org.jclouds.View; + +import com.google.common.io.Closeables; +import com.google.common.reflect.TypeToken; +import com.google.inject.Module; + +/** + * + * @author Adrian Cole + */ +public abstract class BaseViewLiveTest extends BaseContextLiveTest{ + + protected volatile V view; + + @Override + protected void initializeContext() { + Closeables.closeQuietly(context); + view = createView(setupProperties(), setupModules()); + context = view.unwrap(); + } + + protected abstract TypeToken viewType(); + + @Override + protected TypeToken contextType() { + return TypeToken.of(Context.class); + } + + protected V createView(Properties props, Iterable modules) { + return newBuilder().modules(modules).overrides(props).buildView(viewType()); + } + +} diff --git a/core/src/test/java/org/jclouds/apis/Compute.java b/core/src/test/java/org/jclouds/apis/Compute.java index 41bbc31787..f725b9784d 100644 --- a/core/src/test/java/org/jclouds/apis/Compute.java +++ b/core/src/test/java/org/jclouds/apis/Compute.java @@ -18,9 +18,8 @@ */ package org.jclouds.apis; -import java.io.Closeable; - -import org.jclouds.internal.BaseWrapper; +import org.jclouds.Context; +import org.jclouds.internal.BaseView; import org.jclouds.location.Provider; import com.google.common.reflect.TypeToken; @@ -28,9 +27,9 @@ import com.google.common.reflect.TypeToken; /** * For tests */ -public class Compute extends BaseWrapper { +public class Compute extends BaseView { - public Compute(@Provider Closeable ctx, @Provider TypeToken inputType) { + public Compute(@Provider Context ctx, @Provider TypeToken inputType) { super(ctx, inputType); } } diff --git a/core/src/test/java/org/jclouds/apis/JcloudsTestBlobStoreApiMetadata.java b/core/src/test/java/org/jclouds/apis/JcloudsTestBlobStoreApiMetadata.java index ad9fab58cd..d67646956a 100644 --- a/core/src/test/java/org/jclouds/apis/JcloudsTestBlobStoreApiMetadata.java +++ b/core/src/test/java/org/jclouds/apis/JcloudsTestBlobStoreApiMetadata.java @@ -58,7 +58,7 @@ public class JcloudsTestBlobStoreApiMetadata extends BaseRestApiMetadata { protected Builder(){ super(IntegrationTestClient.class, IntegrationTestAsyncClient.class); id("test-blobstore-api") - .wrapper(Storage.class) + .view(Storage.class) .name("Test Blobstore Api") .identityName("user") .credentialName("password") diff --git a/core/src/test/java/org/jclouds/apis/JcloudsTestComputeApiMetadata.java b/core/src/test/java/org/jclouds/apis/JcloudsTestComputeApiMetadata.java index 990ca48d01..16e2868b1d 100644 --- a/core/src/test/java/org/jclouds/apis/JcloudsTestComputeApiMetadata.java +++ b/core/src/test/java/org/jclouds/apis/JcloudsTestComputeApiMetadata.java @@ -56,7 +56,7 @@ public class JcloudsTestComputeApiMetadata extends BaseRestApiMetadata { protected Builder(){ super(IntegrationTestClient.class, IntegrationTestAsyncClient.class); id("test-compute-api") - .wrapper(Compute.class) + .view(Compute.class) .name("Test Compute Api") .identityName("user") .credentialName("password") diff --git a/core/src/test/java/org/jclouds/apis/JcloudsTestYetAnotherComputeApiMetadata.java b/core/src/test/java/org/jclouds/apis/JcloudsTestYetAnotherComputeApiMetadata.java index 530629d212..ac10bd4b8a 100644 --- a/core/src/test/java/org/jclouds/apis/JcloudsTestYetAnotherComputeApiMetadata.java +++ b/core/src/test/java/org/jclouds/apis/JcloudsTestYetAnotherComputeApiMetadata.java @@ -56,7 +56,7 @@ public class JcloudsTestYetAnotherComputeApiMetadata extends BaseRestApiMetadata protected Builder(){ super(IntegrationTestClient.class, IntegrationTestAsyncClient.class); id("test-yet-another-compute-api") - .wrapper(Compute.class) + .view(Compute.class) .name("Test Yet Another Compute Api") .identityName("user") .credentialName("password") diff --git a/core/src/test/java/org/jclouds/apis/Storage.java b/core/src/test/java/org/jclouds/apis/Storage.java index b16df9976e..9ebe7c5b60 100644 --- a/core/src/test/java/org/jclouds/apis/Storage.java +++ b/core/src/test/java/org/jclouds/apis/Storage.java @@ -18,9 +18,8 @@ */ package org.jclouds.apis; -import java.io.Closeable; - -import org.jclouds.internal.BaseWrapper; +import org.jclouds.Context; +import org.jclouds.internal.BaseView; import org.jclouds.location.Provider; import com.google.common.reflect.TypeToken; @@ -29,10 +28,10 @@ import com.google.inject.Inject; /** * For tests */ -public class Storage extends BaseWrapper { +public class Storage extends BaseView { @Inject - public Storage(@Provider Closeable ctx, @Provider TypeToken inputType) { + public Storage(@Provider Context ctx, @Provider TypeToken inputType) { super(ctx, inputType); } } diff --git a/core/src/test/java/org/jclouds/apis/internal/BaseApiMetadataTest.java b/core/src/test/java/org/jclouds/apis/internal/BaseApiMetadataTest.java index e8c95de2ed..e0bd3a19cb 100644 --- a/core/src/test/java/org/jclouds/apis/internal/BaseApiMetadataTest.java +++ b/core/src/test/java/org/jclouds/apis/internal/BaseApiMetadataTest.java @@ -22,7 +22,7 @@ import static org.testng.Assert.assertEquals; import java.util.Set; -import org.jclouds.Wrapper; +import org.jclouds.View; import org.jclouds.apis.ApiMetadata; import org.jclouds.apis.Apis; import org.testng.annotations.Test; @@ -38,11 +38,11 @@ import com.google.common.reflect.TypeToken; public abstract class BaseApiMetadataTest { protected final ApiMetadata toTest; - protected final Set> wrappers; + protected final Set> views; - public BaseApiMetadataTest(ApiMetadata toTest, Set> wrappers) { + public BaseApiMetadataTest(ApiMetadata toTest, Set> views) { this.toTest = toTest; - this.wrappers = wrappers; + this.views = views; } @Test @@ -55,10 +55,10 @@ public abstract class BaseApiMetadataTest { // it is ok to have multiple services in the same classpath (ex. ec2 vs elb) @Test public void testTransformableToContains() { - for (TypeToken wrapper : wrappers) { - ImmutableSet ofType = ImmutableSet.copyOf(Apis.contextWrappableAs(wrapper)); + for (TypeToken view : views) { + ImmutableSet ofType = ImmutableSet.copyOf(Apis.viewableAs(view)); assert ofType.contains(toTest) : String.format("%s not found in %s for %s", toTest, ofType, - wrapper); + view); } } diff --git a/core/src/test/java/org/jclouds/config/BindPropertiesToExpandedValuesTest.java b/core/src/test/java/org/jclouds/config/BindPropertiesToExpandedValuesTest.java new file mode 100644 index 0000000000..22290b0b81 --- /dev/null +++ b/core/src/test/java/org/jclouds/config/BindPropertiesToExpandedValuesTest.java @@ -0,0 +1,49 @@ +/** + * 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.config; + +import static org.testng.Assert.assertEquals; + +import java.util.Properties; + +import org.testng.annotations.Test; + +import com.google.inject.Guice; + +/** + * Tests behavior of BindPropertiesToExpandedValues + * + * @author Adrian Cole + */ +@Test(groups = "unit", testName = "BindPropertiesToExpandedValuesTest") +public class BindPropertiesToExpandedValuesTest { + + @Test + public void testExpand() { + Properties input = new Properties(); + input.setProperty("id", "1234"); + input.setProperty("path", "path:${id}"); + Properties output = Guice.createInjector(new BindPropertiesToExpandedValues(input)).getInstance(Properties.class); + + Properties expected = new Properties(); + expected.setProperty("id", "1234"); + expected.setProperty("path", "path:1234"); + assertEquals(output, expected); + } +} diff --git a/core/src/test/java/org/jclouds/config/BindRestContextWithWildcardExtendsExplicitAndRawTypeTest.java b/core/src/test/java/org/jclouds/config/BindRestContextWithWildcardExtendsExplicitAndRawTypeTest.java new file mode 100644 index 0000000000..59e201b13c --- /dev/null +++ b/core/src/test/java/org/jclouds/config/BindRestContextWithWildcardExtendsExplicitAndRawTypeTest.java @@ -0,0 +1,127 @@ +/** + * 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.config; + +import static org.easymock.EasyMock.createMock; +import static org.testng.Assert.assertEquals; + +import javax.inject.Inject; + +import org.jclouds.domain.Credentials; +import org.jclouds.http.IntegrationTestAsyncClient; +import org.jclouds.http.IntegrationTestClient; +import org.jclouds.providers.AnonymousProviderMetadata; +import org.jclouds.providers.ProviderMetadata; +import org.jclouds.providers.config.BindProviderMetadataContextAndCredentials; +import org.jclouds.rest.RestApiMetadata; +import org.jclouds.rest.RestContext; +import org.jclouds.rest.Utils; +import org.jclouds.rest.internal.BaseRestClientTest.MockModule; +import org.testng.annotations.Test; + +import com.google.common.reflect.TypeToken; +import com.google.inject.AbstractModule; +import com.google.inject.Guice; +import com.google.inject.Injector; + +/** + * + * @author Adrian Cole + */ +@Test(groups = "unit", testName = "BindRestContextWithWildcardExtendsExplicitAndRawTypeTest") +public class BindRestContextWithWildcardExtendsExplicitAndRawTypeTest { + + @SuppressWarnings( { "unused", "unchecked" }) + private static class ExpectedBindings { + + private final RestContext raw; + private final RestContext explicit; + + @Inject + public ExpectedBindings(RestContext raw, + RestContext explicit) { + this.raw = raw; + this.explicit = explicit; + } + + } + + @Test + public void testRawAndExplicit() { + ProviderMetadata md = AnonymousProviderMetadata.forClientMappedToAsyncClientOnEndpoint( + IntegrationTestClient.class, IntegrationTestAsyncClient.class, "http://localhost"); + + ExpectedBindings bindings = injectorFor(md).getInstance(ExpectedBindings.class); + assertEquals(bindings.raw, bindings.explicit); + } + + private Injector injectorFor(ProviderMetadata md) { + return Guice.createInjector( + new BindProviderMetadataContextAndCredentials(md, new Credentials("user", "pass")), + new BindRestContextWithWildcardExtendsExplicitAndRawType(RestApiMetadata.class.cast(md + .getApiMetadata())), + + // stuff needed for RestContextImpl + new MockModule(), + new AbstractModule() { + + @Override + protected void configure() { + bind(Utils.class).toInstance(createMock(Utils.class)); + bind(IntegrationTestClient.class).toInstance(createMock(IntegrationTestClient.class)); + bind(IntegrationTestAsyncClient.class).toInstance(createMock(IntegrationTestAsyncClient.class)); + } + }); + } + + @SuppressWarnings( { "unused", "unchecked" }) + private static class ExpectedBindingsWithWildCardExtends { + + private final RestContext raw; + private final RestContext explicit; + private final RestContext wildcardExtends; + + @Inject + public ExpectedBindingsWithWildCardExtends(RestContext raw, + RestContext explicit, + RestContext wildcardExtends) { + this.raw = raw; + this.explicit = explicit; + this.wildcardExtends = wildcardExtends; + } + + } + + @SuppressWarnings("unchecked") + @Test + public void testRawExplicitAndWildCardExtends() { + ProviderMetadata md = AnonymousProviderMetadata.forClientMappedToAsyncClientOnEndpoint( + IntegrationTestClient.class, IntegrationTestAsyncClient.class, "http://localhost"); + + TypeToken wildCardExtendsType = new TypeToken>() { + private static final long serialVersionUID = -8170268554700397860L; + }; + + md = md.toBuilder().apiMetadata(md.getApiMetadata().toBuilder().context(wildCardExtendsType).build()).build(); + + ExpectedBindingsWithWildCardExtends bindings = injectorFor(md).getInstance(ExpectedBindingsWithWildCardExtends.class); + assertEquals(bindings.raw, bindings.explicit); + assertEquals(bindings.explicit, bindings.wildcardExtends); + } +} diff --git a/core/src/test/java/org/jclouds/config/ValueOfConfigurationKeyOrNullTest.java b/core/src/test/java/org/jclouds/config/ValueOfConfigurationKeyOrNullTest.java index 1af174d9f0..53c8000b82 100644 --- a/core/src/test/java/org/jclouds/config/ValueOfConfigurationKeyOrNullTest.java +++ b/core/src/test/java/org/jclouds/config/ValueOfConfigurationKeyOrNullTest.java @@ -20,8 +20,6 @@ package org.jclouds.config; import static org.testng.Assert.assertEquals; -import java.util.concurrent.ExecutionException; - import org.testng.annotations.Test; import com.google.inject.AbstractModule; @@ -37,12 +35,12 @@ import com.google.inject.name.Names; public class ValueOfConfigurationKeyOrNullTest { @Test - public void testNotThere() throws InterruptedException, ExecutionException { + public void testNotThere() { assertEquals(new ValueOfConfigurationKeyOrNull(Guice.createInjector()).apply("foo"), null); } @Test - public void testThere() throws InterruptedException, ExecutionException { + public void testThere() { assertEquals(new ValueOfConfigurationKeyOrNull(Guice.createInjector(new AbstractModule() { @Override @@ -53,5 +51,17 @@ public class ValueOfConfigurationKeyOrNullTest { })).apply("foo"), "bar"); } + + @Test + public void testEmptyIsThere() { + assertEquals(new ValueOfConfigurationKeyOrNull(Guice.createInjector(new AbstractModule() { + @Override + protected void configure() { + bindConstant().annotatedWith(Names.named("foo")).to(""); + } + + })).apply("foo"), ""); + + } } 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 5deafb7df6..5992ca7293 100644 --- a/core/src/test/java/org/jclouds/events/config/EventBusModuleTest.java +++ b/core/src/test/java/org/jclouds/events/config/EventBusModuleTest.java @@ -40,9 +40,8 @@ import com.google.inject.name.Names; * * @author Ignasi Barrera */ -@Test(groups = "unit") -public class EventBusModuleTest -{ +@Test(groups = "unit", testName = "EventBusModuleTest") +public class EventBusModuleTest { private Injector injector; @BeforeMethod diff --git a/core/src/test/java/org/jclouds/internal/BaseWrapperTest.java b/core/src/test/java/org/jclouds/internal/BaseViewTest.java similarity index 61% rename from core/src/test/java/org/jclouds/internal/BaseWrapperTest.java rename to core/src/test/java/org/jclouds/internal/BaseViewTest.java index ebda6dfbbe..506899d066 100644 --- a/core/src/test/java/org/jclouds/internal/BaseWrapperTest.java +++ b/core/src/test/java/org/jclouds/internal/BaseViewTest.java @@ -18,12 +18,14 @@ */ package org.jclouds.internal; +import static org.easymock.EasyMock.createMock; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertFalse; import static org.testng.Assert.assertNotEquals; -import java.io.Closeable; - +import org.jclouds.lifecycle.Closer; +import org.jclouds.providers.ProviderMetadata; +import org.jclouds.rest.Utils; import org.testng.annotations.Test; import com.google.common.base.Objects; @@ -32,26 +34,41 @@ import com.google.common.reflect.TypeToken; /** * @author Adrian Cole */ -@Test(groups = "unit", testName = "BaseWrapperTest") -public class BaseWrapperTest { - private static class Water implements Closeable { +@Test(groups = "unit", testName = "BaseViewTest") +public class BaseViewTest { + private static class Water extends ContextImpl { + + protected Water() { + super(createMock(ProviderMetadata.class), "identity", createMock(Utils.class), createMock(Closer.class)); + } @Override public void close() { } + @Override public boolean equals(Object in){ return Objects.equal(in.getClass(), getClass()); } } - private static interface PeanutButter extends Closeable { + private static class PeanutButter extends ContextImpl { + + protected PeanutButter() { + super(createMock(ProviderMetadata.class), "identity", createMock(Utils.class), createMock(Closer.class)); + } @Override - void close(); + public void close() { + } + + @Override + public boolean equals(Object in){ + return Objects.equal(in.getClass(), getClass()); + } } - - private static class Wine extends BaseWrapper { + + private static class Wine extends BaseView { protected Wine() { super(new Water(), TypeToken.of(Water.class)); @@ -60,19 +77,19 @@ public class BaseWrapperTest { public void testWaterTurnedIntoWine() { Wine wine = new Wine(); - assertEquals(wine.getWrappedType(), TypeToken.of(Water.class)); + assertEquals(wine.getBackendType(), TypeToken.of(Water.class)); assertEquals(wine.unwrap(TypeToken.of(Water.class)), new Water()); assertEquals(wine.unwrap(), new Water()); } public void testPeanutButterDidntTurnIntoWine() { Wine wine = new Wine(); - assertNotEquals(wine.getWrappedType(), TypeToken.of(PeanutButter.class)); + assertNotEquals(wine.getBackendType(), TypeToken.of(PeanutButter.class)); try { wine.unwrap(TypeToken.of(PeanutButter.class)); assertFalse(true); } catch (IllegalArgumentException e) { - assertEquals(e.getMessage(), "wrapped type: org.jclouds.internal.BaseWrapperTest$Water not assignable from org.jclouds.internal.BaseWrapperTest$PeanutButter"); + assertEquals(e.getMessage(), "backend type: org.jclouds.internal.BaseViewTest$Water not assignable from org.jclouds.internal.BaseViewTest$PeanutButter"); } } diff --git a/core/src/test/java/org/jclouds/location/functions/RegionToEndpointTest.java b/core/src/test/java/org/jclouds/location/functions/RegionToEndpointTest.java new file mode 100644 index 0000000000..7c0e015a7f --- /dev/null +++ b/core/src/test/java/org/jclouds/location/functions/RegionToEndpointTest.java @@ -0,0 +1,68 @@ +/** + * 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.location.functions; + +import static org.testng.Assert.assertEquals; + +import java.io.File; +import java.net.URI; +import java.util.Map; + +import org.testng.annotations.Test; + +import com.google.common.base.Supplier; +import com.google.common.base.Suppliers; +import com.google.common.collect.ImmutableMap; + +/** + * Tests behavior of {@code RegionToEndpoint} + * + * @author Adrian Cole + */ +@Test(groups = "unit", testName = "RegionToEndpointTest") +public class RegionToEndpointTest { + + @Test + public void testCorrect() { + RegionToEndpoint fn = new RegionToEndpoint(Suppliers.>> ofInstance(ImmutableMap.of("1", + Suppliers.ofInstance(URI.create("http://1"))))); + assertEquals(fn.apply("1"), URI.create("http://1")); + } + + @Test(expectedExceptions = IllegalArgumentException.class) + public void testMustBeString() { + RegionToEndpoint fn = new RegionToEndpoint(Suppliers.>> ofInstance(ImmutableMap.of("1", + Suppliers.ofInstance(URI.create("http://1"))))); + fn.apply(new File("foo")); + } + + @Test(expectedExceptions = IllegalStateException.class) + public void testMustHaveEndpoints() { + RegionToEndpoint fn = new RegionToEndpoint(Suppliers.>> ofInstance(ImmutableMap + .> of())); + fn.apply("1"); + } + + @Test(expectedExceptions = IllegalArgumentException.class) + public void testNullIsIllegal() { + RegionToEndpoint fn = new RegionToEndpoint(Suppliers.>> ofInstance(ImmutableMap.of("1", + Suppliers.ofInstance(URI.create("http://1"))))); + fn.apply(null); + } +} diff --git a/core/src/test/java/org/jclouds/providers/ProvidersTest.java b/core/src/test/java/org/jclouds/providers/ProvidersTest.java index 465421ee62..0432219b99 100644 --- a/core/src/test/java/org/jclouds/providers/ProvidersTest.java +++ b/core/src/test/java/org/jclouds/providers/ProvidersTest.java @@ -63,13 +63,13 @@ public class ProvidersTest { @Test public void testTransformableTo() { - Iterable providersMetadata = Providers.contextWrappableAs(Storage.class); + Iterable providersMetadata = Providers.viewableAs(Storage.class); for (ProviderMetadata providerMetadata : providersMetadata) { assertEquals(testBlobstoreProvider, providerMetadata); } - providersMetadata = Providers.contextWrappableAs(Compute.class); + providersMetadata = Providers.viewableAs(Compute.class); for (ProviderMetadata providerMetadata : providersMetadata) { if (providerMetadata.getName().equals(testComputeProvider.getName())) { @@ -79,7 +79,7 @@ public class ProvidersTest { } } - providersMetadata = Providers.contextWrappableAs(Balancer.class); + providersMetadata = Providers.viewableAs(Balancer.class); assertEquals(false, providersMetadata.iterator().hasNext()); } diff --git a/core/src/test/java/org/jclouds/providers/config/BindProviderMetadataContextAndCredentialsTest.java b/core/src/test/java/org/jclouds/providers/config/BindProviderMetadataContextAndCredentialsTest.java new file mode 100644 index 0000000000..8a345016f9 --- /dev/null +++ b/core/src/test/java/org/jclouds/providers/config/BindProviderMetadataContextAndCredentialsTest.java @@ -0,0 +1,163 @@ +/** + * 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.providers.config; + +import static org.testng.Assert.assertEquals; + +import java.util.Properties; +import java.util.Set; + +import javax.inject.Inject; + +import org.jclouds.Constants; +import org.jclouds.Context; +import org.jclouds.apis.ApiMetadata; +import org.jclouds.domain.Credentials; +import org.jclouds.domain.LoginCredentials; +import org.jclouds.http.IntegrationTestAsyncClient; +import org.jclouds.http.IntegrationTestClient; +import org.jclouds.internal.FilterStringsBoundToInjectorByName; +import org.jclouds.javax.annotation.Nullable; +import org.jclouds.location.Iso3166; +import org.jclouds.location.Provider; +import org.jclouds.providers.AnonymousProviderMetadata; +import org.jclouds.providers.ProviderMetadata; +import org.jclouds.rest.annotations.Api; +import org.jclouds.rest.annotations.ApiVersion; +import org.jclouds.rest.annotations.BuildVersion; +import org.jclouds.rest.annotations.Credential; +import org.jclouds.rest.annotations.Identity; +import org.testng.annotations.Test; + +import com.google.common.base.Predicates; +import com.google.common.reflect.TypeToken; +import com.google.inject.Guice; +import com.google.inject.Key; +import com.google.inject.name.Names; + +/** + * + * @author Adrian Cole + */ +@Test(groups = "unit", testName = "BindProviderMetadataContextAndCredentialsTest") +public class BindProviderMetadataContextAndCredentialsTest { + + @SuppressWarnings("unused") + private static class ExpectedBindings { + private final javax.inject.Provider backend; + private final ProviderMetadata providerMetadata; + private final Credentials creds; + private final String identity; + private final String credential; + private final String providerId; + private final Set iso3166Codes; + private final String apiId; + private final String apiVersion; + private final String buildVersion; + + @Inject + private ExpectedBindings(@Provider javax.inject.Provider backend, ProviderMetadata providerMetadata, + @Provider Credentials creds, @Identity String identity, @Nullable @Credential String credential, + @Provider String providerId, @Iso3166 Set iso3166Codes, @Api String apiId, + @ApiVersion String apiVersion, @Nullable @BuildVersion String buildVersion, + @Provider TypeToken backendToken, FilterStringsBoundToInjectorByName filter) { + this.backend = backend; + assertEquals(backendToken, providerMetadata.getApiMetadata().getContext()); + this.providerMetadata = providerMetadata; + Properties props = new Properties(); + props.putAll(filter.apply(Predicates. alwaysTrue())); + Properties expected = new Properties(); + expected.putAll(providerMetadata.getApiMetadata().getDefaultProperties()); + expected.putAll(providerMetadata.getDefaultProperties()); + assertEquals(props, expected); + this.creds = creds; + this.identity = identity; + assertEquals(identity, creds.identity); + this.credential = credential; + assertEquals(credential, creds.credential); + this.providerId = providerId; + assertEquals(providerId, providerMetadata.getId()); + this.iso3166Codes = iso3166Codes; + assertEquals(iso3166Codes, providerMetadata.getIso3166Codes()); + this.apiId = apiId; + assertEquals(apiId, providerMetadata.getApiMetadata().getId()); + this.apiVersion = apiVersion; + assertEquals(apiVersion, providerMetadata.getApiMetadata().getVersion()); + this.buildVersion = buildVersion; + assertEquals(buildVersion, providerMetadata.getApiMetadata().getBuildVersion().orNull()); + } + + } + + @Test + public void testExpectedBindingsWhenCredentialIsNotNull() { + + ProviderMetadata md = AnonymousProviderMetadata.forClientMappedToAsyncClientOnEndpoint( + IntegrationTestClient.class, IntegrationTestAsyncClient.class, "http://localhost"); + Credentials creds = LoginCredentials.builder().user("user").password("password").build(); + + ExpectedBindings bindings = Guice.createInjector(new BindProviderMetadataContextAndCredentials(md, creds)) + .getInstance(ExpectedBindings.class); + assertEquals(bindings.identity, "user"); + assertEquals(bindings.credential, "password"); + } + + @Test + public void testExpectedBindingsWhenCredentialIsNull() { + + ProviderMetadata md = AnonymousProviderMetadata.forClientMappedToAsyncClientOnEndpoint( + IntegrationTestClient.class, IntegrationTestAsyncClient.class, "http://localhost"); + Credentials creds = LoginCredentials.builder().user("user").build(); + + ExpectedBindings bindings = Guice.createInjector(new BindProviderMetadataContextAndCredentials(md, creds)) + .getInstance(ExpectedBindings.class); + assertEquals(bindings.identity, "user"); + assertEquals(bindings.credential, null); + } + + @Test + public void testExpectedBindingsWhenBuildVersionAbsent() { + + ProviderMetadata md = AnonymousProviderMetadata.forClientMappedToAsyncClientOnEndpoint( + IntegrationTestClient.class, IntegrationTestAsyncClient.class, "http://localhost"); + ApiMetadata apiMd = md.getApiMetadata().toBuilder().buildVersion(null).build(); + md = md.toBuilder().apiMetadata(apiMd).build(); + Credentials creds = LoginCredentials.builder().user("user").build(); + + ExpectedBindings bindings = Guice.createInjector(new BindProviderMetadataContextAndCredentials(md, creds)) + .getInstance(ExpectedBindings.class); + assertEquals(bindings.buildVersion, null); + } + + @Test + public void testProviderOverridesApiMetadataProperty() { + + ProviderMetadata md = AnonymousProviderMetadata.forClientMappedToAsyncClientOnEndpoint( + IntegrationTestClient.class, IntegrationTestAsyncClient.class, "http://localhost"); + Properties defaultProps = md.getDefaultProperties(); + defaultProps.setProperty(Constants.PROPERTY_SESSION_INTERVAL, Integer.MAX_VALUE + ""); + md = md.toBuilder().defaultProperties(defaultProps).build(); + + Credentials creds = LoginCredentials.builder().user("user").build(); + + int session = Guice.createInjector(new BindProviderMetadataContextAndCredentials(md, creds)).getInstance( + Key.get(int.class, Names.named(Constants.PROPERTY_SESSION_INTERVAL))); + assertEquals(session, Integer.MAX_VALUE); + } +} diff --git a/core/src/test/java/org/jclouds/providers/internal/BaseProviderMetadataTest.java b/core/src/test/java/org/jclouds/providers/internal/BaseProviderMetadataTest.java index 70d0e1d412..96cef94607 100644 --- a/core/src/test/java/org/jclouds/providers/internal/BaseProviderMetadataTest.java +++ b/core/src/test/java/org/jclouds/providers/internal/BaseProviderMetadataTest.java @@ -24,7 +24,7 @@ import static org.testng.Assert.assertEquals; import java.util.Set; import java.util.logging.Logger; -import org.jclouds.Wrapper; +import org.jclouds.View; import org.jclouds.apis.ApiMetadata; import org.jclouds.providers.ProviderMetadata; import org.jclouds.providers.Providers; @@ -42,12 +42,12 @@ public abstract class BaseProviderMetadataTest { private final ProviderMetadata toTest; private final ApiMetadata expectedApi; - private final Set> wrappers; + private final Set> views; public BaseProviderMetadataTest(ProviderMetadata toTest, ApiMetadata expectedApi) { this.toTest = checkNotNull(toTest, "toTest must be defined"); this.expectedApi = checkNotNull(expectedApi, "expectedApi must be defined"); - this.wrappers = expectedApi.getWrappers(); + this.views = expectedApi.getViews(); } @Test @@ -68,10 +68,10 @@ public abstract class BaseProviderMetadataTest { @Test public void testTransformableToContains() { - for (TypeToken wrapper : wrappers) { - ImmutableSet ofType = ImmutableSet.copyOf(Providers.contextWrappableAs(wrapper)); + for (TypeToken view : views) { + ImmutableSet ofType = ImmutableSet.copyOf(Providers.viewableAs(view)); assert ofType.contains(toTest) : String.format("%s not found in %s for %s", toTest, ofType, - wrapper); + view); } } diff --git a/core/src/test/java/org/jclouds/providers/internal/UpdateProviderMetadataFromPropertiesTest.java b/core/src/test/java/org/jclouds/providers/internal/UpdateProviderMetadataFromPropertiesTest.java new file mode 100644 index 0000000000..cebe3ba45d --- /dev/null +++ b/core/src/test/java/org/jclouds/providers/internal/UpdateProviderMetadataFromPropertiesTest.java @@ -0,0 +1,73 @@ +/** + * 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.providers.internal; + +import static org.jclouds.Constants.PROPERTY_ISO3166_CODES; +import static org.testng.Assert.assertEquals; + +import java.util.Properties; + +import org.jclouds.Constants; +import org.jclouds.http.IntegrationTestAsyncClient; +import org.jclouds.http.IntegrationTestClient; +import org.jclouds.providers.AnonymousProviderMetadata; +import org.jclouds.providers.ProviderMetadata; +import org.testng.annotations.Test; + +import com.google.common.collect.ImmutableSet; + +/** + * + * @author Adrian Cole + */ +@Test(groups = "unit", testName = "UpdateProviderMetadataFromPropertiesTest") +public class UpdateProviderMetadataFromPropertiesTest { + + @Test + public void testProviderMetadataWithUpdatedEndpointUpdatesAndRetainsAllDefaultPropertiesExceptEndpoint() { + ProviderMetadata md = AnonymousProviderMetadata.forClientMappedToAsyncClientOnEndpoint( + IntegrationTestClient.class, IntegrationTestAsyncClient.class, "http://localhost"); + + Properties props = new Properties(); + props.putAll(md.getDefaultProperties()); + props.setProperty(Constants.PROPERTY_ENDPOINT, "http://nonlocal"); + + ProviderMetadata newMd = new UpdateProviderMetadataFromProperties(md).apply(props); + + assertEquals(newMd.getEndpoint(), "http://nonlocal"); + assertEquals(newMd.getDefaultProperties(), md.getDefaultProperties()); + } + + @Test + public void testProviderMetadataWithUpdatedIso3166CodesUpdatesAndRetainsAllDefaultPropertiesExceptIso3166Codes() { + ProviderMetadata md = AnonymousProviderMetadata.forClientMappedToAsyncClientOnEndpoint( + IntegrationTestClient.class, IntegrationTestAsyncClient.class, "http://localhost"); + + Properties props = new Properties(); + props.putAll(md.getDefaultProperties()); + props.setProperty(PROPERTY_ISO3166_CODES, "US-CA"); + + ProviderMetadata newMd = new UpdateProviderMetadataFromProperties(md).apply(props); + + assertEquals(newMd.getIso3166Codes(), ImmutableSet.of("US-CA")); + assertEquals(newMd.getDefaultProperties(), md.getDefaultProperties()); + } + + //TODO: add all the rest of the tests +} diff --git a/core/src/test/java/org/jclouds/rest/internal/BaseRestApiMetadataTest.java b/core/src/test/java/org/jclouds/rest/internal/BaseRestApiMetadataTest.java index 702e9fe873..e16a760c28 100644 --- a/core/src/test/java/org/jclouds/rest/internal/BaseRestApiMetadataTest.java +++ b/core/src/test/java/org/jclouds/rest/internal/BaseRestApiMetadataTest.java @@ -20,7 +20,7 @@ package org.jclouds.rest.internal; import java.util.Set; -import org.jclouds.Wrapper; +import org.jclouds.View; import org.jclouds.apis.ApiMetadata; import org.jclouds.apis.Apis; import org.jclouds.apis.internal.BaseApiMetadataTest; @@ -38,8 +38,8 @@ import com.google.common.reflect.TypeToken; @Test(groups = "unit") public abstract class BaseRestApiMetadataTest extends BaseApiMetadataTest { - public BaseRestApiMetadataTest(RestApiMetadata toTest, Set> wrappers) { - super(toTest, wrappers); + public BaseRestApiMetadataTest(RestApiMetadata toTest, Set> views) { + super(toTest, views); } @Test 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 bf21b33c32..f4a5b6439d 100644 --- a/core/src/test/java/org/jclouds/rest/internal/RestAnnotationProcessorTest.java +++ b/core/src/test/java/org/jclouds/rest/internal/RestAnnotationProcessorTest.java @@ -939,7 +939,7 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest { @Path("/{foo}") @MapBinder(BindToJsonPayload.class) @Consumes(MediaType.APPLICATION_JSON) - Wrapper putWithMethodBinderConsumes(@PathParam("foo") @PayloadParam("fooble") String path); + View putWithMethodBinderConsumes(@PathParam("foo") @PayloadParam("fooble") String path); @GET @Path("/") @@ -1017,7 +1017,7 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest { ListenableFuture rowdy(@PathParam("id") int path); } - static class Wrapper { + static class View { String foo; } @@ -1069,7 +1069,7 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest { assertResponseParserClassEquals(method, request, ParseJson.class); // now test that it works! - Function parser = (Function) RestAnnotationProcessor + Function parser = (Function) RestAnnotationProcessor .createResponseParser(parserFactory, injector, method, request); assertEquals(parser.apply(new HttpResponse(200, "ok", newStringPayload("{ foo:\"bar\"}"))).foo, "bar"); diff --git a/core/src/test/java/org/jclouds/util/Maps2Test.java b/core/src/test/java/org/jclouds/util/Maps2Test.java index d0f3cbf1fd..8c52536fa7 100644 --- a/core/src/test/java/org/jclouds/util/Maps2Test.java +++ b/core/src/test/java/org/jclouds/util/Maps2Test.java @@ -31,6 +31,7 @@ import org.testng.annotations.Test; import com.google.common.base.Function; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Lists; import com.google.common.collect.Maps; /** @@ -86,4 +87,18 @@ public class Maps2Test { }), expected); } + @Test + public void testCovariantUniqueIndex() { + Iterable values = Lists.newArrayList(1, 2, 3, 4, 5); + Map map = Maps2.uniqueIndex(values, new Function() { + + @Override + public Double apply(Object input) { + return (Integer)input + 0.1; + } + }); + + assertEquals(map.get(1.1), 1); + } + } diff --git a/core/src/test/java/org/jclouds/util/ProvidersTest.java b/core/src/test/java/org/jclouds/util/ProvidersTest.java index 81ee659d3f..b265eb4f0c 100644 --- a/core/src/test/java/org/jclouds/util/ProvidersTest.java +++ b/core/src/test/java/org/jclouds/util/ProvidersTest.java @@ -32,6 +32,7 @@ import com.google.common.collect.Sets; public class ProvidersTest { @Test + @Deprecated public void testSupportedProviders() { Iterable providers = org.jclouds.rest.Providers.getSupportedProviders(); assertEquals(Sets.newLinkedHashSet(providers), ImmutableSet. of("test-blobstore-api", "test-compute-api", diff --git a/labs/elb/src/main/java/org/jclouds/elb/ELBApiMetadata.java b/labs/elb/src/main/java/org/jclouds/elb/ELBApiMetadata.java index 53ed7685f9..31dc402184 100644 --- a/labs/elb/src/main/java/org/jclouds/elb/ELBApiMetadata.java +++ b/labs/elb/src/main/java/org/jclouds/elb/ELBApiMetadata.java @@ -81,7 +81,7 @@ public class ELBApiMetadata extends BaseRestApiMetadata { .defaultProperties(ELBApiMetadata.defaultProperties()) .defaultEndpoint("https://elasticloadbalancing.us-east-1.amazonaws.com") .documentation(URI.create("http://docs.amazonwebservices.com/ElasticLoadBalancing/latest/APIReference")) - .wrapper(LoadBalancerServiceContext.class) + .view(LoadBalancerServiceContext.class) .defaultModules(ImmutableSet.>of(ELBRestClientModule.class, ELBLoadBalancerContextModule.class)); } diff --git a/labs/glesys/src/main/java/org/jclouds/glesys/GleSYSApiMetadata.java b/labs/glesys/src/main/java/org/jclouds/glesys/GleSYSApiMetadata.java index a258b0a973..7dbfcf25c0 100644 --- a/labs/glesys/src/main/java/org/jclouds/glesys/GleSYSApiMetadata.java +++ b/labs/glesys/src/main/java/org/jclouds/glesys/GleSYSApiMetadata.java @@ -80,7 +80,7 @@ public class GleSYSApiMetadata extends BaseRestApiMetadata { .version("1") .defaultEndpoint("https://api.glesys.com") .defaultProperties(GleSYSApiMetadata.defaultProperties()) - .wrapper(TypeToken.of(ComputeServiceContext.class)) + .view(TypeToken.of(ComputeServiceContext.class)) .defaultModules(ImmutableSet.>of(GleSYSComputeServiceContextModule.class, GleSYSRestClientModule.class)); } diff --git a/labs/glesys/src/main/java/org/jclouds/glesys/functions/ParseTemplatesFromHttpResponse.java b/labs/glesys/src/main/java/org/jclouds/glesys/functions/ParseTemplatesFromHttpResponse.java index be87e2adfd..c03f109e27 100644 --- a/labs/glesys/src/main/java/org/jclouds/glesys/functions/ParseTemplatesFromHttpResponse.java +++ b/labs/glesys/src/main/java/org/jclouds/glesys/functions/ParseTemplatesFromHttpResponse.java @@ -44,9 +44,9 @@ public class ParseTemplatesFromHttpResponse implements Function>> parser; @Inject - public ParseTemplatesFromHttpResponse(GsonWrapper gsonWrapper) { - this.parser = new ParseFirstJsonValueNamed>>(checkNotNull(gsonWrapper, - "gsonWrapper"), new TypeLiteral>>() { + public ParseTemplatesFromHttpResponse(GsonWrapper gsonView) { + this.parser = new ParseFirstJsonValueNamed>>(checkNotNull(gsonView, + "gsonView"), new TypeLiteral>>() { }, "templates"); } diff --git a/labs/glesys/src/test/java/org/jclouds/glesys/compute/GleSYSTemplateBuilderLiveTest.java b/labs/glesys/src/test/java/org/jclouds/glesys/compute/GleSYSTemplateBuilderLiveTest.java index 5f5844e624..918aed8a49 100644 --- a/labs/glesys/src/test/java/org/jclouds/glesys/compute/GleSYSTemplateBuilderLiveTest.java +++ b/labs/glesys/src/test/java/org/jclouds/glesys/compute/GleSYSTemplateBuilderLiveTest.java @@ -81,7 +81,7 @@ public class GleSYSTemplateBuilderLiveTest extends BaseTemplateBuilderLiveTest { @Test public void testDefaultTemplateBuilder() throws IOException { - Template defaultTemplate = context.getComputeService().templateBuilder().build(); + Template defaultTemplate = view.getComputeService().templateBuilder().build(); assertEquals(defaultTemplate.getImage().getId(), "Ubuntu 11.04 64-bit"); assertEquals(defaultTemplate.getImage().getOperatingSystem().getVersion(), "11.04"); assertEquals(defaultTemplate.getImage().getOperatingSystem().is64Bit(), true); diff --git a/labs/glesys/src/test/java/org/jclouds/glesys/internal/BaseGleSYSClientLiveTest.java b/labs/glesys/src/test/java/org/jclouds/glesys/internal/BaseGleSYSClientLiveTest.java index 9c826505a0..8db9fff181 100644 --- a/labs/glesys/src/test/java/org/jclouds/glesys/internal/BaseGleSYSClientLiveTest.java +++ b/labs/glesys/src/test/java/org/jclouds/glesys/internal/BaseGleSYSClientLiveTest.java @@ -61,7 +61,7 @@ public class BaseGleSYSClientLiveTest extends BaseComputeServiceContextLiveTest @Override public void setupContext() { super.setupContext(); - gleContext = context.unwrap(); + gleContext = view.unwrap(); } protected void createDomain(String domain) { diff --git a/labs/nodepool/pom.xml b/labs/nodepool/pom.xml new file mode 100644 index 0000000000..403658b301 --- /dev/null +++ b/labs/nodepool/pom.xml @@ -0,0 +1,93 @@ + + + 4.0.0 + + jclouds-project + org.jclouds + 1.5.0-SNAPSHOT + ../../project/pom.xml + + org.jclouds.labs + nodepool + jclouds nodepool + bundle + + UTF-8 + 0.1.46 + ${test.aws.identity} + ${test.aws.credential} + + + + org.jclouds + jclouds-compute + ${project.version} + + + org.jclouds + jclouds-core + ${project.version} + test-jar + test + + + org.jclouds + jclouds-compute + ${project.version} + test-jar + test + + + org.jclouds.provider + aws-ec2 + ${project.version} + test + + + org.jclouds.driver + jclouds-enterprise + ${project.version} + test + + + org.jclouds.driver + jclouds-sshj + ${project.version} + test + + + org.jclouds + jclouds-scriptbuilder + ${project.version} + test + + + org.jclouds.driver + jclouds-jsch + ${project.version} + test + + + com.jcraft + jsch + test + + + + + + org.apache.felix + maven-bundle-plugin + + + ${project.artifactId} + org.jclouds.nodepool*;version="${project.version}" + org.jclouds*;version="${project.version}",* + + + + + + + diff --git a/labs/nodepool/src/main/java/org/jclouds/nodepool/PooledComputeService.java b/labs/nodepool/src/main/java/org/jclouds/nodepool/PooledComputeService.java new file mode 100644 index 0000000000..771a1bef9e --- /dev/null +++ b/labs/nodepool/src/main/java/org/jclouds/nodepool/PooledComputeService.java @@ -0,0 +1,28 @@ +/** + * 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.nodepool; + +import org.jclouds.compute.ComputeService; +import org.jclouds.compute.RunNodesException; + +public interface PooledComputeService extends ComputeService { + + void startPool() throws RunNodesException; + +} diff --git a/labs/nodepool/src/main/java/org/jclouds/nodepool/internal/BasePooledComputeService.java b/labs/nodepool/src/main/java/org/jclouds/nodepool/internal/BasePooledComputeService.java new file mode 100644 index 0000000000..725be05e85 --- /dev/null +++ b/labs/nodepool/src/main/java/org/jclouds/nodepool/internal/BasePooledComputeService.java @@ -0,0 +1,270 @@ +/** + * 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.nodepool.internal; + +import java.util.Map; +import java.util.Set; + +import org.jclouds.compute.ComputeService; +import org.jclouds.compute.ComputeServiceContext; +import org.jclouds.compute.ImageExtension; +import org.jclouds.compute.RunNodesException; +import org.jclouds.compute.RunScriptOnNodesException; +import org.jclouds.compute.domain.ComputeMetadata; +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.NodeMetadataBuilder; +import org.jclouds.compute.domain.Template; +import org.jclouds.compute.domain.TemplateBuilder; +import org.jclouds.compute.options.RunScriptOptions; +import org.jclouds.compute.options.TemplateOptions; +import org.jclouds.domain.Location; +import org.jclouds.nodepool.PooledComputeService; +import org.jclouds.scriptbuilder.domain.Statement; + +import com.google.common.base.Optional; +import com.google.common.base.Predicate; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; +import com.google.common.util.concurrent.ListenableFuture; + +public class BasePooledComputeService implements PooledComputeService { + + private final ComputeService backingComputeService; + private final String backingGroup; + private final Template backingTemplate; + private final int minPoolSize; + private Map groupMapping; + + public BasePooledComputeService(ComputeService backingComputeService, String backingGroup, Template backingTemplate, int minPoolSize) { + this.backingComputeService = backingComputeService; + this.backingGroup = backingGroup; + this.backingTemplate = backingTemplate; + this.minPoolSize = minPoolSize; + } + + @Override + public void startPool() throws RunNodesException { + Set backingNodes = + backingComputeService.createNodesInGroup(backingGroup, minPoolSize, backingTemplate); + groupMapping = Maps.newHashMap(); + for (NodeMetadata node : backingNodes) { + groupMapping.put(node, "unassigned"); + } + } + + @Override + public ComputeServiceContext getContext() { + return backingComputeService.getContext(); + } + + @Override + public TemplateBuilder templateBuilder() { + return backingComputeService.templateBuilder(); + } + + @Override + public TemplateOptions templateOptions() { + return backingComputeService.templateOptions(); + } + + @Override + public Set listHardwareProfiles() { + return ImmutableSet.of(backingTemplate.getHardware()); + } + + @Override + public Set listImages() { + return ImmutableSet.of(backingTemplate.getImage()); + } + + @Override + public Set listNodes() { + Set allocatedNodes = Sets.newLinkedHashSet(); + for (ComputeMetadata node : backingComputeService.listNodes()) { + NodeMetadata metadata = backingComputeService.getNodeMetadata(node.getId()); + String group = groupMapping.get(node); + if ("unassigned".equals(group)) + continue; + NodeMetadata nodeWithUpdatedGroup = + NodeMetadataBuilder.fromNodeMetadata(metadata).group(group).build(); + allocatedNodes.add(nodeWithUpdatedGroup); + } + return allocatedNodes; + } + + @Override + public Set listAssignableLocations() { + return ImmutableSet.of(backingTemplate.getLocation()); + } + + @Override + public Set createNodesInGroup(String group, + int count, Template template) throws RunNodesException { + throw new RuntimeException("not implemented"); + } + + @Override + public Set createNodesInGroup(String group, + int count, TemplateOptions templateOptions) + throws RunNodesException { + throw new RuntimeException("not implemented"); + } + + @Override + public Set createNodesInGroup(String group, + int count) throws RunNodesException { + int allocatedCount = 0; + Set allocatedNodes = Sets.newLinkedHashSet(); + for (NodeMetadata metadata : groupMapping.keySet()) { + if (groupMapping.get(metadata).equals("unassigned")) { + groupMapping.put(metadata, "group"); + NodeMetadata nodeWithUpdatedGroup = + NodeMetadataBuilder.fromNodeMetadata(metadata).group(group).build(); + allocatedNodes.add(nodeWithUpdatedGroup); + allocatedCount += 1; + if (allocatedCount == count) break; + } + } + return allocatedNodes; + } + + @Override + public void resumeNode(String id) { + backingComputeService.resumeNode(id); + + } + + @Override + public void resumeNodesMatching(Predicate filter) { + backingComputeService.resumeNodesMatching(filter); + + } + + @Override + public void suspendNode(String id) { + backingComputeService.suspendNode(id); + } + + @Override + public void suspendNodesMatching(Predicate filter) { + backingComputeService.suspendNodesMatching(filter); + } + + @Override + public void destroyNode(String id) { + + backingComputeService.destroyNode(id); + } + + @Override + public Set destroyNodesMatching( + Predicate filter) { + return backingComputeService.destroyNodesMatching(filter); + } + + @Override + public void rebootNode(String id) { + backingComputeService.rebootNode(id); + + } + + @Override + public void rebootNodesMatching(Predicate filter) { + backingComputeService.rebootNodesMatching(filter); + + } + + @Override + public NodeMetadata getNodeMetadata(String id) { + return backingComputeService.getNodeMetadata(id); + } + + @Override + public Set listNodesDetailsMatching( + Predicate filter) { + return backingComputeService.listNodesDetailsMatching(filter); + } + + @Override + public Map runScriptOnNodesMatching( + Predicate filter, String runScript) + throws RunScriptOnNodesException { + // TODO Auto-generated method stub + return backingComputeService.runScriptOnNodesMatching(filter, runScript); + } + + @Override + public Map runScriptOnNodesMatching( + Predicate filter, Statement runScript) + throws RunScriptOnNodesException { + return backingComputeService.runScriptOnNodesMatching(filter, runScript); + } + + @Override + public Map runScriptOnNodesMatching( + Predicate filter, String runScript, + RunScriptOptions options) throws RunScriptOnNodesException { + return backingComputeService.runScriptOnNodesMatching(filter, runScript, options); + } + + @Override + public Map runScriptOnNodesMatching( + Predicate filter, Statement runScript, + RunScriptOptions options) throws RunScriptOnNodesException { + return backingComputeService.runScriptOnNodesMatching(filter, runScript, options); + } + + @Override + public ExecResponse runScriptOnNode(String id, Statement runScript, + RunScriptOptions options) { + return backingComputeService.runScriptOnNode(id, runScript, options); + } + + @Override + public ListenableFuture submitScriptOnNode(String id, + Statement runScript, RunScriptOptions options) { + return backingComputeService.submitScriptOnNode(id, runScript, options); + } + + @Override + public ExecResponse runScriptOnNode(String id, Statement runScript) { + return backingComputeService.runScriptOnNode(id, runScript); + } + + @Override + public ExecResponse runScriptOnNode(String id, String runScript, + RunScriptOptions options) { + return backingComputeService.runScriptOnNode(id, runScript, options); + } + + @Override + public ExecResponse runScriptOnNode(String id, String runScript) { + return backingComputeService.runScriptOnNode(id, runScript); + } + + @Override + public Optional getImageExtension() { + return Optional.absent(); + } + +} diff --git a/labs/nodepool/src/test/java/org/jclouds/nodepool/AppTest.java b/labs/nodepool/src/test/java/org/jclouds/nodepool/AppTest.java new file mode 100644 index 0000000000..7977cc8e58 --- /dev/null +++ b/labs/nodepool/src/test/java/org/jclouds/nodepool/AppTest.java @@ -0,0 +1,287 @@ +/** + * 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.nodepool; + +import static com.google.common.base.Throwables.propagate; +import static com.google.common.collect.Iterables.getOnlyElement; +import static org.jclouds.scriptbuilder.domain.Statements.newStatementList; + +import java.io.File; +import java.util.Collection; +import java.util.LinkedList; +import java.util.Map; +import java.util.Properties; +import java.util.logging.Logger; + +import junit.framework.TestCase; + +import org.jclouds.Constants; +import org.jclouds.ContextBuilder; +import org.jclouds.compute.ComputeService; +import org.jclouds.compute.ComputeServiceContext; +import org.jclouds.compute.RunNodesException; +import org.jclouds.compute.domain.ComputeMetadata; +import org.jclouds.compute.domain.NodeMetadata; +import org.jclouds.compute.domain.NodeState; +import org.jclouds.compute.domain.OsFamily; +import org.jclouds.compute.domain.Template; +import org.jclouds.compute.domain.TemplateBuilder; +import org.jclouds.enterprise.config.EnterpriseConfigurationModule; +import org.jclouds.logging.slf4j.config.SLF4JLoggingModule; +import org.jclouds.nodepool.internal.BasePooledComputeService; +import org.jclouds.scriptbuilder.domain.Statement; +import org.jclouds.scriptbuilder.domain.Statements; +import org.jclouds.scriptbuilder.statements.java.InstallJDK; +import org.jclouds.scriptbuilder.statements.login.AdminAccess; +import org.jclouds.sshj.config.SshjSshClientModule; + +import com.google.common.base.Strings; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; +import com.google.inject.Module; + +/** + * Unit test for simple App. + */ +public class AppTest extends TestCase { + private String identity; + private String credential; + private String providerName; + private File privateKey; + private File publicKey; + private String endPointUrl; + public String profile; + private int retentionTime; + public int instanceCap; + + private String imageId; + private String osFamily; + private String osVersion; + private String hardwareId; + private int ram; + private int cores; + private String initScript; + private String name; + private boolean stopOnTerminate; + private ComputeService compute; + private PooledComputeService pooledCompute; + private Collection nodes = new LinkedList(); + private static Logger LOGGER = Logger.getLogger("AppTest"); + + private long time; + + @Override + protected void setUp() throws Exception { + // setup JCloudsCloud + identity = "insert-your-identity-here"; + credential = "insert-your-credential-here"; + providerName = "aws-ec2"; + privateKey = new File("private-key"); + publicKey = new File("public-key"); + endPointUrl = ""; + profile = "aws-slave-profile"; + retentionTime = -1; + instanceCap = 3; + + // cloud instance template + name = "aws-jenkins-slave"; + // numExecutors = 1; + // description = "" + imageId = "us-east-1/ami-4dad7424"; + osFamily = ""; + osVersion = ""; + hardwareId = "t1.micro"; + ram = -1; + cores = -1; + // labels = "whii"; + initScript = "touch /tmp/hellothere"; + stopOnTerminate = true; + } + + /** + * Rigourous Test :-) + */ + public void testApp() { + createCompute(); + assertNotNull(compute); + createAndStartPool(); + assertNotNull(pooledCompute); + for (int i = 0; i < 3; i++) { + startCounter(); + provision("pool-1"); + stopCounter(); + } + for (int i = 0; i < 3; i++) { + startCounter(); + provision("pool-2"); + stopCounter(); + } + for (int i = 0; i < 3; i++) { + startCounter(); + provision("pool-3"); + stopCounter(); + } + assertEquals(9, getRunningNodesCount()); + for (NodeMetadata slave : nodes) { + assertNotNull(slave); + LOGGER.info(slave.getId() + "-" + slave.getGroup()); + terminate(slave); + } + assertEquals(0, getRunningNodesCount()); + } + + private void stopCounter() { + LOGGER.info("Elapsed time: " + (System.currentTimeMillis() - time)); + } + + private void startCounter() { + time = System.currentTimeMillis(); + } + + public AppTest getCloud() { + return this; + } + + public ComputeService getCompute() { + return pooledCompute; + } + + public NodeMetadata provision(String groupName) { + LOGGER.info("Provisioning new node"); + NodeMetadata nodeMetadata = createNodeWithJdk(groupName); + nodes.add(nodeMetadata); + return nodeMetadata; + } + + public int getRunningNodesCount() { + int nodeCount = 0; + + for (ComputeMetadata cm : pooledCompute.listNodes()) { + if (NodeMetadata.class.isInstance(cm)) { + String nodeGroup = ((NodeMetadata) cm).getGroup(); + + if (!((NodeMetadata) cm).getState().equals(NodeState.SUSPENDED) + && !((NodeMetadata) cm).getState().equals(NodeState.TERMINATED)) { + nodeCount++; + } + } + } + return nodeCount; + } + + private void createCompute() { + Properties overrides = new Properties(); + if (!Strings.isNullOrEmpty(this.endPointUrl)) { + overrides.setProperty(Constants.PROPERTY_ENDPOINT, this.endPointUrl); + } + Iterable modules = ImmutableSet. of(new SshjSshClientModule(), new SLF4JLoggingModule(), + new EnterpriseConfigurationModule()); + this.compute = ContextBuilder.newBuilder(providerName) + .credentials(identity, credential) + .modules(modules) + .overrides(overrides).buildView(ComputeServiceContext.class).getComputeService(); + } + + private void createAndStartPool() { + LOGGER.info("creating jclouds nodepool"); + ImmutableMap userMetadata = ImmutableMap.of("Name", name); + TemplateBuilder templateBuilder = compute.templateBuilder(); + if (!Strings.isNullOrEmpty(imageId)) { + LOGGER.info("Setting image id to " + imageId); + templateBuilder.imageId(imageId); + } else { + if (!Strings.isNullOrEmpty(osFamily)) { + LOGGER.info("Setting osFamily to " + osFamily); + templateBuilder.osFamily(OsFamily.valueOf(osFamily)); + } + if (!Strings.isNullOrEmpty(osVersion)) { + LOGGER.info("Setting osVersion to " + osVersion); + templateBuilder.osVersionMatches(osVersion); + } + } + if (!Strings.isNullOrEmpty((hardwareId))) { + LOGGER.info("Setting hardware Id to " + hardwareId); + } else { + LOGGER.info("Setting minRam " + ram + " and minCores " + cores); + templateBuilder.minCores(cores).minRam(ram); + } + + Template template = templateBuilder.build(); + + // setup the jcloudTemplate to customize the nodeMetadata with jdk, etc. + // also opening ports + AdminAccess adminAccess = AdminAccess.builder().adminUsername("jenkins").installAdminPrivateKey(false) // no + // need + .grantSudoToAdminUser(false) // no need + .adminPrivateKey(getCloud().privateKey) // temporary due to jclouds + // bug + .authorizeAdminPublicKey(true).adminPublicKey(getCloud().publicKey).build(); + + // Jenkins needs /jenkins dir. + Statement jenkinsDirStatement = Statements.newStatementList(Statements.exec("mkdir /jenkins"), + Statements.exec("chown jenkins /jenkins")); + + Statement bootstrap = newStatementList(adminAccess, jenkinsDirStatement, Statements.exec(this.initScript), + InstallJDK.fromOpenJDK()); + + template.getOptions().inboundPorts(22).userMetadata(userMetadata).runScript(bootstrap); + + pooledCompute = new BasePooledComputeService(compute, "jenkins-pool", template, 10); + + try { + pooledCompute.startPool(); + } catch (RunNodesException e) { + destroyBadNodesAndPropagate(e); + } + } + + private NodeMetadata createNodeWithJdk(String groupName) { + LOGGER.info("creating jclouds node"); + + NodeMetadata nodeMetadata = null; + + try { + nodeMetadata = getOnlyElement(pooledCompute.createNodesInGroup(groupName, 1)); + } catch (RunNodesException e) { + throw destroyBadNodesAndPropagate(e); + } + + // Check if nodeMetadata is null and throw + return nodeMetadata; + } + + private RuntimeException destroyBadNodesAndPropagate(RunNodesException e) { + for (Map.Entry nodeError : e.getNodeErrors().entrySet()) + getCloud().getCompute().destroyNode(nodeError.getKey().getId()); + throw propagate(e); + } + + public void terminate(NodeMetadata nodeMetaData) { + if (stopOnTerminate) { + LOGGER.info("Suspending the Slave : " + nodeMetaData.getName()); + final ComputeService compute = getCloud().getCompute(); + compute.suspendNode(nodeMetaData.getId()); + } else { + LOGGER.info("Terminating the Slave : " + nodeMetaData.getName()); + final ComputeService compute = getCloud().getCompute(); + compute.destroyNode(nodeMetaData.getId()); + } + } + +} diff --git a/labs/openstack-swift/pom.xml b/labs/openstack-swift/pom.xml new file mode 100644 index 0000000000..d1480dd579 --- /dev/null +++ b/labs/openstack-swift/pom.xml @@ -0,0 +1,151 @@ + + + + 4.0.0 + + org.jclouds + jclouds-project + 1.5.0-SNAPSHOT + ../../project/pom.xml + + org.jclouds.labs + openstack-swift + jcloud openstack-swift api + jclouds components to access an implementation of OpenStack Swift + bundle + + + + http://localhost:5000 + + 1.0 + + FIXME_IDENTITY + FIXME_CREDENTIALS + passwordCredentials + FIXME_HTTPURL + FIXME_HTTPMD5 + + + + + org.jclouds.common + openstack-common + ${project.version} + + + org.jclouds + jclouds-blobstore + ${project.version} + + + org.jclouds + jclouds-core + ${project.version} + test-jar + test + + + org.jclouds.common + openstack-common + ${project.version} + test-jar + test + + + org.jclouds + jclouds-blobstore + ${project.version} + test-jar + test + + + org.jclouds.driver + jclouds-slf4j + ${project.version} + test + + + ch.qos.logback + logback-classic + 1.0.0 + test + + + + + + live + + + + org.apache.maven.plugins + maven-surefire-plugin + + + integration + integration-test + + test + + + + ${test.openstack-swift.endpoint} + ${test.openstack-swift.api-version} + ${test.openstack-swift.build-version} + ${test.openstack-swift.identity} + ${test.openstack-swift.credential} + ${test.jclouds.keystone.credential-type} + ${jclouds.blobstore.httpstream.url} + ${jclouds.blobstore.httpstream.md5} + + + + + + + + + + + + + + org.apache.felix + maven-bundle-plugin + + + ${project.artifactId} + org.jclouds.openstack.swift.v1*;version="${project.version}" + + org.jclouds.blobstore.internal;version="${project.version}", + org.jclouds.rest.internal;version="${project.version}", + org.jclouds*;version="${project.version}", + * + + + + + + + + diff --git a/labs/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/SwiftApiMetadata.java b/labs/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/SwiftApiMetadata.java new file mode 100644 index 0000000000..60a20eea8b --- /dev/null +++ b/labs/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/SwiftApiMetadata.java @@ -0,0 +1,100 @@ +/** + * 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.openstack.swift.v1; + +import static org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties.SERVICE_TYPE; + +import java.net.URI; +import java.util.Properties; + +import org.jclouds.apis.ApiMetadata; +import org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties; +import org.jclouds.openstack.services.ServiceType; +import org.jclouds.openstack.swift.v1.config.SwiftRestClientModule; +import org.jclouds.rest.RestContext; +import org.jclouds.rest.internal.BaseRestApiMetadata; + +import com.google.common.collect.ImmutableSet; +import com.google.common.reflect.TypeToken; +import com.google.inject.Module; + +/** + * Implementation of {@link ApiMetadata} for Swift 1.0 API + * + * @author Adrian Cole + */ +public class SwiftApiMetadata extends BaseRestApiMetadata { + + /** The serialVersionUID */ + private static final long serialVersionUID = 6725672099385580694L; + + public static final TypeToken> CONTEXT_TOKEN = new TypeToken>() { + private static final long serialVersionUID = -5070937833892503232L; + }; + + @Override + public Builder toBuilder() { + return new Builder().fromApiMetadata(this); + } + + public SwiftApiMetadata() { + this(new Builder()); + } + + protected SwiftApiMetadata(Builder builder) { + super(builder); + } + + public static Properties defaultProperties() { + Properties properties = BaseRestApiMetadata.defaultProperties(); + properties.setProperty(SERVICE_TYPE, ServiceType.OBJECT_STORE); + // TODO: this doesn't actually do anything yet. + properties.setProperty(KeystoneProperties.VERSION, "2.0"); + return properties; + } + + public static class Builder extends BaseRestApiMetadata.Builder { + + protected Builder() { + super(SwiftClient.class, SwiftAsyncClient.class); + id("openstack-swift") + .name("OpenStack Swift Diablo+ API") + .identityName("tenantId:user") + .credentialName("password") + .documentation(URI.create("http://docs.openstack.org/api/openstack-object-storage/1.0/content/ch_object-storage-dev-overview.html")) + .version("1.0") + .defaultEndpoint("http://localhost:5000") + .defaultProperties(SwiftApiMetadata.defaultProperties()) + .defaultModules(ImmutableSet.>of(SwiftRestClientModule.class)); + } + + @Override + public SwiftApiMetadata build() { + return new SwiftApiMetadata(this); + } + + @Override + public Builder fromApiMetadata(ApiMetadata in) { + super.fromApiMetadata(in); + return this; + } + + } + +} diff --git a/labs/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/SwiftAsyncClient.java b/labs/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/SwiftAsyncClient.java new file mode 100644 index 0000000000..5f1fc80d59 --- /dev/null +++ b/labs/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/SwiftAsyncClient.java @@ -0,0 +1,69 @@ +/** + * 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.openstack.swift.v1; + +import java.util.Set; + +import org.jclouds.javax.annotation.Nullable; +import org.jclouds.location.Region; +import org.jclouds.location.functions.RegionToEndpoint; +import org.jclouds.openstack.swift.v1.features.AccountAsyncClient; +import org.jclouds.openstack.swift.v1.features.ContainerAsyncClient; +import org.jclouds.openstack.swift.v1.features.ObjectAsyncClient; +import org.jclouds.rest.annotations.Delegate; +import org.jclouds.rest.annotations.EndpointParam; + +import com.google.inject.Provides; + +/** + * Provides asynchronous access to Swift via their REST API. + *

+ * + * @see SwiftClient + * @see api doc + * @author Adrian Cole + */ +public interface SwiftAsyncClient { + /** + * + * @return the Region codes configured + */ + @Provides + @Region + Set getConfiguredRegions(); + + /** + * Provides asynchronous access to Account features. + */ + @Delegate + AccountAsyncClient getAccountClientForRegion(@EndpointParam(parser = RegionToEndpoint.class) @Nullable String region); + + /** + * Provides asynchronous access to Container features. + */ + @Delegate + ContainerAsyncClient getContainerClientForRegion( + @EndpointParam(parser = RegionToEndpoint.class) @Nullable String region); + + /** + * Provides asynchronous access to Object features. + */ + @Delegate + ObjectAsyncClient getObjectClientForRegion(@EndpointParam(parser = RegionToEndpoint.class) @Nullable String region); +} diff --git a/labs/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/SwiftClient.java b/labs/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/SwiftClient.java new file mode 100644 index 0000000000..4f1e30e70c --- /dev/null +++ b/labs/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/SwiftClient.java @@ -0,0 +1,71 @@ +/** + * 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.openstack.swift.v1; + +import java.util.Set; +import java.util.concurrent.TimeUnit; + +import org.jclouds.concurrent.Timeout; +import org.jclouds.javax.annotation.Nullable; +import org.jclouds.location.Region; +import org.jclouds.location.functions.RegionToEndpoint; +import org.jclouds.openstack.swift.v1.features.AccountClient; +import org.jclouds.openstack.swift.v1.features.ContainerClient; +import org.jclouds.openstack.swift.v1.features.ObjectClient; +import org.jclouds.rest.annotations.Delegate; +import org.jclouds.rest.annotations.EndpointParam; + +import com.google.inject.Provides; + +/** + * Provides synchronous access to Swift. + *

+ * + * @see SwiftAsyncClient + * @see api doc + * @author Adrian Cole + */ +@Timeout(duration = 60, timeUnit = TimeUnit.SECONDS) +public interface SwiftClient { + /** + * + * @return the Region codes configured + */ + @Provides + @Region + Set getConfiguredRegions(); + + /** + * Provides synchronous access to Account features. + */ + @Delegate + AccountClient getAccountClientForRegion(@EndpointParam(parser = RegionToEndpoint.class) @Nullable String region); + + /** + * Provides synchronous access to Container features. + */ + @Delegate + ContainerClient getContainerClientForRegion(@EndpointParam(parser = RegionToEndpoint.class) @Nullable String region); + + /** + * Provides synchronous access to Object features. + */ + @Delegate + ObjectClient getObjectClientForRegion(@EndpointParam(parser = RegionToEndpoint.class) @Nullable String region); +} diff --git a/labs/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/config/SwiftProperties.java b/labs/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/config/SwiftProperties.java new file mode 100644 index 0000000000..57216017cf --- /dev/null +++ b/labs/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/config/SwiftProperties.java @@ -0,0 +1,28 @@ +/** + * 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.openstack.swift.v1.config; + +/** + * Configuration properties and constants used in openstack Swift connections. + * + * @author Adam Lowe + */ +public class SwiftProperties { + +} diff --git a/labs/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/config/SwiftRestClientModule.java b/labs/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/config/SwiftRestClientModule.java new file mode 100644 index 0000000000..54dfd01498 --- /dev/null +++ b/labs/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/config/SwiftRestClientModule.java @@ -0,0 +1,85 @@ +/** + * 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.openstack.swift.v1.config; + +import java.util.Map; + +import org.jclouds.http.HttpErrorHandler; +import org.jclouds.http.annotation.ClientError; +import org.jclouds.http.annotation.Redirection; +import org.jclouds.http.annotation.ServerError; +import org.jclouds.json.config.GsonModule.DateAdapter; +import org.jclouds.json.config.GsonModule.Iso8601DateAdapter; +import org.jclouds.openstack.keystone.v2_0.config.KeystoneAuthenticationModule; +import org.jclouds.openstack.swift.v1.SwiftAsyncClient; +import org.jclouds.openstack.swift.v1.SwiftClient; +import org.jclouds.openstack.swift.v1.features.AccountAsyncClient; +import org.jclouds.openstack.swift.v1.features.AccountClient; +import org.jclouds.openstack.swift.v1.features.ContainerAsyncClient; +import org.jclouds.openstack.swift.v1.features.ContainerClient; +import org.jclouds.openstack.swift.v1.features.ObjectAsyncClient; +import org.jclouds.openstack.swift.v1.features.ObjectClient; +import org.jclouds.openstack.swift.v1.handlers.SwiftErrorHandler; +import org.jclouds.rest.ConfiguresRestClient; +import org.jclouds.rest.config.RestClientModule; + +import com.google.common.collect.ImmutableMap; + +/** + * Configures the Swift connection. + * + * @author Adrian Cole + */ +@ConfiguresRestClient +public class SwiftRestClientModule extends RestClientModule { + + public static final Map, Class> DELEGATE_MAP = ImmutableMap., Class> builder() + .put(AccountClient.class, AccountAsyncClient.class) + .put(ContainerClient.class, ContainerAsyncClient.class) + .put(ObjectClient.class, ObjectAsyncClient.class) + .build(); + + public SwiftRestClientModule() { + super(DELEGATE_MAP); + } + + @Override + protected void configure() { + bind(DateAdapter.class).to(Iso8601DateAdapter.class); + super.configure(); + } + + @Override + protected void installLocations() { + // TODO: select this from KeystoneProperties.VERSION; note you select from + // a guice provided + // property, so it will have to come from somewhere else, maybe we move + // this to the the + // ContextBuilder + install(KeystoneAuthenticationModule.forRegions()); + super.installLocations(); + } + + @Override + protected void bindErrorHandlers() { + bind(HttpErrorHandler.class).annotatedWith(Redirection.class).to(SwiftErrorHandler.class); + bind(HttpErrorHandler.class).annotatedWith(ClientError.class).to(SwiftErrorHandler.class); + bind(HttpErrorHandler.class).annotatedWith(ServerError.class).to(SwiftErrorHandler.class); + } +} diff --git a/labs/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/domain/AccountMetadata.java b/labs/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/domain/AccountMetadata.java new file mode 100644 index 0000000000..61a53d5c4a --- /dev/null +++ b/labs/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/domain/AccountMetadata.java @@ -0,0 +1,101 @@ +package org.jclouds.openstack.swift.v1.domain; + +import static com.google.common.base.Objects.equal; +import static com.google.common.base.Objects.toStringHelper; + +import com.google.common.base.Objects; +import com.google.common.base.Objects.ToStringHelper; + +/** + * @author Adrian Cole + * @see api doc + */ +public class AccountMetadata { + + public static Builder builder() { + return new Builder(); + } + + public Builder toBuilder() { + return builder().fromAccountMetadata(this); + } + + public static class Builder { + protected int containerCount; + protected long bytesUsed; + + /** + * @see AccountMetadata#getContainerCount() + */ + public Builder containerCount(int containerCount) { + this.containerCount = containerCount; + return this; + } + + /** + * @see AccountMetadata#getBytesUsed() + */ + public Builder bytesUsed(long bytesUsed) { + this.bytesUsed = bytesUsed; + return this; + } + + public AccountMetadata build() { + return new AccountMetadata(containerCount, bytesUsed); + } + + public Builder fromAccountMetadata(AccountMetadata from) { + return containerCount(from.getContainerCount()).bytesUsed(from.getBytesUsed()); + } + } + + protected final int containerCount; + protected final long bytesUsed; + + public AccountMetadata(int containerCount, long bytesUsed) { + this.containerCount = containerCount; + this.bytesUsed = bytesUsed; + } + + /** + * + * @return the number of containers in OpenStack Object Storage for the account + */ + public int getContainerCount() { + return containerCount; + } + + /** + * @return the total bytes stored in OpenStack Object Storage for the account + */ + public long getBytesUsed() { + return bytesUsed; + } + + @Override + public boolean equals(Object object) { + if (this == object) { + return true; + } + if (object instanceof AccountMetadata) { + final AccountMetadata other = AccountMetadata.class.cast(object); + return equal(getContainerCount(), other.getContainerCount()) && equal(getBytesUsed(), other.getBytesUsed()); + } else { + return false; + } + } + + @Override + public int hashCode() { + return Objects.hashCode(getContainerCount(), getBytesUsed()); + } + + @Override + public String toString() { + return string().toString(); + } + + protected ToStringHelper string() { + return toStringHelper("").add("containerCount", getContainerCount()).add("bytesUsed", getBytesUsed()); + } +} diff --git a/labs/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/domain/ContainerMetadata.java b/labs/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/domain/ContainerMetadata.java new file mode 100644 index 0000000000..2852022535 --- /dev/null +++ b/labs/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/domain/ContainerMetadata.java @@ -0,0 +1,138 @@ +package org.jclouds.openstack.swift.v1.domain; + +import static com.google.common.base.Objects.equal; +import static com.google.common.base.Objects.toStringHelper; +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.common.base.Objects; +import com.google.common.base.Objects.ToStringHelper; + +/** + * retrieve a list of existing storage containers ordered by name. The sort order for the name is + * based on a binary comparison, a single built-in collating sequence that compares string data + * using SQLite's memcmp() function, regardless of text encoding. + * + * @author Adrian Cole + * @see api + * doc + */ +public class ContainerMetadata implements Comparable { + + public static Builder builder() { + return new Builder(); + } + + public Builder toBuilder() { + return builder().fromAccountMetadata(this); + } + + public static class Builder { + protected String name; + protected int count; + protected int bytes; + + /** + * @see ContainerMetadata#getName() + */ + public Builder name(String name) { + this.name = checkNotNull(name, "name"); + return this; + } + + /** + * @see ContainerMetadata#getCount() + */ + public Builder count(int count) { + this.count = count; + return this; + } + + /** + * @see ContainerMetadata#getBytes() + */ + public Builder bytes(int bytes) { + this.bytes = bytes; + return this; + } + + public ContainerMetadata build() { + return new ContainerMetadata(name, count, bytes); + } + + public Builder fromAccountMetadata(ContainerMetadata from) { + return name(from.getName()).count(from.getCount()).bytes(from.getBytes()); + } + } + + protected final String name; + protected final int count; + protected final int bytes; + + public ContainerMetadata(String name, int count, int bytes) { + this.name = checkNotNull(name, "name"); + this.count = count; + this.bytes = bytes; + } + + /** + * + * @return the name of the container + */ + public String getName() { + return name; + } + + /** + * + * @return the number of objects in the container + */ + public int getCount() { + return count; + } + + /** + * @return the total bytes stored in this container + */ + public int getBytes() { + return bytes; + } + + @Override + public boolean equals(Object object) { + if (this == object) { + return true; + } + if (object instanceof ContainerMetadata) { + final ContainerMetadata other = ContainerMetadata.class.cast(object); + return equal(getName(), other.getName()) && equal(getCount(), other.getCount()) + && equal(getBytes(), other.getBytes()); + } else { + return false; + } + } + + @Override + public int hashCode() { + return Objects.hashCode(getName(), getCount(), getBytes()); + } + + @Override + public String toString() { + return string().toString(); + } + + protected ToStringHelper string() { + return toStringHelper("").add("name", getName()).add("count", getCount()).add("bytes", getBytes()); + } + + @Override + public int compareTo(ContainerMetadata that) { + if (that == null) + return 1; + if (this == that) + return 0; + return this.getName().compareTo(that.getName()); + } + +} diff --git a/labs/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/AccountAsyncClient.java b/labs/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/AccountAsyncClient.java new file mode 100644 index 0000000000..c159b221cd --- /dev/null +++ b/labs/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/AccountAsyncClient.java @@ -0,0 +1,83 @@ +/** + * 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.openstack.swift.v1.features; + +import java.util.Set; + +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.HEAD; +import javax.ws.rs.Path; +import javax.ws.rs.core.MediaType; + +import org.jclouds.openstack.filters.AuthenticateRequest; +import org.jclouds.openstack.swift.v1.domain.AccountMetadata; +import org.jclouds.openstack.swift.v1.domain.ContainerMetadata; +import org.jclouds.openstack.swift.v1.functions.ParseAccountMetadataResponseFromHeaders; +import org.jclouds.openstack.swift.v1.options.ListContainersOptions; +import org.jclouds.rest.annotations.ExceptionParser; +import org.jclouds.rest.annotations.QueryParams; +import org.jclouds.rest.annotations.RequestFilters; +import org.jclouds.rest.annotations.ResponseParser; +import org.jclouds.rest.annotations.SkipEncoding; +import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404; + +import com.google.common.util.concurrent.ListenableFuture; + +/** + * Storage Account Services + * + * @see AccountClient + * @author Adrian Cole + * @see api doc + */ +@SkipEncoding( { '/', '=' }) +@RequestFilters(AuthenticateRequest.class) +public interface AccountAsyncClient { + + /** + * @see AccountClient#getAccountMetadata + */ + @HEAD + @ResponseParser(ParseAccountMetadataResponseFromHeaders.class) + @Path("/") + ListenableFuture getAccountMetadata(); + + /** + * @see AccountClient#listContainers() + */ + @GET + @Consumes(MediaType.APPLICATION_JSON) + @QueryParams(keys = "format", values = "json") + @ExceptionParser(ReturnEmptySetOnNotFoundOr404.class) + @Path("/") + ListenableFuture> listContainers(); + + /** + * @see AccountClient#listContainers(ListContainersOptions) + */ + @GET + @Consumes(MediaType.APPLICATION_JSON) + @QueryParams(keys = "format", values = "json") + @ExceptionParser(ReturnEmptySetOnNotFoundOr404.class) + @Path("/") + ListenableFuture> listContainers(ListContainersOptions options); +} diff --git a/labs/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/AccountClient.java b/labs/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/AccountClient.java new file mode 100644 index 0000000000..a00414c61a --- /dev/null +++ b/labs/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/AccountClient.java @@ -0,0 +1,62 @@ +/** + * 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.openstack.swift.v1.features; + +import java.util.Set; +import java.util.concurrent.TimeUnit; + +import org.jclouds.concurrent.Timeout; +import org.jclouds.openstack.swift.v1.domain.AccountMetadata; +import org.jclouds.openstack.swift.v1.domain.ContainerMetadata; +import org.jclouds.openstack.swift.v1.options.ListContainersOptions; + +/** + * Storage Account Services + * + * @see AccountAsyncClient + * @author Adrian Cole + * @see api doc + */ +@Timeout(duration = 180, timeUnit = TimeUnit.SECONDS) +public interface AccountClient { + /** + * Retrieve Account Metadata + * + * @return account metadata including container count and bytes used + */ + AccountMetadata getAccountMetadata(); + + /** + * @see #listContainers(ListContainersOptions) + */ + Set listContainers(); + + /** + * retrieve a list of existing storage containers ordered by name. The sort order for the name is + * based on a binary comparison, a single built-in collating sequence that compares string data + * using SQLite's memcmp() function, regardless of text encoding. + * + * @param options + * @return a list of existing storage containers ordered by name. + */ + Set listContainers(ListContainersOptions options); + +} diff --git a/labs/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/ContainerAsyncClient.java b/labs/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/ContainerAsyncClient.java new file mode 100644 index 0000000000..68fda93deb --- /dev/null +++ b/labs/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/ContainerAsyncClient.java @@ -0,0 +1,38 @@ +/** + * 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.openstack.swift.v1.features; + +import org.jclouds.openstack.filters.AuthenticateRequest; +import org.jclouds.rest.annotations.RequestFilters; +import org.jclouds.rest.annotations.SkipEncoding; + +/** + * Storage Container Services + * + * @see ContainerClient + * @author Adrian Cole + * @see api doc + */ +@SkipEncoding({ '/', '=' }) +@RequestFilters(AuthenticateRequest.class) +public interface ContainerAsyncClient { + +} diff --git a/labs/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/ContainerClient.java b/labs/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/ContainerClient.java new file mode 100644 index 0000000000..fc91e8e253 --- /dev/null +++ b/labs/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/ContainerClient.java @@ -0,0 +1,37 @@ +/** + * 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.openstack.swift.v1.features; + +import java.util.concurrent.TimeUnit; + +import org.jclouds.concurrent.Timeout; + +/** + * Storage Container Services + * + * @see ContainerAsyncClient + * @author Adrian Cole + * @see api doc + */ +@Timeout(duration = 180, timeUnit = TimeUnit.SECONDS) +public interface ContainerClient { + +} diff --git a/labs/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/ObjectAsyncClient.java b/labs/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/ObjectAsyncClient.java new file mode 100644 index 0000000000..597a5e2e17 --- /dev/null +++ b/labs/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/ObjectAsyncClient.java @@ -0,0 +1,38 @@ +/** + * 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.openstack.swift.v1.features; + +import org.jclouds.openstack.filters.AuthenticateRequest; +import org.jclouds.rest.annotations.RequestFilters; +import org.jclouds.rest.annotations.SkipEncoding; + +/** + * Storage Object Services + * + * @see ObjectClient + * @author Adrian Cole + * @see api doc + */ +@SkipEncoding( { '/', '=' }) +@RequestFilters(AuthenticateRequest.class) +public interface ObjectAsyncClient { + +} diff --git a/labs/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/ObjectClient.java b/labs/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/ObjectClient.java new file mode 100644 index 0000000000..18a8145401 --- /dev/null +++ b/labs/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/ObjectClient.java @@ -0,0 +1,43 @@ +/** + * 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.openstack.swift.v1.features; + +import java.util.concurrent.TimeUnit; + +import org.jclouds.concurrent.Timeout; + +/** + * Storage Object Services An object represents the data and any metadata for the files stored in + * the system. Through the ReST interface, metadata for an object can be included by adding custom + * HTTP headers to the request and the data payload as the request body. Objects cannot exceed 5GB + * and must have names that do not exceed 1024 bytes after URL encoding. However, objects larger + * than 5GB can be segmented and then concatenated together so that you can upload 5 GB segments and + * download a single concatenated object. You can work with the segments and manifests directly with + * HTTP requests. + * + * @see ObjectAsyncClient + * @author Adrian Cole + * @see api doc + */ +@Timeout(duration = 180, timeUnit = TimeUnit.SECONDS) +public interface ObjectClient { + +} diff --git a/labs/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/functions/ParseAccountMetadataResponseFromHeaders.java b/labs/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/functions/ParseAccountMetadataResponseFromHeaders.java new file mode 100644 index 0000000000..e01ccadfed --- /dev/null +++ b/labs/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/functions/ParseAccountMetadataResponseFromHeaders.java @@ -0,0 +1,42 @@ +/** + * 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.openstack.swift.v1.functions; + +import org.jclouds.http.HttpResponse; +import org.jclouds.openstack.swift.v1.domain.AccountMetadata; + +import com.google.common.base.Function; + +/** + * This parses {@link AccountMetadata} from HTTP headers. + * + * @author James Murty + */ +public class ParseAccountMetadataResponseFromHeaders implements Function { + + /** + * parses the http response headers to create a new {@link AccountMetadata} object. + */ + public AccountMetadata apply(HttpResponse from) { + return AccountMetadata.builder() + .bytesUsed(Long.parseLong(from.getFirstHeaderOrNull("X-Account-Bytes-Used"))) + .containerCount(Integer.parseInt(from.getFirstHeaderOrNull("X-Account-Container-Count"))) + .build(); + } +} diff --git a/labs/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/handlers/SwiftErrorHandler.java b/labs/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/handlers/SwiftErrorHandler.java new file mode 100644 index 0000000000..0437dd48e3 --- /dev/null +++ b/labs/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/handlers/SwiftErrorHandler.java @@ -0,0 +1,82 @@ +/** + * 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.openstack.swift.v1.handlers; + +import static org.jclouds.http.HttpUtils.closeClientButKeepContentStream; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import javax.inject.Singleton; + +import org.jclouds.blobstore.ContainerNotFoundException; +import org.jclouds.blobstore.KeyNotFoundException; +import org.jclouds.http.HttpCommand; +import org.jclouds.http.HttpErrorHandler; +import org.jclouds.http.HttpResponse; +import org.jclouds.http.HttpResponseException; +import org.jclouds.rest.AuthorizationException; + +/** + * This will parse and set an appropriate exception on the command object. + * + * @author Adrian Cole + * + */ +// TODO: is there error spec someplace? let's type errors, etc. +@Singleton +public class SwiftErrorHandler implements HttpErrorHandler { + public static final String PREFIX = "^/v[0-9][^/]*/[a-zA-Z]+_[^/]+/"; + public static final Pattern CONTAINER_PATH = Pattern.compile(PREFIX + "([^/]+)$"); + public static final Pattern CONTAINER_KEY_PATH = Pattern.compile(PREFIX + "([^/]+)/(.*)"); + + public void handleError(HttpCommand command, HttpResponse response) { + // it is important to always read fully and close streams + byte[] data = closeClientButKeepContentStream(response); + String message = data != null ? new String(data) : null; + + Exception exception = message != null ? new HttpResponseException(command, response, message) + : new HttpResponseException(command, response); + message = message != null ? message : String.format("%s -> %s", command.getCurrentRequest().getRequestLine(), + response.getStatusLine()); + switch (response.getStatusCode()) { + case 401: + exception = new AuthorizationException(exception.getMessage(), exception); + break; + case 404: + if (!command.getCurrentRequest().getMethod().equals("DELETE")) { + String path = command.getCurrentRequest().getEndpoint().getPath(); + Matcher matcher = CONTAINER_PATH.matcher(path); + Exception oldException = exception; + if (matcher.find()) { + exception = new ContainerNotFoundException(matcher.group(1), message); + exception.initCause(oldException); + } else { + matcher = CONTAINER_KEY_PATH.matcher(path); + if (matcher.find()) { + exception = new KeyNotFoundException(matcher.group(1), matcher.group(2), message); + exception.initCause(oldException); + } + } + } + break; + } + command.setException(exception); + } +} diff --git a/labs/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/options/ListContainersOptions.java b/labs/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/options/ListContainersOptions.java new file mode 100644 index 0000000000..e2afee6159 --- /dev/null +++ b/labs/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/options/ListContainersOptions.java @@ -0,0 +1,79 @@ +/** + * 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.openstack.swift.v1.options; + +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.base.Preconditions.checkState; + +import org.jclouds.http.options.BaseHttpRequestOptions; + +/** + * Contains options supported in the REST API for the GET container operation.

+ */ +public class ListContainersOptions extends BaseHttpRequestOptions { + public static final ListContainersOptions NONE = new ListContainersOptions(); + + /** + * Given a string value x, return object names greater in value than the specified marker. + */ + public ListContainersOptions marker(String marker) { + queryParameters.put("marker", checkNotNull(marker, "marker")); + return this; + } + + public String getMarker() { + return getFirstQueryOrNull("marker"); + } + + /** + * For an integer value n, limits the number of results to n values. + */ + public ListContainersOptions limit(int limit) { + checkState(limit >= 0, "limit must be >= 0"); + checkState(limit <= 10000, "limit must be <= 10000"); + queryParameters.put("limit", Integer.toString(limit)); + return this; + } + + public int getLimit() { + String val = getFirstQueryOrNull("limit"); + return val != null ? new Integer(val) : 10000; + } + + + public static class Builder { + + /** + * @see ListContainersOptions#marker(String) + */ + public static ListContainersOptions marker(String marker) { + ListContainersOptions options = new ListContainersOptions(); + return options.marker(marker); + } + + /** + * @see ListContainersOptions#limit(int) + */ + public static ListContainersOptions limit(int limit) { + ListContainersOptions options = new ListContainersOptions(); + return options.limit(limit); + } + + } +} diff --git a/labs/openstack-swift/src/main/resources/META-INF/services/org.jclouds.apis.ApiMetadata b/labs/openstack-swift/src/main/resources/META-INF/services/org.jclouds.apis.ApiMetadata new file mode 100644 index 0000000000..84f1200b16 --- /dev/null +++ b/labs/openstack-swift/src/main/resources/META-INF/services/org.jclouds.apis.ApiMetadata @@ -0,0 +1 @@ +org.jclouds.openstack.swift.v1.SwiftApiMetadata diff --git a/labs/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/PasswordAuthenticationExpectTest.java b/labs/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/PasswordAuthenticationExpectTest.java new file mode 100644 index 0000000000..8ec1e81980 --- /dev/null +++ b/labs/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/PasswordAuthenticationExpectTest.java @@ -0,0 +1,75 @@ +/** + * 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.openstack.swift.v1; + +import static org.testng.Assert.assertEquals; + +import java.net.URI; +import java.util.Properties; + +import org.jclouds.http.HttpRequest; +import org.jclouds.http.HttpResponse; +import org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties; +import org.jclouds.openstack.swift.v1.internal.BaseSwiftClientExpectTest; +import org.jclouds.openstack.swift.v1.parse.ParseContainerListTest; +import org.testng.annotations.Test; + +import com.google.common.collect.ImmutableMultimap; +import com.google.common.collect.ImmutableSet; + +/** + * + * @see KeystoneProperties#CREDENTIAL_TYPE + * @author Adrian Cole + */ +@Test(groups = "unit", testName = "PasswordAuthenticationExpectTest") +public class PasswordAuthenticationExpectTest extends BaseSwiftClientExpectTest { + + /** + * this reflects the properties that a user would pass to createContext + */ + @Override + protected Properties setupProperties() { + Properties contextProperties = super.setupProperties(); + contextProperties.setProperty("jclouds.keystone.credential-type", "passwordCredentials"); + return contextProperties; + } + + public void testListContainersWhenResponseIs2xx() throws Exception { + HttpRequest listContainers = HttpRequest + .builder() + .method("GET") + .endpoint(URI.create("https://objects.jclouds.org/v1.0/40806637803162/?format=json")) + .headers( + ImmutableMultimap. builder().put("Accept", "application/json") + .put("X-Auth-Token", authToken).build()).build(); + + HttpResponse listContainersResponse = HttpResponse.builder().statusCode(200) + .payload(payloadFromResource("/container_list.json")).build(); + + SwiftClient clientWhenContainersExist = requestsSendResponses(keystoneAuthWithUsernameAndPassword, + responseWithKeystoneAccess, listContainers, listContainersResponse); + + assertEquals(clientWhenContainersExist.getConfiguredRegions(), ImmutableSet.of("region-a.geo-1")); + + assertEquals(clientWhenContainersExist.getAccountClientForRegion("region-a.geo-1").listContainers().toString(), + new ParseContainerListTest().expected().toString()); + } + +} diff --git a/labs/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/SwiftApiMetadataTest.java b/labs/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/SwiftApiMetadataTest.java new file mode 100644 index 0000000000..469225ca2b --- /dev/null +++ b/labs/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/SwiftApiMetadataTest.java @@ -0,0 +1,38 @@ +/** + * 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.openstack.swift.v1; + +import org.jclouds.View; +import org.jclouds.apis.internal.BaseApiMetadataTest; +import org.testng.annotations.Test; + +import com.google.common.collect.ImmutableSet; +import com.google.common.reflect.TypeToken; + +/** + * + * @author Adrian Cole + */ +@Test(groups = "unit", testName = "SwiftApiMetadataTest") +// public class SwiftApiMetadataTest extends BaseBlobStoreApiMetadataTest { +public class SwiftApiMetadataTest extends BaseApiMetadataTest { + public SwiftApiMetadataTest() { + super(new SwiftApiMetadata(), ImmutableSet.> of()); + } +} diff --git a/labs/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/SwiftErrorHandlerTest.java b/labs/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/SwiftErrorHandlerTest.java new file mode 100644 index 0000000000..bc2a762f57 --- /dev/null +++ b/labs/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/SwiftErrorHandlerTest.java @@ -0,0 +1,120 @@ +/** + * 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.openstack.swift.v1; + +import static org.easymock.EasyMock.createMock; +import static org.easymock.EasyMock.expect; +import static org.easymock.EasyMock.replay; +import static org.easymock.EasyMock.reportMatcher; +import static org.easymock.EasyMock.verify; + +import java.net.URI; + +import org.easymock.IArgumentMatcher; +import org.jclouds.blobstore.ContainerNotFoundException; +import org.jclouds.blobstore.KeyNotFoundException; +import org.jclouds.http.HttpCommand; +import org.jclouds.http.HttpRequest; +import org.jclouds.http.HttpResponse; +import org.jclouds.io.Payloads; +import org.jclouds.openstack.swift.v1.handlers.SwiftErrorHandler; +import org.jclouds.util.Strings2; +import org.testng.annotations.Test; + +/** + * + * @author Adrian Cole + */ +@Test(groups = "unit", testName = "SwiftErrorHandlerTest") +public class SwiftErrorHandlerTest { + + @Test + public void test404SetsKeyNotFoundExceptionMosso() { + assertCodeMakes("HEAD", URI + .create("http://host/v1/MossoCloudFS_7064cdb1d49d4dcba3c899ac33e8409d/adriancole-blobstore1/key"), 404, + "Not Found", "", KeyNotFoundException.class); + } + + @Test + public void test404SetsKeyNotFoundExceptionSwift() { + assertCodeMakes("HEAD", URI + .create("http://67.202.39.175:8080/v1/AUTH_7064cdb1d49d4dcba3c899ac33e8409d/adriancole-blobstore1/key"), + 404, "Not Found", "", KeyNotFoundException.class); + } + + @Test + public void test404SetsContainerNotFoundExceptionMosso() { + assertCodeMakes("HEAD", URI + .create("http://host/v1/MossoCloudFS_7064cdb1d49d4dcba3c899ac33e8409d/adriancole-blobstore1"), 404, + "Not Found", "", ContainerNotFoundException.class); + } + + @Test + public void test404SetsContainerNotFoundExceptionSwift() { + assertCodeMakes("HEAD", URI + .create("http://67.202.39.175:8080/v1/AUTH_7064cdb1d49d4dcba3c899ac33e8409d/adriancole-blobstore1"), + 404, "Not Found", "", ContainerNotFoundException.class); + } + + private void assertCodeMakes(String method, URI uri, int statusCode, String message, String content, + Class expected) { + assertCodeMakes(method, uri, statusCode, message, "text/plain", content, expected); + } + + private void assertCodeMakes(String method, URI uri, int statusCode, String message, String contentType, + String content, Class expected) { + + SwiftErrorHandler function = new SwiftErrorHandler(); + + HttpCommand command = createMock(HttpCommand.class); + HttpRequest request = new HttpRequest(method, uri); + HttpResponse response = new HttpResponse(statusCode, message, Payloads.newInputStreamPayload(Strings2 + .toInputStream(content))); + response.getPayload().getContentMetadata().setContentType(contentType); + + expect(command.getCurrentRequest()).andReturn(request).atLeastOnce(); + command.setException(classEq(expected)); + + replay(command); + + function.handleError(command, response); + + verify(command); + } + + public static Exception classEq(final Class in) { + reportMatcher(new IArgumentMatcher() { + + @Override + public void appendTo(StringBuffer buffer) { + buffer.append("classEq("); + buffer.append(in); + buffer.append(")"); + } + + @Override + public boolean matches(Object arg) { + return arg.getClass() == in; + } + + }); + return null; + } + +} diff --git a/labs/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/AccountClientExpectTest.java b/labs/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/AccountClientExpectTest.java new file mode 100644 index 0000000000..5038f6cae4 --- /dev/null +++ b/labs/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/AccountClientExpectTest.java @@ -0,0 +1,104 @@ +/** + * 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 + * + * Unles 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 expres or implied. See the License for the + * specific language governing permisions and limitations + * under the License. + */ +package org.jclouds.openstack.swift.v1.features; + +import static org.testng.Assert.assertEquals; + +import java.net.URI; + +import org.jclouds.http.HttpRequest; +import org.jclouds.http.HttpResponse; +import org.jclouds.openstack.swift.v1.SwiftClient; +import org.jclouds.openstack.swift.v1.domain.AccountMetadata; +import org.jclouds.openstack.swift.v1.internal.BaseSwiftClientExpectTest; +import org.jclouds.openstack.swift.v1.parse.ParseContainerListTest; +import org.testng.annotations.Test; + +import com.google.common.collect.ImmutableMultimap; +import com.google.common.collect.ImmutableSet; + +/** + * @author Adrian Cole + */ +@Test(groups = "unit", testName = "AccountClientExpectTest") +public class AccountClientExpectTest extends BaseSwiftClientExpectTest { + + public void testGetAccountMetadataWhenResponseIs2xx() throws Exception { + + HttpRequest getAccountMetadata = HttpRequest + .builder() + .method("HEAD") + .endpoint(URI.create("https://objects.jclouds.org/v1.0/40806637803162/")) + .headers( + ImmutableMultimap. builder() + .put("X-Auth-Token", authToken).build()).build(); + + HttpResponse listContainersResponse = HttpResponse.builder().statusCode(204) + .headers(ImmutableMultimap.of( + "X-Account-Container-Count", "3", + "X-Account-Bytes-Used", "323479")).build(); + + SwiftClient clientWhenContainersExist = requestsSendResponses(keystoneAuthWithUsernameAndPassword, + responseWithKeystoneAccess, getAccountMetadata, listContainersResponse); + + assertEquals( + clientWhenContainersExist.getAccountClientForRegion("region-a.geo-1").getAccountMetadata(), + AccountMetadata.builder().containerCount(3).bytesUsed(323479).build()); + } + + public void testListContainersWhenResponseIs2xx() throws Exception { + + HttpRequest listContainers = HttpRequest + .builder() + .method("GET") + .endpoint(URI.create("https://objects.jclouds.org/v1.0/40806637803162/?format=json")) + .headers( + ImmutableMultimap. builder().put("Accept", "application/json") + .put("X-Auth-Token", authToken).build()).build(); + + HttpResponse listContainersResponse = HttpResponse.builder().statusCode(200) + .payload(payloadFromResource("/container_list.json")).build(); + + SwiftClient clientWhenContainersExist = requestsSendResponses(keystoneAuthWithUsernameAndPassword, + responseWithKeystoneAccess, listContainers, listContainersResponse); + + assertEquals( + clientWhenContainersExist.getAccountClientForRegion("region-a.geo-1").listContainers() + .toString(), new ParseContainerListTest().expected().toString()); + } + + public void testListContainersWhenResponseIs404() throws Exception { + HttpRequest listContainers = HttpRequest + .builder() + .method("GET") + .endpoint(URI.create("https://objects.jclouds.org/v1.0/40806637803162/?format=json")) + .headers( + ImmutableMultimap. builder().put("Accept", "application/json") + .put("X-Auth-Token", authToken).build()).build(); + + HttpResponse listContainersResponse = HttpResponse.builder().statusCode(404).build(); + + SwiftClient clientWhenNoContainersExist = requestsSendResponses(keystoneAuthWithUsernameAndPassword, + responseWithKeystoneAccess, listContainers, listContainersResponse); + + assertEquals(clientWhenNoContainersExist.getAccountClientForRegion("region-a.geo-1").listContainers(), ImmutableSet.of()); + + } + +} diff --git a/labs/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/AccountClientLiveTest.java b/labs/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/AccountClientLiveTest.java new file mode 100644 index 0000000000..1eb410a1db --- /dev/null +++ b/labs/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/AccountClientLiveTest.java @@ -0,0 +1,61 @@ +/** + * 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.openstack.swift.v1.features; + +import static org.testng.Assert.assertNotNull; +import static org.testng.Assert.assertTrue; + +import java.util.Set; + +import org.jclouds.openstack.swift.v1.domain.AccountMetadata; +import org.jclouds.openstack.swift.v1.domain.ContainerMetadata; +import org.jclouds.openstack.swift.v1.internal.BaseSwiftClientLiveTest; +import org.testng.annotations.Test; + +/** + * @author Adrian Cole + */ +@Test(groups = "live", testName = "ContainerClientLiveTest") +public class AccountClientLiveTest extends BaseSwiftClientLiveTest { + + @Test + public void testGetAccountMetadata() throws Exception { + for (String regionId : swiftContext.getApi().getConfiguredRegions()) { + AccountClient client = swiftContext.getApi().getAccountClientForRegion(regionId); + AccountMetadata account = client.getAccountMetadata(); + assertNotNull(account); + assertTrue(account.getContainerCount() >= 0); + assertTrue(account.getBytesUsed() >= 0); + } + } + + @Test + public void testListContainers() throws Exception { + for (String regionId : swiftContext.getApi().getConfiguredRegions()) { + AccountClient client = swiftContext.getApi().getAccountClientForRegion(regionId); + Set response = client.listContainers(); + assertNotNull(response); + for (ContainerMetadata container : response) { + assertNotNull(container.getName()); + assertTrue(container.getCount() >= 0); + assertTrue(container.getBytes() >= 0); + } + } + } +} diff --git a/labs/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/ContainerClientExpectTest.java b/labs/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/ContainerClientExpectTest.java new file mode 100644 index 0000000000..ecec4c562c --- /dev/null +++ b/labs/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/ContainerClientExpectTest.java @@ -0,0 +1,31 @@ +/** + * 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.openstack.swift.v1.features; + +import org.jclouds.openstack.swift.v1.internal.BaseSwiftClientExpectTest; +import org.testng.annotations.Test; + +/** + * + * @author Adrian Cole + */ +@Test(groups = "unit", testName = "ContainerAsyncClientTest") +public class ContainerClientExpectTest extends BaseSwiftClientExpectTest { + +} diff --git a/labs/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/ContainerClientLiveTest.java b/labs/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/ContainerClientLiveTest.java new file mode 100644 index 0000000000..dcbe482135 --- /dev/null +++ b/labs/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/ContainerClientLiveTest.java @@ -0,0 +1,31 @@ +/** + * 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.openstack.swift.v1.features; + +import org.jclouds.openstack.swift.v1.internal.BaseSwiftClientLiveTest; +import org.testng.annotations.Test; + +/** + * + * @author Adrian Cole + */ +@Test(groups = "live", testName = "ContainerClientLiveTest") +public class ContainerClientLiveTest extends BaseSwiftClientLiveTest { + +} diff --git a/labs/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/ObjectClientExpectTest.java b/labs/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/ObjectClientExpectTest.java new file mode 100644 index 0000000000..f38bf988e1 --- /dev/null +++ b/labs/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/ObjectClientExpectTest.java @@ -0,0 +1,30 @@ +/** + * 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.openstack.swift.v1.features; + +import org.jclouds.openstack.swift.v1.internal.BaseSwiftClientExpectTest; +import org.testng.annotations.Test; + +/** + * @author Adrian Cole + */ +@Test(groups = "unit", testName = "ObjectAsyncClientTest") +public class ObjectClientExpectTest extends BaseSwiftClientExpectTest { + +} diff --git a/labs/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/ObjectClientLiveTest.java b/labs/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/ObjectClientLiveTest.java new file mode 100644 index 0000000000..f8d816c48e --- /dev/null +++ b/labs/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/ObjectClientLiveTest.java @@ -0,0 +1,30 @@ +/** + * 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.openstack.swift.v1.features; + +import org.jclouds.openstack.swift.v1.internal.BaseSwiftClientLiveTest; +import org.testng.annotations.Test; + +/** + * @author Adrian Cole + */ +@Test(groups = "live", testName = "ObjectClientLiveTest") +public class ObjectClientLiveTest extends BaseSwiftClientLiveTest { + +} diff --git a/labs/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/internal/BaseSwiftAsyncClientExpectTest.java b/labs/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/internal/BaseSwiftAsyncClientExpectTest.java new file mode 100644 index 0000000000..1668d4276b --- /dev/null +++ b/labs/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/internal/BaseSwiftAsyncClientExpectTest.java @@ -0,0 +1,39 @@ +/** + * 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.openstack.swift.v1.internal; + +import java.util.Properties; + +import org.jclouds.http.HttpRequest; +import org.jclouds.http.HttpResponse; +import org.jclouds.openstack.swift.v1.SwiftAsyncClient; + +import com.google.common.base.Function; +import com.google.inject.Module; + +/** + * Base class for writing KeyStone Rest Client Expect tests + * + * @author Adrian Cole + */ +public class BaseSwiftAsyncClientExpectTest extends BaseSwiftExpectTest { + public SwiftAsyncClient createClient(Function fn, Module module, Properties props) { + return createInjector(fn, module, props).getInstance(SwiftAsyncClient.class); + } +} diff --git a/labs/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/internal/BaseSwiftClientExpectTest.java b/labs/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/internal/BaseSwiftClientExpectTest.java new file mode 100644 index 0000000000..b3f4330057 --- /dev/null +++ b/labs/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/internal/BaseSwiftClientExpectTest.java @@ -0,0 +1,30 @@ +/** + * 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.openstack.swift.v1.internal; + +import org.jclouds.openstack.swift.v1.SwiftClient; + +/** + * Base class for writing KeyStone Rest Client Expect tests + * + * @author Adrian Cole + */ +public class BaseSwiftClientExpectTest extends BaseSwiftExpectTest { + +} diff --git a/labs/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/internal/BaseSwiftClientLiveTest.java b/labs/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/internal/BaseSwiftClientLiveTest.java new file mode 100644 index 0000000000..3eb8dfb0b4 --- /dev/null +++ b/labs/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/internal/BaseSwiftClientLiveTest.java @@ -0,0 +1,74 @@ +/** + * 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.openstack.swift.v1.internal; + +import java.util.Properties; + +import org.jclouds.apis.BaseContextLiveTest; +import org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties; +import org.jclouds.openstack.swift.v1.SwiftApiMetadata; +import org.jclouds.openstack.swift.v1.SwiftAsyncClient; +import org.jclouds.openstack.swift.v1.SwiftClient; +import org.jclouds.rest.RestContext; +import org.testng.annotations.AfterGroups; +import org.testng.annotations.BeforeGroups; +import org.testng.annotations.Test; + +import com.google.common.reflect.TypeToken; + +/** + * Tests behavior of {@code SwiftClient} + * + * @author Adrian Cole + */ +@Test(groups = "live") +public class BaseSwiftClientLiveTest extends BaseContextLiveTest> { + + public BaseSwiftClientLiveTest() { + provider = "openstack-swift"; + } + + protected RestContext swiftContext; + + @BeforeGroups(groups = { "integration", "live" }) + @Override + public void setupContext() { + super.setupContext(); + swiftContext = context; + } + + @Override + protected Properties setupProperties() { + Properties props = super.setupProperties(); + setIfTestSystemPropertyPresent(props, KeystoneProperties.CREDENTIAL_TYPE); + return props; + } + + @AfterGroups(groups = "live") + protected void tearDown() { + if (swiftContext != null) + swiftContext.close(); + } + + @Override + protected TypeToken> contextType() { + return SwiftApiMetadata.CONTEXT_TOKEN; + } + +} diff --git a/labs/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/internal/BaseSwiftExpectTest.java b/labs/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/internal/BaseSwiftExpectTest.java new file mode 100644 index 0000000000..67d55b8832 --- /dev/null +++ b/labs/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/internal/BaseSwiftExpectTest.java @@ -0,0 +1,52 @@ +/** + * 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.openstack.swift.v1.internal; + +import org.jclouds.http.HttpRequest; +import org.jclouds.http.HttpResponse; +import org.jclouds.openstack.keystone.v2_0.internal.KeystoneFixture; +import org.jclouds.rest.internal.BaseRestClientExpectTest; + +/** + * Base class for writing Swift Expect tests + * + * @author Adrian Cole + */ +public class BaseSwiftExpectTest extends BaseRestClientExpectTest { + protected HttpRequest keystoneAuthWithUsernameAndPassword; + protected HttpRequest keystoneAuthWithAccessKeyAndSecretKey; + protected String authToken; + protected HttpResponse responseWithKeystoneAccess; + protected HttpRequest extensionsOfSwiftRequest; + protected HttpResponse extensionsOfSwiftResponse; + protected HttpResponse unmatchedExtensionsOfSwiftResponse; + + public BaseSwiftExpectTest() { + provider = "openstack-swift"; + keystoneAuthWithUsernameAndPassword = KeystoneFixture.INSTANCE.initialAuthWithUsernameAndPassword(identity, + credential); + keystoneAuthWithAccessKeyAndSecretKey = KeystoneFixture.INSTANCE.initialAuthWithAccessKeyAndSecretKey(identity, + credential); + + authToken = KeystoneFixture.INSTANCE.getAuthToken(); + responseWithKeystoneAccess = KeystoneFixture.INSTANCE.responseWithAccess(); + // now, createContext arg will need tenant prefix + identity = KeystoneFixture.INSTANCE.getTenantName() + ":" + identity; + } +} diff --git a/labs/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/options/ListContainersOptionsTest.java b/labs/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/options/ListContainersOptionsTest.java new file mode 100644 index 0000000000..64b207034b --- /dev/null +++ b/labs/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/options/ListContainersOptionsTest.java @@ -0,0 +1,96 @@ +/** + * 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.openstack.swift.v1.options; + +import static org.jclouds.openstack.swift.v1.options.ListContainersOptions.Builder.limit; +import static org.jclouds.openstack.swift.v1.options.ListContainersOptions.Builder.marker; +import static org.testng.Assert.assertEquals; + +import java.util.Collections; + +import org.jclouds.http.options.HttpRequestOptions; +import org.testng.annotations.Test; + +/** + * Tests possible uses of ListContainerOptions and ListContainerOptions.Builder.* + * + * @author Adrian Cole + */ +@Test(testName = "ListContainersOptionsTest") +public class ListContainersOptionsTest { + + @Test + public void testAssignability() { + assert HttpRequestOptions.class.isAssignableFrom(ListContainersOptions.class); + assert !String.class.isAssignableFrom(ListContainersOptions.class); + } + @Test + public void testNoOptionsQueryString() { + HttpRequestOptions options = new ListContainersOptions(); + assertEquals(options.buildQueryParameters().size(), 0); + } + + @Test + public void testMarker() { + ListContainersOptions options = new ListContainersOptions(); + options.marker("test"); + assertEquals(options.buildQueryParameters().get("marker"), Collections.singletonList("test")); + } + + @Test + public void testNullMarker() { + ListContainersOptions options = new ListContainersOptions(); + assertEquals(options.buildQueryParameters().get("marker"), Collections.EMPTY_LIST); + } + + @Test + public void testMarkerStatic() { + ListContainersOptions options = marker("test"); + assertEquals(options.buildQueryParameters().get("marker"), Collections.singletonList("test")); + } + + @Test(expectedExceptions = NullPointerException.class) + public void testMarkerNPE() { + marker(null); + } + + @Test + public void testLimit() { + ListContainersOptions options = new ListContainersOptions(); + options.limit(1000); + assertEquals(options.buildQueryParameters().get("limit"), Collections.singletonList("1000")); + } + + @Test + public void testNullLimit() { + ListContainersOptions options = new ListContainersOptions(); + assertEquals(options.buildQueryParameters().get("limit"), Collections.EMPTY_LIST); + } + + @Test + public void testLimitStatic() { + ListContainersOptions options = limit(1000); + assertEquals(options.buildQueryParameters().get("limit"), Collections.singletonList("1000")); + } + + @Test(expectedExceptions = IllegalStateException.class) + public void testLimitNegative() { + limit(-1); + } +} diff --git a/labs/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/parse/ParseContainerListTest.java b/labs/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/parse/ParseContainerListTest.java new file mode 100644 index 0000000000..3c583121c4 --- /dev/null +++ b/labs/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/parse/ParseContainerListTest.java @@ -0,0 +1,59 @@ +/** + * 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.openstack.swift.v1.parse; + +import java.util.Set; + +import javax.ws.rs.Consumes; +import javax.ws.rs.core.MediaType; + +import org.jclouds.json.BaseSetParserTest; +import org.jclouds.openstack.swift.v1.domain.ContainerMetadata; +import org.testng.annotations.Test; + +import com.google.common.collect.ImmutableSet; + +/** + * + * @author Adrian Cole + */ +@Test(groups = "unit", testName = "ParseContainerListTest") +public class ParseContainerListTest extends BaseSetParserTest { + + @Override + public String resource() { + return "/container_list.json"; + } + + @Override + @Consumes(MediaType.APPLICATION_JSON) + public Set expected() { + return ImmutableSet + .of(ContainerMetadata.builder() + .name("test_container_1") + .count(2) + .bytes(78) + .build(), + ContainerMetadata.builder() + .name("test_container_2") + .count(1) + .bytes(17) + .build()); + } +} diff --git a/labs/openstack-swift/src/test/resources/container_list.json b/labs/openstack-swift/src/test/resources/container_list.json new file mode 100644 index 0000000000..ef7e791530 --- /dev/null +++ b/labs/openstack-swift/src/test/resources/container_list.json @@ -0,0 +1,4 @@ +[ + {"name":"test_container_1", "count":2, "bytes":78}, + {"name":"test_container_2", "count":1, "bytes":17} +] \ No newline at end of file diff --git a/labs/openstack-swift/src/test/resources/logback.xml b/labs/openstack-swift/src/test/resources/logback.xml new file mode 100644 index 0000000000..bd89efb8c0 --- /dev/null +++ b/labs/openstack-swift/src/test/resources/logback.xml @@ -0,0 +1,51 @@ + + + + target/test-data/jclouds.log + + + %d %-5p [%c] [%thread] %m%n + + + + + target/test-data/jclouds-wire.log + + + %d %-5p [%c] [%thread] %m%n + + + + + target/test-data/jclouds-blobstore.log + + + %d %-5p [%c] [%thread] %m%n + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/labs/opsource-servers/src/main/java/org/jclouds/opsource/servers/OpSourceServersApiMetadata.java b/labs/opsource-servers/src/main/java/org/jclouds/opsource/servers/OpSourceServersApiMetadata.java index c96b3d3beb..f890283ebe 100644 --- a/labs/opsource-servers/src/main/java/org/jclouds/opsource/servers/OpSourceServersApiMetadata.java +++ b/labs/opsource-servers/src/main/java/org/jclouds/opsource/servers/OpSourceServersApiMetadata.java @@ -73,7 +73,7 @@ public class OpSourceServersApiMetadata extends BaseRestApiMetadata { .defaultEndpoint("https://api.opsourcecloud.net/oec/${jclouds.api-version}") .defaultProperties(OpSourceServersApiMetadata.defaultProperties()) .defaultModule(OpSourceServersRestClientModule.class); -// .wrapper(TypeToken.of(ComputeServiceContext.class)) +// .view(TypeToken.of(ComputeServiceContext.class)) // .defaultModules(ImmutableSet.>of(OpSourceServersRestClientModule.class, OpSourceServersComputeServiceContextModule.class)); } diff --git a/labs/pom.xml b/labs/pom.xml index 60b5dee8da..b774ad00cb 100644 --- a/labs/pom.xml +++ b/labs/pom.xml @@ -41,5 +41,6 @@ savvis-symphonyvpdc dmtf carrenza-vcloud-director + openstack-swift diff --git a/labs/savvis-symphonyvpdc/src/main/java/org/jclouds/savvis/vpdc/VPDCApiMetadata.java b/labs/savvis-symphonyvpdc/src/main/java/org/jclouds/savvis/vpdc/VPDCApiMetadata.java index 912297047c..9c14210227 100644 --- a/labs/savvis-symphonyvpdc/src/main/java/org/jclouds/savvis/vpdc/VPDCApiMetadata.java +++ b/labs/savvis-symphonyvpdc/src/main/java/org/jclouds/savvis/vpdc/VPDCApiMetadata.java @@ -82,7 +82,7 @@ public class VPDCApiMetadata extends BaseRestApiMetadata { .buildVersion("2.3") .defaultEndpoint("https://api.savvis.net/vpdc") .defaultProperties(VPDCApiMetadata.defaultProperties()) - .wrapper(TypeToken.of(ComputeServiceContext.class)) + .view(TypeToken.of(ComputeServiceContext.class)) .defaultModules(ImmutableSet.>of(VPDCRestClientModule.class, VPDCComputeServiceContextModule.class)); } diff --git a/labs/savvis-symphonyvpdc/src/main/java/org/jclouds/savvis/vpdc/config/VPDCRestClientModule.java b/labs/savvis-symphonyvpdc/src/main/java/org/jclouds/savvis/vpdc/config/VPDCRestClientModule.java index ddae92f080..f1434b9dd8 100644 --- a/labs/savvis-symphonyvpdc/src/main/java/org/jclouds/savvis/vpdc/config/VPDCRestClientModule.java +++ b/labs/savvis-symphonyvpdc/src/main/java/org/jclouds/savvis/vpdc/config/VPDCRestClientModule.java @@ -20,7 +20,6 @@ package org.jclouds.savvis.vpdc.config; import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkState; -import static org.jclouds.Constants.PROPERTY_IDENTITY; import static org.jclouds.Constants.PROPERTY_SESSION_INTERVAL; import static org.jclouds.rest.config.BinderUtils.bindClientAndAsyncClient; import static org.jclouds.savvis.vpdc.reference.VPDCConstants.PROPERTY_VPDC_TIMEOUT_TASK_COMPLETED; @@ -42,6 +41,7 @@ import org.jclouds.location.Provider; import org.jclouds.location.suppliers.ImplicitLocationSupplier; import org.jclouds.predicates.RetryablePredicate; import org.jclouds.rest.ConfiguresRestClient; +import org.jclouds.rest.annotations.Identity; import org.jclouds.rest.config.RestClientModule; import org.jclouds.rest.suppliers.MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier; import org.jclouds.savvis.vpdc.VPDCAsyncClient; @@ -105,7 +105,7 @@ public class VPDCRestClientModule extends RestClientModule> provideOrgs(Supplier cache, - @Named(PROPERTY_IDENTITY) final String user) { + @Identity final String user) { return Suppliers.compose(new Function>() { @Override diff --git a/labs/savvis-symphonyvpdc/src/test/java/org/jclouds/savvis/vpdc/compute/VPDCTemplateBuilderLiveTest.java b/labs/savvis-symphonyvpdc/src/test/java/org/jclouds/savvis/vpdc/compute/VPDCTemplateBuilderLiveTest.java index d37882e876..19e7184024 100644 --- a/labs/savvis-symphonyvpdc/src/test/java/org/jclouds/savvis/vpdc/compute/VPDCTemplateBuilderLiveTest.java +++ b/labs/savvis-symphonyvpdc/src/test/java/org/jclouds/savvis/vpdc/compute/VPDCTemplateBuilderLiveTest.java @@ -69,7 +69,7 @@ public class VPDCTemplateBuilderLiveTest extends BaseTemplateBuilderLiveTest { @Override public void testDefaultTemplateBuilder() throws IOException { - Template defaultTemplate = context.getComputeService().templateBuilder().build(); + Template defaultTemplate = view.getComputeService().templateBuilder().build(); assertEquals(defaultTemplate.getImage().getOperatingSystem().getVersion(), "5"); assertEquals(defaultTemplate.getImage().getOperatingSystem().is64Bit(), true); assertEquals(defaultTemplate.getImage().getOperatingSystem().getFamily(), OsFamily.RHEL); diff --git a/labs/savvis-symphonyvpdc/src/test/java/org/jclouds/savvis/vpdc/features/VMClientLiveTest.java b/labs/savvis-symphonyvpdc/src/test/java/org/jclouds/savvis/vpdc/features/VMClientLiveTest.java index cb645f8346..0afcd54aeb 100644 --- a/labs/savvis-symphonyvpdc/src/test/java/org/jclouds/savvis/vpdc/features/VMClientLiveTest.java +++ b/labs/savvis-symphonyvpdc/src/test/java/org/jclouds/savvis/vpdc/features/VMClientLiveTest.java @@ -279,7 +279,7 @@ public class VMClientLiveTest extends BaseVPDCClientLiveTest { protected void checkSSH(IPSocket socket) { socketTester.apply(socket); - SshClient client = context.utils().sshFactory() + SshClient client = view.utils().sshFactory() .create(socket, LoginCredentials.builder().user(username).password(password).build()); try { client.connect(); diff --git a/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/VCloudDirectorApiMetadata.java b/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/VCloudDirectorApiMetadata.java index a4d70cd388..384cf1ad6c 100644 --- a/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/VCloudDirectorApiMetadata.java +++ b/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/VCloudDirectorApiMetadata.java @@ -92,7 +92,7 @@ public class VCloudDirectorApiMetadata extends BaseRestApiMetadata { .defaultProperties(VCloudDirectorApiMetadata.defaultProperties()) .context(TypeToken.of(VCloudDirectorContext.class)) .defaultModule(VCloudDirectorRestClientModule.class); -// .wrapper(TypeToken.of(ComputeServiceContext.class)) +// .view(TypeToken.of(ComputeServiceContext.class)) // .defaultModules(ImmutableSet.>of(VCloudDirectorRestClientModule.class, VCloudDirectorComputeServiceContextModule.class)); } diff --git a/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/VCloudDirectorConstants.java b/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/VCloudDirectorConstants.java index 3ac2dee73b..91088d307e 100644 --- a/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/VCloudDirectorConstants.java +++ b/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/VCloudDirectorConstants.java @@ -18,6 +18,12 @@ */ package org.jclouds.vcloud.director.v1_5; +import org.jclouds.rest.RestContext; +import org.jclouds.vcloud.director.v1_5.login.SessionAsyncClient; +import org.jclouds.vcloud.director.v1_5.login.SessionClient; + +import com.google.common.reflect.TypeToken; + /** * Constants used by VCloudDirector clients * @@ -63,4 +69,11 @@ public class VCloudDirectorConstants { /** TODO javadoc */ public static final String PROPERTY_NS_NAME_LEN_MAX = "jclouds.dns_name_length_max"; + + /** TODO javadoc */ + public static final TypeToken> SESSION_CONTEXT_TYPE = + new TypeToken>() { + /** The serialVersionUID */ + private static final long serialVersionUID = -3625362618882122604L; + }; } diff --git a/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/VCloudDirectorMediaType.java b/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/VCloudDirectorMediaType.java index 68d93a1b09..d12ed4fdb1 100644 --- a/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/VCloudDirectorMediaType.java +++ b/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/VCloudDirectorMediaType.java @@ -196,6 +196,8 @@ public class VCloudDirectorMediaType { public static final String NETWORK_POOL = "application/vnd.vmware.admin.networkPool+xml"; public static final String ENTITY = "application/vnd.vmware.vcloud.entity+xml"; + + public static final String ADMIN = "application/vnd.vmware.admin.vcloud+xml"; /** * All acceptable media types. @@ -220,7 +222,7 @@ public class VCloudDirectorMediaType { ADMIN_ORG_NETWORK, USER, ROLE, DEPLOY_VAPP_PARAMS, RECOMPOSE_VAPP_PARAMS, RELOCATE_VM_PARAMS, UNDEPLOY_VAPP_PARAMS, ADMIN_VDC, MEDIA_PARAMS, RUNTIME_INFO_SECTION, SCREEN_TICKET, VAPP_NETWORK, - TEXT_XML, ADMIN_VDC, NETWORK_POOL, ADMIN_ORG, ENTITY + TEXT_XML, ADMIN_VDC, NETWORK_POOL, ADMIN_ORG, ENTITY, ADMIN ); // NOTE These lists must be updated whenever a new media type constant is added. diff --git a/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/domain/network/NetworkConnection.java b/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/domain/network/NetworkConnection.java index 60f71eb726..4c5303552d 100644 --- a/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/domain/network/NetworkConnection.java +++ b/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/domain/network/NetworkConnection.java @@ -1,4 +1,4 @@ -/** +/* * Licensed to jclouds, Inc. (jclouds) under one or more * contributor license agreements. See the NOTICE file * distributed with this work for additional information @@ -37,15 +37,9 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Maps; - /** * Represents a network connection. - *

- *

- *

Java class for NetworkConnection complex type. - *

- *

The following schema fragment specifies the expected content contained within this class. - *

+ * *

  * <complexType name="NetworkConnection">
  *   <complexContent>
@@ -83,7 +77,7 @@ public class NetworkConnection {
       @XmlEnumValue("dhcp") DHCP("dhcp"),
       @XmlEnumValue("manual") MANUAL("manual"),
       @XmlEnumValue("none") NONE("none"),
-      UNRECOGNIZED("unrecognized");
+      @XmlEnumValue("") UNRECOGNIZED("unrecognized");
       
       public static final List ALL = ImmutableList.of(POOL, DHCP, MANUAL, NONE);
 
@@ -126,7 +120,7 @@ public class NetworkConnection {
       private String externalIpAddress;
       private boolean isConnected;
       private String macAddress;
-      private String ipAddressAllocationMode;
+      private IpAddressAllocationMode ipAddressAllocationMode;
       private String network;
       private Boolean needsCustomization;
 
@@ -173,11 +167,19 @@ public class NetworkConnection {
       /**
        * @see NetworkConnection#getIpAddressAllocationMode()
        */
-      public Builder ipAddressAllocationMode(String ipAddressAllocationMode) {
+      public Builder ipAddressAllocationMode(IpAddressAllocationMode ipAddressAllocationMode) {
          this.ipAddressAllocationMode = ipAddressAllocationMode;
          return this;
       }
 
+      /**
+       * @see NetworkConnection#getIpAddressAllocationMode()
+       */
+      public Builder ipAddressAllocationMode(String ipAddressAllocationMode) {
+         this.ipAddressAllocationMode = IpAddressAllocationMode.valueOf(ipAddressAllocationMode);
+         return this;
+      }
+
       /**
        * @see NetworkConnection#getNetwork()
        */
@@ -214,11 +216,11 @@ public class NetworkConnection {
    }
 
    public NetworkConnection(int networkConnectionIndex, String ipAddress, String externalIpAddress, boolean connected,
-                            String macAddress, String ipAddressAllocationMode, String network, Boolean needsCustomization) {
+                            String macAddress, IpAddressAllocationMode ipAddressAllocationMode, String network, Boolean needsCustomization) {
       this.networkConnectionIndex = networkConnectionIndex;
       this.ipAddress = ipAddress;
       this.externalIpAddress = externalIpAddress;
-      isConnected = connected;
+      this.isConnected = connected;
       this.macAddress = macAddress;
       this.ipAddressAllocationMode = ipAddressAllocationMode;
       this.network = network;
@@ -241,7 +243,7 @@ public class NetworkConnection {
    @XmlElement(name = "MACAddress")
    protected String macAddress;
    @XmlElement(name = "IpAddressAllocationMode", required = true)
-   protected String ipAddressAllocationMode;
+   protected IpAddressAllocationMode ipAddressAllocationMode;
    @XmlAttribute(required = true)
    protected String network;
    @XmlAttribute
@@ -297,7 +299,7 @@ public class NetworkConnection {
     * @return possible object is
     *         {@link String }
     */
-   public String getIpAddressAllocationMode() {
+   public IpAddressAllocationMode getIpAddressAllocationMode() {
       return ipAddressAllocationMode;
    }
 
diff --git a/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/domain/params/UndeployVAppParams.java b/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/domain/params/UndeployVAppParams.java
index dcb37b6ab9..67ac098e49 100644
--- a/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/domain/params/UndeployVAppParams.java
+++ b/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/domain/params/UndeployVAppParams.java
@@ -59,7 +59,7 @@ public class UndeployVAppParams {
       @XmlEnumValue("suspend") SUSPEND("suspend"),
       @XmlEnumValue("shutdown") SHUTDOWN("shutdown"),
       @XmlEnumValue("force") FORCE("force"),
-      UNRECOGNIZED("unrecognized");
+      @XmlEnumValue("") UNRECOGNIZED("unrecognized");
       
       public static final List ALL = ImmutableList.of( POWER_OFF, SUSPEND, SHUTDOWN, FORCE );
 
@@ -97,13 +97,21 @@ public class UndeployVAppParams {
 
    public static class Builder {
 
-      private String undeployPowerAction;
+      private PowerAction undeployPowerAction;
+
+      /**
+       * @see UndeployVAppParams#getUndeployPowerAction()
+       */
+      public Builder undeployPowerAction(PowerAction undeployPowerAction) {
+         this.undeployPowerAction = undeployPowerAction;
+         return this;
+      }
 
       /**
        * @see UndeployVAppParams#getUndeployPowerAction()
        */
       public Builder undeployPowerAction(String undeployPowerAction) {
-         this.undeployPowerAction = undeployPowerAction;
+         this.undeployPowerAction = PowerAction.valueOf(undeployPowerAction);
          return this;
       }
 
@@ -123,7 +131,7 @@ public class UndeployVAppParams {
    }
 
    @XmlElement(name = "UndeployPowerAction")
-   protected String undeployPowerAction;
+   protected PowerAction undeployPowerAction;
 
    /**
     * The specified action is applied to all VMs in the vApp.
@@ -140,7 +148,7 @@ public class UndeployVAppParams {
     *
     * @since 1.5
     */
-   public String getUndeployPowerAction() {
+   public PowerAction getUndeployPowerAction() {
       return undeployPowerAction;
    }
 
diff --git a/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/endpoints/Catalog.java b/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/endpoints/Catalog.java
new file mode 100644
index 0000000000..ed25c38a9b
--- /dev/null
+++ b/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/endpoints/Catalog.java
@@ -0,0 +1,39 @@
+/**
+ * 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.vcloud.director.v1_5.endpoints;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import javax.inject.Qualifier;
+
+/**
+ * Related to a VCloud Catalog.
+ * 
+ * @author Adrian Cole
+ * 
+ */
+@Retention(value = RetentionPolicy.RUNTIME)
+@Target(value = { ElementType.TYPE, ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD })
+@Qualifier
+public @interface Catalog {
+
+}
\ No newline at end of file
diff --git a/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/endpoints/Network.java b/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/endpoints/Network.java
new file mode 100644
index 0000000000..d140afa967
--- /dev/null
+++ b/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/endpoints/Network.java
@@ -0,0 +1,39 @@
+/**
+ * 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.vcloud.director.v1_5.endpoints;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import javax.inject.Qualifier;
+
+/**
+ * Related to a VCloud Network.
+ * 
+ * @author Adrian Cole
+ * 
+ */
+@Retention(value = RetentionPolicy.RUNTIME)
+@Target(value = { ElementType.TYPE, ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD })
+@Qualifier
+public @interface Network {
+
+}
\ No newline at end of file
diff --git a/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/endpoints/Org.java b/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/endpoints/Org.java
new file mode 100644
index 0000000000..d774605ffd
--- /dev/null
+++ b/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/endpoints/Org.java
@@ -0,0 +1,39 @@
+/**
+ * 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.vcloud.director.v1_5.endpoints;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import javax.inject.Qualifier;
+
+/**
+ * Related to a VCloud express Org.
+ * 
+ * @author Adrian Cole
+ * 
+ */
+@Retention(value = RetentionPolicy.RUNTIME)
+@Target(value = { ElementType.TYPE, ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD })
+@Qualifier
+public @interface Org {
+
+}
\ No newline at end of file
diff --git a/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/endpoints/OrgList.java b/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/endpoints/OrgList.java
new file mode 100644
index 0000000000..041ed0fb28
--- /dev/null
+++ b/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/endpoints/OrgList.java
@@ -0,0 +1,39 @@
+/**
+ * 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.vcloud.director.v1_5.endpoints;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import javax.inject.Qualifier;
+
+/**
+ * Related to a VCloud express Org List.
+ * 
+ * @author Adrian Cole
+ * 
+ */
+@Retention(value = RetentionPolicy.RUNTIME)
+@Target(value = { ElementType.TYPE, ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD })
+@Qualifier
+public @interface OrgList {
+
+}
\ No newline at end of file
diff --git a/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/endpoints/TasksList.java b/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/endpoints/TasksList.java
new file mode 100644
index 0000000000..8f97c5ffb2
--- /dev/null
+++ b/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/endpoints/TasksList.java
@@ -0,0 +1,39 @@
+/**
+ * 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.vcloud.director.v1_5.endpoints;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import javax.inject.Qualifier;
+
+/**
+ * Related to a VCloud express Task List.
+ * 
+ * @author Adrian Cole
+ * 
+ */
+@Retention(value = RetentionPolicy.RUNTIME)
+@Target(value = { ElementType.TYPE, ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD })
+@Qualifier
+public @interface TasksList {
+
+}
\ No newline at end of file
diff --git a/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/endpoints/VCloudLogin.java b/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/endpoints/VCloudLogin.java
new file mode 100644
index 0000000000..a97b295bd0
--- /dev/null
+++ b/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/endpoints/VCloudLogin.java
@@ -0,0 +1,40 @@
+/**
+ * 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.vcloud.director.v1_5.endpoints;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import javax.inject.Qualifier;
+
+/**
+ * Represents a component related to vCloud.
+ * 
+ * @see 
+ * @author Adrian Cole
+ * 
+ */
+@Retention(value = RetentionPolicy.RUNTIME)
+@Target(value = { ElementType.TYPE, ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD })
+@Qualifier
+public @interface VCloudLogin {
+
+}
diff --git a/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/endpoints/Vdc.java b/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/endpoints/Vdc.java
new file mode 100644
index 0000000000..a53f515f62
--- /dev/null
+++ b/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/endpoints/Vdc.java
@@ -0,0 +1,39 @@
+/**
+ * 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.vcloud.director.v1_5.endpoints;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import javax.inject.Qualifier;
+
+/**
+ * Related to a VCloud express Catalog.
+ * 
+ * @author Adrian Cole
+ * 
+ */
+@Retention(value = RetentionPolicy.RUNTIME)
+@Target(value = {ElementType.TYPE, ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD })
+@Qualifier
+public @interface Vdc {
+
+}
\ No newline at end of file
diff --git a/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/functions/AllCatalogItemsInCatalog.java b/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/functions/AllCatalogItemsInCatalog.java
new file mode 100644
index 0000000000..d9d408d75b
--- /dev/null
+++ b/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/functions/AllCatalogItemsInCatalog.java
@@ -0,0 +1,81 @@
+/**
+ * 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.vcloud.director.v1_5.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;
+import javax.inject.Singleton;
+
+import org.jclouds.Constants;
+import org.jclouds.logging.Logger;
+import org.jclouds.vcloud.director.v1_5.VCloudDirectorMediaType;
+import org.jclouds.vcloud.director.v1_5.domain.Catalog;
+import org.jclouds.vcloud.director.v1_5.domain.CatalogItem;
+import org.jclouds.vcloud.director.v1_5.domain.Reference;
+import org.jclouds.vcloud.director.v1_5.user.VCloudDirectorAsyncClient;
+
+import com.google.common.base.Function;
+import com.google.common.base.Predicate;
+
+/**
+ * @author danikov
+ */
+@Singleton
+public class AllCatalogItemsInCatalog implements Function> {
+   @Resource
+   public Logger logger = Logger.NULL;
+
+   private final VCloudDirectorAsyncClient aclient;
+   private final ExecutorService executor;
+
+   @Inject
+   AllCatalogItemsInCatalog(VCloudDirectorAsyncClient aclient, @Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor) {
+      this.aclient = aclient;
+      this.executor = executor;
+   }
+
+   @Override
+   public Iterable apply(Catalog from) {
+
+      Iterable catalogItems = transformParallel(filter(from.getCatalogItems(), new Predicate() {
+
+         @Override
+         public boolean apply(Reference input) {
+            return input.getType().equals(VCloudDirectorMediaType.CATALOG_ITEM);
+         }
+
+      }), new Function>() {
+
+         @Override
+         public Future apply(Reference from) {
+            return aclient.getCatalogClient().getCatalogItem(from.getHref());
+         }
+
+      }, executor, null, logger, "catalogItems in " + from.getHref());
+      return catalogItems;
+   }
+
+}
\ No newline at end of file
diff --git a/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/functions/AllCatalogItemsInOrg.java b/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/functions/AllCatalogItemsInOrg.java
new file mode 100644
index 0000000000..d72568246b
--- /dev/null
+++ b/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/functions/AllCatalogItemsInOrg.java
@@ -0,0 +1,59 @@
+/**
+ * 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.vcloud.director.v1_5.functions;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+import org.jclouds.vcloud.director.v1_5.domain.Catalog;
+import org.jclouds.vcloud.director.v1_5.domain.CatalogItem;
+import org.jclouds.vcloud.director.v1_5.domain.org.Org;
+
+import com.google.common.base.Function;
+import com.google.common.collect.Iterables;
+
+/**
+ * @author danikov
+ */
+@Singleton
+public class AllCatalogItemsInOrg implements Function> {
+
+   private final Function> allCatalogsInOrg;
+
+   private final Function> allCatalogItemsInCatalog;
+
+   @Inject
+   AllCatalogItemsInOrg(Function> allCatalogsInOrg,
+            Function> allCatalogItemsInCatalog) {
+      this.allCatalogsInOrg = allCatalogsInOrg;
+      this.allCatalogItemsInCatalog = allCatalogItemsInCatalog;
+   }
+
+   @Override
+   public Iterable apply(Org from) {
+      return Iterables.concat(Iterables.transform(allCatalogsInOrg.apply(from),
+               new Function>() {
+                  @Override
+                  public Iterable apply(Catalog from) {
+                     return allCatalogItemsInCatalog.apply(from);
+                  }
+
+               }));
+   }
+}
\ No newline at end of file
diff --git a/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/functions/AllCatalogsInOrg.java b/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/functions/AllCatalogsInOrg.java
new file mode 100644
index 0000000000..5b2c5d6b84
--- /dev/null
+++ b/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/functions/AllCatalogsInOrg.java
@@ -0,0 +1,68 @@
+/**
+ * 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.vcloud.director.v1_5.functions;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Future;
+
+import javax.annotation.Resource;
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.inject.Singleton;
+
+import org.jclouds.Constants;
+import org.jclouds.concurrent.FutureIterables;
+import org.jclouds.logging.Logger;
+import org.jclouds.vcloud.director.v1_5.domain.Catalog;
+import org.jclouds.vcloud.director.v1_5.domain.Reference;
+import org.jclouds.vcloud.director.v1_5.domain.org.AdminOrg;
+import org.jclouds.vcloud.director.v1_5.user.VCloudDirectorAsyncClient;
+
+import com.google.common.base.Function;
+
+/**
+ * @author danikov
+ */
+@Singleton
+public class AllCatalogsInOrg implements Function> {
+   @Resource
+   public Logger logger = Logger.NULL;
+
+   private final VCloudDirectorAsyncClient aclient;
+   private final ExecutorService executor;
+
+   @Inject
+   AllCatalogsInOrg(VCloudDirectorAsyncClient aclient, @Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor) {
+      this.aclient = aclient;
+      this.executor = executor;
+   }
+
+   @Override
+   public Iterable apply(final AdminOrg org) {
+      Iterable catalogs = FutureIterables.transformParallel(org.getCatalogs(),
+            new Function>() {
+               @Override
+               public Future apply(Reference from) {
+                  return aclient.getCatalogClient().getCatalog(from.getHref());
+               }
+
+            }, executor, null, logger, "catalogs in " + org.getName());
+      return catalogs;
+   }
+}
\ No newline at end of file
diff --git a/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/functions/AllVdcsInOrg.java b/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/functions/AllVdcsInOrg.java
new file mode 100644
index 0000000000..a17407e386
--- /dev/null
+++ b/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/functions/AllVdcsInOrg.java
@@ -0,0 +1,71 @@
+/**
+ * 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.vcloud.director.v1_5.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;
+import javax.inject.Singleton;
+
+import org.jclouds.Constants;
+import org.jclouds.logging.Logger;
+import org.jclouds.vcloud.director.v1_5.domain.Reference;
+import org.jclouds.vcloud.director.v1_5.domain.Vdc;
+import org.jclouds.vcloud.director.v1_5.domain.org.AdminOrg;
+import org.jclouds.vcloud.director.v1_5.user.VCloudDirectorAsyncClient;
+
+import com.google.common.base.Function;
+
+/**
+ * @author danikov
+ */
+@Singleton
+public class AllVdcsInOrg implements Function> {
+   @Resource
+   public Logger logger = Logger.NULL;
+
+   private final VCloudDirectorAsyncClient aclient;
+   private final ExecutorService executor;
+
+   @Inject
+   AllVdcsInOrg(VCloudDirectorAsyncClient aclient, @Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor) {
+      this.aclient = aclient;
+      this.executor = executor;
+   }
+
+   @Override
+   public Iterable apply(final AdminOrg org) {
+
+      Iterable catalogItems = transformParallel(org.getVdcs(),
+            new Function>() {
+               @Override
+               public Future apply(Reference from) {
+                  return aclient.getVdcClient().getVdc(from.getHref());
+               }
+
+            }, executor, null, logger, "vdcs in org " + org.getName());
+      return catalogItems;
+   }
+
+}
\ No newline at end of file
diff --git a/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/functions/DefaultNetworkNameInTemplate.java b/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/functions/DefaultNetworkNameInTemplate.java
new file mode 100644
index 0000000000..5760a2f0af
--- /dev/null
+++ b/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/functions/DefaultNetworkNameInTemplate.java
@@ -0,0 +1,54 @@
+/**
+ * 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.vcloud.director.v1_5.functions;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.collect.Iterables.get;
+
+import java.util.Set;
+
+import javax.annotation.Resource;
+import javax.inject.Singleton;
+
+import org.jclouds.dmtf.ovf.Network;
+import org.jclouds.dmtf.ovf.NetworkSection;
+import org.jclouds.logging.Logger;
+import org.jclouds.vcloud.director.v1_5.domain.VAppTemplate;
+
+import com.google.common.base.Function;
+
+@Singleton
+public class DefaultNetworkNameInTemplate implements Function {
+   @Resource
+   protected Logger logger = Logger.NULL;
+   
+   private SectionForVAppTemplate networkSelector = 
+         new SectionForVAppTemplate(NetworkSection.class);
+
+   @Override
+   public String apply(VAppTemplate vAppTemplate) {
+      checkArgument(vAppTemplate != null, "vAppTemplate was null!");
+      vAppTemplate.getSections();
+      Set networks = networkSelector.apply(vAppTemplate).getNetworks();
+      checkArgument(networks.size() > 0, "no networks found in vAppTemplate %s", vAppTemplate);
+      if (networks.size() > 1)
+         logger.warn("multiple networks found for %s, choosing first from: %s", vAppTemplate.getName(), networks);
+      return get(networks, 0).getName();
+   }
+}
\ No newline at end of file
diff --git a/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/functions/OrgNameAndCatalogNameToEndpoint.java b/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/functions/OrgNameAndCatalogNameToEndpoint.java
new file mode 100644
index 0000000000..62b571d136
--- /dev/null
+++ b/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/functions/OrgNameAndCatalogNameToEndpoint.java
@@ -0,0 +1,78 @@
+/**
+ * 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.vcloud.director.v1_5.functions;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.jclouds.vcloud.director.v1_5.predicates.ReferencePredicates.nameEquals;
+
+import java.net.URI;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.Set;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+import org.jclouds.vcloud.director.v1_5.domain.Reference;
+import org.jclouds.vcloud.director.v1_5.domain.org.AdminOrg;
+import org.jclouds.vcloud.director.v1_5.endpoints.Catalog;
+
+import com.google.common.base.Function;
+import com.google.common.base.Supplier;
+import com.google.common.collect.Iterables;
+
+/**
+ * 
+ * @author danikov
+ */
+@Singleton
+public class OrgNameAndCatalogNameToEndpoint implements Function {
+   private final Supplier> orgMap;
+   private final Supplier defaultOrg;
+   private final Supplier defaultCatalog;
+
+   @Inject
+   public OrgNameAndCatalogNameToEndpoint(Supplier> orgMap,
+         @org.jclouds.vcloud.director.v1_5.endpoints.Org Supplier defaultOrg,
+         @Catalog Supplier defaultCatalog) {
+      this.orgMap = orgMap;
+      this.defaultOrg = defaultOrg;
+      this.defaultCatalog = defaultCatalog;
+   }
+
+   @SuppressWarnings("unchecked")
+   public URI apply(Object from) {
+      Iterable orgCatalog = (Iterable) checkNotNull(from, "args");
+      Object org = Iterables.get(orgCatalog, 0);
+      Object catalog = Iterables.get(orgCatalog, 1);
+      if (org == null && catalog == null)
+         return defaultCatalog.get().getHref();
+      else if (org == null)
+         org = defaultOrg.get().getName();
+
+      try {
+         Set catalogs = checkNotNull(orgMap.get().get(org)).getCatalogs();
+         return catalog == null ? Iterables.getLast(catalogs).getHref() : 
+            Iterables.find(catalogs, nameEquals((String)catalog)).getHref();
+      } catch (NullPointerException e) {
+         throw new NoSuchElementException(org + "/" + catalog + " not found in " + orgMap.get());
+      }
+   }
+
+}
\ No newline at end of file
diff --git a/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/functions/OrgNameAndVdcNameToEndpoint.java b/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/functions/OrgNameAndVdcNameToEndpoint.java
new file mode 100644
index 0000000000..cfcbc34d58
--- /dev/null
+++ b/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/functions/OrgNameAndVdcNameToEndpoint.java
@@ -0,0 +1,77 @@
+/**
+ * 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.vcloud.director.v1_5.functions;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.jclouds.vcloud.director.v1_5.predicates.ReferencePredicates.nameEquals;
+
+import java.net.URI;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.Set;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+import org.jclouds.vcloud.director.v1_5.domain.Reference;
+import org.jclouds.vcloud.director.v1_5.domain.org.AdminOrg;
+import org.jclouds.vcloud.director.v1_5.endpoints.Vdc;
+
+import com.google.common.base.Function;
+import com.google.common.base.Supplier;
+import com.google.common.collect.Iterables;
+
+/**
+ * 
+ * @author danikov
+ */
+@Singleton
+public class OrgNameAndVdcNameToEndpoint implements Function {
+   private final Supplier> orgNameToVdcEndpoint;
+   private final Supplier defaultOrg;
+   private final Supplier defaultVdc;
+
+   @Inject
+   public OrgNameAndVdcNameToEndpoint(Supplier> orgNameToVDCEndpoint,
+         @org.jclouds.vcloud.director.v1_5.endpoints.Org Supplier defaultOrg, @Vdc Supplier defaultVdc) {
+      this.orgNameToVdcEndpoint = orgNameToVDCEndpoint;
+      this.defaultOrg = defaultOrg;
+      this.defaultVdc = defaultVdc;
+   }
+
+   @SuppressWarnings("unchecked")
+   public URI apply(Object from) {
+      Iterable orgVdc = (Iterable) checkNotNull(from, "args");
+      Object org = Iterables.get(orgVdc, 0);
+      Object vdc = Iterables.get(orgVdc, 1);
+      if (org == null && vdc == null)
+         return defaultVdc.get().getHref();
+      else if (org == null)
+         org = defaultOrg.get().getName();
+
+      try {
+        Set vdcs = checkNotNull(orgNameToVdcEndpoint.get().get(org)).getVdcs();
+         return vdc == null ? Iterables.getLast(vdcs).getHref() : 
+            Iterables.find(vdcs, nameEquals((String)vdc)).getHref();
+      } catch (NullPointerException e) {
+         throw new NoSuchElementException(org + "/" + vdc + " not found in " + orgNameToVdcEndpoint.get());
+      }
+   }
+
+}
\ No newline at end of file
diff --git a/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/functions/OrgNameCatalogNameItemNameToEndpoint.java b/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/functions/OrgNameCatalogNameItemNameToEndpoint.java
new file mode 100644
index 0000000000..5f327c9d21
--- /dev/null
+++ b/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/functions/OrgNameCatalogNameItemNameToEndpoint.java
@@ -0,0 +1,78 @@
+/**
+ * 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.vcloud.director.v1_5.functions;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.jclouds.vcloud.director.v1_5.predicates.ReferencePredicates.nameEquals;
+
+import java.net.URI;
+import java.util.Map;
+import java.util.NoSuchElementException;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+import org.jclouds.vcloud.director.v1_5.domain.Reference;
+import org.jclouds.vcloud.director.v1_5.domain.Catalog;
+import org.jclouds.vcloud.director.v1_5.endpoints.Org;
+
+import com.google.common.base.Function;
+import com.google.common.base.Supplier;
+import com.google.common.collect.Iterables;
+
+/**
+ * 
+ * @author danikov
+ */
+@Singleton
+public class OrgNameCatalogNameItemNameToEndpoint implements Function {
+   private final Supplier>> orgCatalogMap;
+   private final Supplier defaultOrg;
+   private final Supplier defaultCatalog;
+
+   @Inject
+   public OrgNameCatalogNameItemNameToEndpoint(
+         Supplier>> orgCatalogMap,
+         @Org Supplier defaultOrg, 
+         @org.jclouds.vcloud.director.v1_5.endpoints.Catalog Supplier defaultCatalog) {
+      this.orgCatalogMap = orgCatalogMap;
+      this.defaultOrg = defaultOrg;
+      this.defaultCatalog = defaultCatalog;
+   }
+
+   @SuppressWarnings("unchecked")
+   public URI apply(Object from) {
+      Iterable orgCatalog = (Iterable) checkNotNull(from, "args");
+      Object org = Iterables.get(orgCatalog, 0);
+      Object catalog = Iterables.get(orgCatalog, 1);
+      Object catalogItem = Iterables.get(orgCatalog, 2);
+      if (org == null)
+         org = defaultOrg.get().getName();
+      if (catalog == null)
+         catalog = defaultCatalog.get().getName();
+      try {
+         Map catalogs = checkNotNull(orgCatalogMap.get().get(org));
+         return Iterables.find(catalogs.get(catalog).getCatalogItems(), nameEquals((String)catalogItem)).getHref();
+      } catch (NullPointerException e) {
+         throw new NoSuchElementException(org + "/" + catalog + "/" + catalogItem + " not found in "
+               + orgCatalogMap.get());
+      }
+   }
+
+}
\ No newline at end of file
diff --git a/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/functions/OrgNameCatalogNameVAppTemplateNameToEndpoint.java b/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/functions/OrgNameCatalogNameVAppTemplateNameToEndpoint.java
new file mode 100644
index 0000000000..d49e2fe787
--- /dev/null
+++ b/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/functions/OrgNameCatalogNameVAppTemplateNameToEndpoint.java
@@ -0,0 +1,87 @@
+/**
+ * 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.vcloud.director.v1_5.functions;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.net.URI;
+import java.util.Map;
+import java.util.NoSuchElementException;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+import org.jclouds.vcloud.director.v1_5.domain.CatalogItem;
+import org.jclouds.vcloud.director.v1_5.domain.Reference;
+import org.jclouds.vcloud.director.v1_5.endpoints.Catalog;
+import org.jclouds.vcloud.director.v1_5.endpoints.Org;
+
+import com.google.common.base.Function;
+import com.google.common.base.Supplier;
+import com.google.common.collect.Iterables;
+
+/**
+ * 
+ * @author danikov
+ */
+@Singleton
+public class OrgNameCatalogNameVAppTemplateNameToEndpoint implements Function {
+   private final Supplier>>> orgCatalogItemMap;
+   private final Supplier defaultOrg;
+   private final Supplier defaultCatalog;
+
+   @Inject
+   public OrgNameCatalogNameVAppTemplateNameToEndpoint(
+            Supplier>>> orgCatalogItemMap,
+            @Org Supplier defaultOrg, @Catalog Supplier defaultCatalog) {
+      this.orgCatalogItemMap = orgCatalogItemMap;
+      this.defaultOrg = defaultOrg;
+      this.defaultCatalog = defaultCatalog;
+   }
+
+   @SuppressWarnings("unchecked")
+   public URI apply(Object from) {
+      Iterable orgCatalog = (Iterable) checkNotNull(from, "args");
+      Object org = Iterables.get(orgCatalog, 0);
+      Object catalog = Iterables.get(orgCatalog, 1);
+      Object catalogItem = Iterables.get(orgCatalog, 2);
+      if (org == null)
+         org = defaultOrg.get().getName();
+      if (catalog == null)
+         catalog = defaultCatalog.get().getName();
+      Map>> orgCatalogItemMap = this.orgCatalogItemMap.get();
+
+      if (!orgCatalogItemMap.containsKey(org))
+         throw new NoSuchElementException("org: " + org + " not found in " + orgCatalogItemMap.keySet());
+      Map> catalogs = orgCatalogItemMap.get(org);
+
+      if (!catalogs.containsKey(catalog))
+         throw new NoSuchElementException("catalog: " + org + "/" + catalog + " not found in " + catalogs.keySet());
+      Map catalogMap = catalogs.get(catalog);
+
+      if (!catalogMap.containsKey(catalogItem))
+         throw new NoSuchElementException("item: " + org + "/" + catalog + "/" + catalogItem + " not found in "
+                  + catalogMap.keySet());
+      CatalogItem item = catalogMap.get(catalogItem);
+
+      return checkNotNull(item.getEntity(), "item: " + org + "/" + catalog + "/" + catalogItem + " has no entity")
+               .getHref();
+   }
+
+}
\ No newline at end of file
diff --git a/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/functions/OrgNameToEndpoint.java b/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/functions/OrgNameToEndpoint.java
new file mode 100644
index 0000000000..f385aee72e
--- /dev/null
+++ b/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/functions/OrgNameToEndpoint.java
@@ -0,0 +1,59 @@
+/**
+ * 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.vcloud.director.v1_5.functions;
+
+import java.net.URI;
+import java.util.Map;
+import java.util.NoSuchElementException;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+import org.jclouds.vcloud.director.v1_5.domain.Reference;
+import org.jclouds.vcloud.director.v1_5.endpoints.Org;
+
+import com.google.common.base.Function;
+import com.google.common.base.Supplier;
+
+/**
+ * 
+ * @author danikov
+ */
+@Singleton
+public class OrgNameToEndpoint implements Function {
+   private final Supplier> orgNameToEndpointSupplier;
+   private final Supplier defaultOrg;
+
+   @Inject
+   public OrgNameToEndpoint(@Org Supplier> orgNameToEndpointSupplier,
+         @Org Supplier defaultOrg) {
+      this.orgNameToEndpointSupplier = orgNameToEndpointSupplier;
+      this.defaultOrg = defaultOrg;
+   }
+
+   public URI apply(Object from) {
+      try {
+         Map orgNameToEndpoint = orgNameToEndpointSupplier.get();
+         return from == null ? defaultOrg.get().getHref() : orgNameToEndpoint.get(from).getHref();
+      } catch (NullPointerException e) {
+         throw new NoSuchElementException("org " + from + " not found in " + orgNameToEndpointSupplier.get().keySet());
+      }
+   }
+
+}
\ No newline at end of file
diff --git a/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/functions/OrgNameToTasksListEndpoint.java b/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/functions/OrgNameToTasksListEndpoint.java
new file mode 100644
index 0000000000..9e124fa8f7
--- /dev/null
+++ b/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/functions/OrgNameToTasksListEndpoint.java
@@ -0,0 +1,64 @@
+/**
+ * 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.vcloud.director.v1_5.functions;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.net.URI;
+import java.util.Map;
+import java.util.NoSuchElementException;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+import org.jclouds.vcloud.director.v1_5.domain.Reference;
+import org.jclouds.vcloud.director.v1_5.domain.org.Org;
+import org.jclouds.vcloud.director.v1_5.endpoints.TasksList;
+
+import com.google.common.base.Function;
+import com.google.common.base.Supplier;
+
+/**
+ * 
+ * @author danikov
+ */
+@Singleton
+public class OrgNameToTasksListEndpoint implements Function {
+   private final Supplier> orgMap;
+   private final Supplier defaultTasksList;
+
+   @Inject
+   public OrgNameToTasksListEndpoint(Supplier> orgMap,
+         @TasksList Supplier defaultTasksList) {
+      this.orgMap = orgMap;
+      this.defaultTasksList = defaultTasksList;
+   }
+
+   public URI apply(Object from) {
+      Object org = from;
+      if (org == null)
+         return defaultTasksList.get().getHref();
+      try {
+         return checkNotNull(orgMap.get().get(org)).getHref();
+      } catch (NullPointerException e) {
+         throw new NoSuchElementException(org + " not found in " + orgMap.get());
+      }
+   }
+
+}
\ No newline at end of file
diff --git a/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/functions/OrgNameVdcNameNetworkNameToEndpoint.java b/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/functions/OrgNameVdcNameNetworkNameToEndpoint.java
new file mode 100644
index 0000000000..c11bf1d534
--- /dev/null
+++ b/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/functions/OrgNameVdcNameNetworkNameToEndpoint.java
@@ -0,0 +1,59 @@
+/**
+ * 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.vcloud.director.v1_5.functions;
+
+import static org.jclouds.vcloud.director.v1_5.predicates.ReferencePredicates.nameEquals;
+
+import java.net.URI;
+import java.util.Map;
+import java.util.NoSuchElementException;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+import org.jclouds.vcloud.director.v1_5.domain.Reference;
+import org.jclouds.vcloud.director.v1_5.endpoints.Org;
+import org.jclouds.vcloud.director.v1_5.endpoints.Vdc;
+
+import com.google.common.base.Supplier;
+import com.google.common.collect.Iterables;
+
+/**
+ * 
+ * @author danikov
+ */
+@Singleton
+public class OrgNameVdcNameNetworkNameToEndpoint extends OrgNameVdcNameResourceNameToEndpoint {
+   @Inject
+   public OrgNameVdcNameNetworkNameToEndpoint(
+         Supplier>> orgVdcMap,
+         @Org Supplier defaultOrg, @Vdc Supplier defaultVdc) {
+      super(orgVdcMap, defaultOrg, defaultVdc);
+   }
+
+   protected URI getEndpointOfResourceInVdc(Object org, Object Vdc, Object resource,
+         org.jclouds.vcloud.director.v1_5.domain.Vdc VdcObject) {
+      Reference resourceEntity = Iterables.find(VdcObject.getAvailableNetworks(), nameEquals((String)Vdc));
+      if (resourceEntity == null)
+         throw new NoSuchElementException("network " + resource + " in Vdc " + Vdc + ", org " + org + " not found in "
+               + VdcObject.getAvailableNetworks());
+      return resourceEntity.getHref();
+   }
+
+}
\ No newline at end of file
diff --git a/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/functions/OrgNameVdcNameResourceEntityNameToEndpoint.java b/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/functions/OrgNameVdcNameResourceEntityNameToEndpoint.java
new file mode 100644
index 0000000000..20e25663bf
--- /dev/null
+++ b/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/functions/OrgNameVdcNameResourceEntityNameToEndpoint.java
@@ -0,0 +1,59 @@
+/**
+ * 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.vcloud.director.v1_5.functions;
+
+import static org.jclouds.vcloud.director.v1_5.predicates.ReferencePredicates.nameEquals;
+
+import java.net.URI;
+import java.util.Map;
+import java.util.NoSuchElementException;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+import org.jclouds.vcloud.director.v1_5.domain.Reference;
+import org.jclouds.vcloud.director.v1_5.endpoints.Org;
+import org.jclouds.vcloud.director.v1_5.endpoints.Vdc;
+
+import com.google.common.base.Supplier;
+import com.google.common.collect.Iterables;
+
+/**
+ * 
+ * @author danikov
+ */
+@Singleton
+public class OrgNameVdcNameResourceEntityNameToEndpoint extends OrgNameVdcNameResourceNameToEndpoint {
+   @Inject
+   public OrgNameVdcNameResourceEntityNameToEndpoint(
+         Supplier>> orgVdcMap,
+         @Org Supplier defaultOrg, @Vdc Supplier defaultVdc) {
+      super(orgVdcMap, defaultOrg, defaultVdc);
+   }
+
+   protected URI getEndpointOfResourceInVdc(Object org, Object Vdc, Object resource,
+         org.jclouds.vcloud.director.v1_5.domain.Vdc VdcObject) {
+      Reference resourceEntity = Iterables.find(VdcObject.getResourceEntities(), nameEquals((String)resource));
+      if (resourceEntity == null)
+         throw new NoSuchElementException("entity " + resource + " in Vdc " + Vdc + ", org " + org + " not found in "
+               + VdcObject.getResourceEntities());
+      return resourceEntity.getHref();
+   }
+
+}
\ No newline at end of file
diff --git a/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/functions/OrgNameVdcNameResourceNameToEndpoint.java b/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/functions/OrgNameVdcNameResourceNameToEndpoint.java
new file mode 100644
index 0000000000..7ff831e3e2
--- /dev/null
+++ b/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/functions/OrgNameVdcNameResourceNameToEndpoint.java
@@ -0,0 +1,79 @@
+/**
+ * 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.vcloud.director.v1_5.functions;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkState;
+
+import java.net.URI;
+import java.util.Map;
+import java.util.NoSuchElementException;
+
+import javax.inject.Inject;
+
+import org.jclouds.vcloud.director.v1_5.domain.Reference;
+import org.jclouds.vcloud.director.v1_5.domain.Vdc;
+import org.jclouds.vcloud.director.v1_5.endpoints.Org;
+
+import com.google.common.base.Function;
+import com.google.common.base.Supplier;
+import com.google.common.collect.Iterables;
+/**
+ * 
+ * @author danikov
+ */
+public abstract class OrgNameVdcNameResourceNameToEndpoint  implements Function{
+
+   protected final Supplier>> orgVdcMap;
+   protected final Supplier defaultOrg;
+   protected final Supplier defaultVdc;
+
+   @Inject
+   public OrgNameVdcNameResourceNameToEndpoint(
+         Supplier>> orgVdcMap,
+         @Org Supplier defaultOrg, @org.jclouds.vcloud.director.v1_5.endpoints.Vdc Supplier defaultVdc) {
+      this.orgVdcMap = orgVdcMap;
+      this.defaultOrg = defaultOrg;
+      this.defaultVdc = defaultVdc;
+   }
+
+   @SuppressWarnings("unchecked")
+   public URI apply(Object from) {
+      Iterable orgVdc = (Iterable) checkNotNull(from, "args");
+      Object org = Iterables.get(orgVdc, 0);
+      Object Vdc = Iterables.get(orgVdc, 1);
+      Object resource = Iterables.get(orgVdc, 2);
+      if (org == null)
+         org = defaultOrg.get().getName();
+      if (Vdc == null)
+         Vdc = defaultVdc.get().getName();
+      Map> orgToVdcs = orgVdcMap.get();
+      checkState(orgToVdcs != null, "could not get map of org name to Vdcs!");
+      Map Vdcs = orgToVdcs.get(org);
+      if (Vdcs == null)
+         throw new NoSuchElementException("org " + org + " not found in " + orgToVdcs.keySet());
+      org.jclouds.vcloud.director.v1_5.domain.Vdc VdcObject = Vdcs.get(Vdc);
+      if (VdcObject == null)
+         throw new NoSuchElementException("Vdc " + Vdc + " in org " + org + " not found in " + Vdcs.keySet());
+      return getEndpointOfResourceInVdc(org, Vdc, resource, VdcObject);
+   }
+
+   protected abstract URI getEndpointOfResourceInVdc(Object org, Object Vdc, Object resource, Vdc VdcObject);
+
+}
\ No newline at end of file
diff --git a/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/functions/OrgsForLocations.java b/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/functions/OrgsForLocations.java
new file mode 100644
index 0000000000..c34a039a06
--- /dev/null
+++ b/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/functions/OrgsForLocations.java
@@ -0,0 +1,92 @@
+/**
+ * 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.vcloud.director.v1_5.functions;
+
+import static com.google.common.collect.Iterables.filter;
+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;
+import javax.inject.Named;
+import javax.inject.Singleton;
+
+import org.jclouds.Constants;
+import org.jclouds.domain.Location;
+import org.jclouds.domain.LocationScope;
+import org.jclouds.logging.Logger;
+import org.jclouds.vcloud.director.v1_5.domain.org.Org;
+import org.jclouds.vcloud.director.v1_5.user.VCloudDirectorAsyncClient;
+
+import com.google.common.base.Function;
+import com.google.common.base.Predicate;
+import com.google.common.collect.Sets;
+
+/**
+ * @author danikov
+ */
+@Singleton
+public class OrgsForLocations implements Function, Iterable> {
+   @Resource
+   public Logger logger = Logger.NULL;
+   private final VCloudDirectorAsyncClient aclient;
+   private final ExecutorService executor;
+
+   @Inject
+   OrgsForLocations(VCloudDirectorAsyncClient aclient, @Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor) {
+      this.aclient = aclient;
+      this.executor = executor;
+   }
+
+   /**
+    * Zones are assignable, but we want regions. so we look for zones, whose
+    * parent is region. then, we use a set to extract the unique set.
+    */
+   @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) {
+            return aclient.getOrgClient().getOrg(from);
+         }
+
+      }, executor, null, logger, "organizations for uris");
+   }
+
+}
\ No newline at end of file
diff --git a/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/functions/OrgsForNames.java b/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/functions/OrgsForNames.java
new file mode 100644
index 0000000000..c1ae4bebc1
--- /dev/null
+++ b/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/functions/OrgsForNames.java
@@ -0,0 +1,77 @@
+/**
+ * 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.vcloud.director.v1_5.functions;
+
+import static org.jclouds.concurrent.FutureIterables.transformParallel;
+import static org.jclouds.vcloud.director.v1_5.predicates.ReferencePredicates.nameEquals;
+
+import java.util.Set;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Future;
+
+import javax.annotation.Resource;
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.inject.Singleton;
+
+import org.jclouds.Constants;
+import org.jclouds.logging.Logger;
+import org.jclouds.vcloud.director.v1_5.domain.Reference;
+import org.jclouds.vcloud.director.v1_5.domain.org.Org;
+import org.jclouds.vcloud.director.v1_5.user.VCloudDirectorAsyncClient;
+import org.jclouds.vcloud.director.v1_5.user.VCloudDirectorClient;
+
+import com.google.common.base.Function;
+import com.google.common.collect.Iterables;
+
+/**
+ * @author danikov
+ */
+@Singleton
+public class OrgsForNames implements Function, Iterable> {
+   @Resource
+   public Logger logger = Logger.NULL;
+   private final VCloudDirectorAsyncClient aclient;
+   private final VCloudDirectorClient sclient;
+   private final ExecutorService executor;
+
+   @Inject
+   OrgsForNames(VCloudDirectorAsyncClient aclient, 
+         VCloudDirectorClient sclient, 
+         @Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor) {
+      this.aclient = aclient;
+      this.sclient = sclient;
+      this.executor = executor;
+   }
+
+   @Override
+   public Iterable apply(Iterable from) {
+      final Set orgs = sclient.getOrgClient().getOrgList().getOrgs();
+      
+      return transformParallel(from, new Function>() {
+
+         @Override
+         public Future apply(String from) {
+            return aclient.getOrgClient().getOrg(Iterables.find(orgs, nameEquals(from)).getHref());
+         }
+
+      }, executor, null, logger, "organizations for names");
+   }
+
+}
\ No newline at end of file
diff --git a/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/functions/ReferenceToEndpoint.java b/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/functions/ReferenceToEndpoint.java
new file mode 100644
index 0000000000..79829e5af9
--- /dev/null
+++ b/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/functions/ReferenceToEndpoint.java
@@ -0,0 +1,39 @@
+/*
+ * 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.vcloud.director.v1_5.functions;
+
+import java.net.URI;
+
+import javax.inject.Singleton;
+
+import org.jclouds.vcloud.director.v1_5.domain.Reference;
+
+import com.google.common.base.Function;
+
+/**
+ * @author danikov
+ */
+@Singleton
+public class ReferenceToEndpoint implements Function {
+   
+   @Override
+   public URI apply(Reference from) {
+      return from.getHref();
+   }
+}
\ No newline at end of file
diff --git a/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/functions/ReferenceToName.java b/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/functions/ReferenceToName.java
new file mode 100644
index 0000000000..2af735f471
--- /dev/null
+++ b/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/functions/ReferenceToName.java
@@ -0,0 +1,37 @@
+/*
+ * 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.vcloud.director.v1_5.functions;
+
+import javax.inject.Singleton;
+
+import org.jclouds.vcloud.director.v1_5.domain.Reference;
+
+import com.google.common.base.Function;
+
+/**
+ * @author danikov
+ */
+@Singleton
+public class ReferenceToName implements Function {
+   
+   @Override
+   public String apply(Reference from) {
+      return from.getName();
+   }
+}
\ No newline at end of file
diff --git a/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/functions/SectionForVAppTemplate.java b/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/functions/SectionForVAppTemplate.java
new file mode 100644
index 0000000000..2efcd27ee4
--- /dev/null
+++ b/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/functions/SectionForVAppTemplate.java
@@ -0,0 +1,56 @@
+/*
+ * 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.vcloud.director.v1_5.functions;
+
+import java.util.Set;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+import org.jclouds.dmtf.ovf.SectionType;
+import org.jclouds.vcloud.director.v1_5.domain.VAppTemplate;
+
+import com.google.common.base.Function;
+import com.google.common.collect.Sets;
+
+/**
+ * @author danikov
+ */
+@Singleton
+public class SectionForVAppTemplate implements Function {
+   
+   private final Class sectionType;
+
+   @Inject
+   SectionForVAppTemplate(Class sectionType) {
+      this.sectionType = sectionType;
+   }
+
+   @SuppressWarnings("unchecked")
+   @Override
+   public S apply(VAppTemplate from) {
+      Set sections = Sets.newLinkedHashSet();
+      for (SectionType section : from.getSections()) {
+         if (sectionType.isAssignableFrom(section.getClass())) {
+            return (S)section;
+         }
+      }
+      return null;
+   }
+}
\ No newline at end of file
diff --git a/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/functions/VAppTemplatesForCatalogItems.java b/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/functions/VAppTemplatesForCatalogItems.java
new file mode 100644
index 0000000000..6e674c72f9
--- /dev/null
+++ b/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/functions/VAppTemplatesForCatalogItems.java
@@ -0,0 +1,100 @@
+/**
+ * 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.vcloud.director.v1_5.functions;
+
+import static com.google.common.collect.Iterables.filter;
+import static org.jclouds.concurrent.FutureIterables.transformParallel;
+import static org.jclouds.util.Throwables2.propagateOrNull;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Future;
+
+import javax.annotation.Resource;
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.inject.Singleton;
+
+import org.jclouds.Constants;
+import org.jclouds.compute.reference.ComputeServiceConstants;
+import org.jclouds.concurrent.ExceptionParsingListenableFuture;
+import org.jclouds.concurrent.Futures;
+import org.jclouds.logging.Logger;
+import org.jclouds.rest.AuthorizationException;
+import org.jclouds.vcloud.director.v1_5.VCloudDirectorMediaType;
+import org.jclouds.vcloud.director.v1_5.domain.CatalogItem;
+import org.jclouds.vcloud.director.v1_5.domain.VAppTemplate;
+import org.jclouds.vcloud.director.v1_5.user.VCloudDirectorAsyncClient;
+
+import com.google.common.base.Function;
+import com.google.common.base.Predicate;
+
+/**
+ * @author danikov
+ */
+@Singleton
+public class VAppTemplatesForCatalogItems implements Function, Iterable> {
+   @Resource
+   @Named(ComputeServiceConstants.COMPUTE_LOGGER)
+   public Logger logger = Logger.NULL;
+   private final VCloudDirectorAsyncClient aclient;
+   private final ExecutorService executor;
+   private final ReturnNullOnAuthorizationException returnNullOnAuthorizationException;
+
+   @Singleton
+   static class ReturnNullOnAuthorizationException implements Function {
+
+      public VAppTemplate apply(Exception from) {
+         if (from instanceof AuthorizationException) {
+            return null;
+         }
+         return propagateOrNull(from);
+      }
+   }
+
+   @Inject
+   VAppTemplatesForCatalogItems(VCloudDirectorAsyncClient aclient,
+            @Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor,
+            ReturnNullOnAuthorizationException returnNullOnAuthorizationException) {
+      this.aclient = aclient;
+      this.executor = executor;
+      this.returnNullOnAuthorizationException = returnNullOnAuthorizationException;
+   }
+
+   @Override
+   public Iterable apply(Iterable from) {
+      return transformParallel(filter(from, new Predicate() {
+
+         @Override
+         public boolean apply(CatalogItem input) {
+            return input.getEntity().getType().equals(VCloudDirectorMediaType.VAPP_TEMPLATE);
+         }
+
+      }), new Function>() {
+
+         @Override
+         public Future apply(CatalogItem from) {
+            return new ExceptionParsingListenableFuture(Futures.makeListenable(VCloudDirectorAsyncClient.class
+                     .cast(aclient).getVAppTemplateClient().getVAppTemplate(from.getEntity().getHref()), executor),
+                     returnNullOnAuthorizationException);
+         }
+
+      }, executor, null, logger, "vappTemplates in");
+   }
+
+}
\ No newline at end of file
diff --git a/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/functions/VAppTemplatesInOrg.java b/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/functions/VAppTemplatesInOrg.java
new file mode 100644
index 0000000000..9d114a5b39
--- /dev/null
+++ b/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/functions/VAppTemplatesInOrg.java
@@ -0,0 +1,70 @@
+/**
+ * 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.vcloud.director.v1_5.functions;
+
+import static com.google.common.base.Predicates.and;
+import static com.google.common.base.Predicates.notNull;
+import static com.google.common.collect.Iterables.filter;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+import org.jclouds.vcloud.director.v1_5.domain.CatalogItem;
+import org.jclouds.vcloud.director.v1_5.domain.ResourceEntity.Status;
+import org.jclouds.vcloud.director.v1_5.domain.VAppTemplate;
+import org.jclouds.vcloud.director.v1_5.domain.org.Org;
+
+import com.google.common.base.Function;
+import com.google.common.base.Predicate;
+import com.google.common.collect.ImmutableSet;
+
+/**
+ * @author danikov
+ */
+@Singleton
+public class VAppTemplatesInOrg implements Function> {
+
+   private final Function> allCatalogItemsInOrg;
+   private final Function, Iterable> vAppTemplatesForCatalogItems;
+
+   @Inject
+   VAppTemplatesInOrg(Function> allCatalogItemsInOrg,
+            Function, Iterable> vAppTemplatesForCatalogItems) {
+      this.allCatalogItemsInOrg = allCatalogItemsInOrg;
+      this.vAppTemplatesForCatalogItems = vAppTemplatesForCatalogItems;
+   }
+
+   @Override
+   public Iterable apply(Org from) {
+      Iterable catalogs = allCatalogItemsInOrg.apply(from);
+      Iterable vAppTemplates = vAppTemplatesForCatalogItems.apply(catalogs);
+      return filter(vAppTemplates, and(notNull(), new Predicate(){
+
+         //TODO: test this
+         @Override
+         public boolean apply(VAppTemplate input) {
+            if (input == null)
+               return false;
+            return ImmutableSet.of(Status.RESOLVED, Status.POWERED_OFF).contains(input.getStatus());
+         }
+         
+      }));
+   }
+
+}
\ No newline at end of file
diff --git a/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/internal/VCloudDirectorContextImpl.java b/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/internal/VCloudDirectorContextImpl.java
index 456c65bf1e..ef8d276ec4 100644
--- a/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/internal/VCloudDirectorContextImpl.java
+++ b/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/internal/VCloudDirectorContextImpl.java
@@ -18,21 +18,13 @@
  */
 package org.jclouds.vcloud.director.v1_5.internal;
 
-import java.net.URI;
-import java.util.Map;
-import java.util.Set;
-
 import javax.inject.Inject;
 import javax.inject.Singleton;
 
-import org.jclouds.domain.Credentials;
 import org.jclouds.lifecycle.Closer;
-import org.jclouds.location.Iso3166;
-import org.jclouds.location.Provider;
+import org.jclouds.providers.ProviderMetadata;
 import org.jclouds.rest.RestContext;
 import org.jclouds.rest.Utils;
-import org.jclouds.rest.annotations.ApiVersion;
-import org.jclouds.rest.annotations.BuildVersion;
 import org.jclouds.rest.annotations.Identity;
 import org.jclouds.rest.internal.RestContextImpl;
 import org.jclouds.vcloud.director.v1_5.VCloudDirectorContext;
@@ -41,7 +33,6 @@ import org.jclouds.vcloud.director.v1_5.admin.VCloudDirectorAdminClient;
 import org.jclouds.vcloud.director.v1_5.user.VCloudDirectorAsyncClient;
 import org.jclouds.vcloud.director.v1_5.user.VCloudDirectorClient;
 
-import com.google.common.base.Supplier;
 import com.google.inject.Injector;
 import com.google.inject.TypeLiteral;
 
@@ -54,14 +45,10 @@ public class VCloudDirectorContextImpl extends RestContextImpl adminContext;
 
    @Inject
-   VCloudDirectorContextImpl(Closer closer, Map credentialStore, Utils utils, Injector injector,
-         TypeLiteral syncApi, TypeLiteral asyncApi, 
-         @Provider Supplier endpoint, @Provider String provider,
-         @Identity String identity, @ApiVersion String apiVersion, @BuildVersion String buildVersion,
-         @Iso3166 Set iso3166Codes,
-         RestContext adminContext) {
-      super(closer, credentialStore, utils, injector, syncApi, asyncApi, endpoint, provider, 
-            identity, apiVersion, buildVersion, iso3166Codes);
+   VCloudDirectorContextImpl(ProviderMetadata providerMetadata, @Identity String identity, Utils utils, Closer closer,
+            Injector injector, RestContext adminContext) {
+      super(providerMetadata, identity, utils, closer, injector, TypeLiteral.get(VCloudDirectorClient.class),
+               TypeLiteral.get(VCloudDirectorAsyncClient.class));
       this.adminContext = adminContext;
    }
    
diff --git a/labs/vcloud-director/src/test/java/org/jclouds/vcloud/director/v1_5/AbstractVAppClientLiveTest.java b/labs/vcloud-director/src/test/java/org/jclouds/vcloud/director/v1_5/AbstractVAppClientLiveTest.java
index df302c2c27..a0d47cb00c 100644
--- a/labs/vcloud-director/src/test/java/org/jclouds/vcloud/director/v1_5/AbstractVAppClientLiveTest.java
+++ b/labs/vcloud-director/src/test/java/org/jclouds/vcloud/director/v1_5/AbstractVAppClientLiveTest.java
@@ -246,7 +246,7 @@ public abstract class AbstractVAppClientLiveTest extends BaseVCloudDirectorClien
    }
 
    /**
-    * Power on a VApp.
+    * Power on a {@link VApp}s {@link Vm}s.
     */
    protected VApp powerOn(final URI testVAppURI) {
       VApp testVApp = vAppClient.getVApp(testVAppURI);
diff --git a/labs/vcloud-director/src/test/java/org/jclouds/vcloud/director/v1_5/HttpClientLiveTest.java b/labs/vcloud-director/src/test/java/org/jclouds/vcloud/director/v1_5/HttpClientLiveTest.java
index d924ddb906..f590ff30d6 100644
--- a/labs/vcloud-director/src/test/java/org/jclouds/vcloud/director/v1_5/HttpClientLiveTest.java
+++ b/labs/vcloud-director/src/test/java/org/jclouds/vcloud/director/v1_5/HttpClientLiveTest.java
@@ -32,7 +32,6 @@ import org.jclouds.http.HttpResponse;
 import org.jclouds.util.Strings2;
 import org.jclouds.vcloud.director.v1_5.domain.SessionWithToken;
 import org.jclouds.vcloud.director.v1_5.domain.org.OrgList;
-import org.jclouds.vcloud.director.v1_5.features.admin.AdminCatalogClient;
 import org.jclouds.vcloud.director.v1_5.internal.BaseVCloudDirectorClientLiveTest;
 import org.jclouds.xml.internal.JAXBParser;
 import org.testng.annotations.Test;
@@ -41,7 +40,7 @@ import com.google.common.collect.ImmutableMultimap;
 import com.google.common.collect.Iterables;
 
 /**
- * Tests live behavior of {@link AdminCatalogClient}.
+ * Tests live behavior of operations that use {@link HttpClient}.
  * 
  * @author danikov
  */
diff --git a/labs/vcloud-director/src/test/java/org/jclouds/vcloud/director/v1_5/VCloudDirectorApiMetadataTest.java b/labs/vcloud-director/src/test/java/org/jclouds/vcloud/director/v1_5/VCloudDirectorApiMetadataTest.java
index 75b501fd07..cb2ce5c443 100644
--- a/labs/vcloud-director/src/test/java/org/jclouds/vcloud/director/v1_5/VCloudDirectorApiMetadataTest.java
+++ b/labs/vcloud-director/src/test/java/org/jclouds/vcloud/director/v1_5/VCloudDirectorApiMetadataTest.java
@@ -18,7 +18,7 @@
  */
 package org.jclouds.vcloud.director.v1_5;
 
-import org.jclouds.Wrapper;
+import org.jclouds.View;
 import org.jclouds.rest.internal.BaseRestApiMetadataTest;
 import org.testng.annotations.Test;
 
@@ -34,6 +34,6 @@ import com.google.common.reflect.TypeToken;
 public class VCloudDirectorApiMetadataTest extends BaseRestApiMetadataTest {
 
    public VCloudDirectorApiMetadataTest() {
-      super(new VCloudDirectorApiMetadata(), ImmutableSet.>of());
+      super(new VCloudDirectorApiMetadata(), ImmutableSet.>of());
    }
 }
diff --git a/labs/vcloud-director/src/test/java/org/jclouds/vcloud/director/v1_5/VCloudDirectorClientExperimentLiveTest.java b/labs/vcloud-director/src/test/java/org/jclouds/vcloud/director/v1_5/VCloudDirectorClientExperimentLiveTest.java
index a6d5c931b6..2375017e99 100644
--- a/labs/vcloud-director/src/test/java/org/jclouds/vcloud/director/v1_5/VCloudDirectorClientExperimentLiveTest.java
+++ b/labs/vcloud-director/src/test/java/org/jclouds/vcloud/director/v1_5/VCloudDirectorClientExperimentLiveTest.java
@@ -34,7 +34,7 @@ public class VCloudDirectorClientExperimentLiveTest extends BaseVCloudDirectorCl
 
    public void testImplicitSession() {
       Session session = context.getApi().getCurrentSession();
-      assertEquals(session.getHref().toASCIIString(), context.getEndpoint().toASCIIString() + "/session/");
+      assertEquals(session.getHref().toASCIIString(), context.getProviderMetadata().getEndpoint() + "/session/");
    }
 
    /**
diff --git a/labs/vcloud-director/src/test/java/org/jclouds/vcloud/director/v1_5/domain/Checks.java b/labs/vcloud-director/src/test/java/org/jclouds/vcloud/director/v1_5/domain/Checks.java
index 15b9f8a2dd..2f4345c595 100644
--- a/labs/vcloud-director/src/test/java/org/jclouds/vcloud/director/v1_5/domain/Checks.java
+++ b/labs/vcloud-director/src/test/java/org/jclouds/vcloud/director/v1_5/domain/Checks.java
@@ -36,6 +36,7 @@ import static org.jclouds.vcloud.director.v1_5.VCloudDirectorLiveTestConstants.R
 import static org.jclouds.vcloud.director.v1_5.VCloudDirectorLiveTestConstants.REQUIRED_VALUE_OBJECT_FMT;
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertNotEquals;
 import static org.testng.Assert.assertNotNull;
 import static org.testng.Assert.assertTrue;
 import static org.testng.Assert.fail;
@@ -73,23 +74,22 @@ import org.jclouds.vcloud.director.v1_5.domain.network.NetworkServiceType;
 import org.jclouds.vcloud.director.v1_5.domain.network.RouterInfo;
 import org.jclouds.vcloud.director.v1_5.domain.network.SyslogServerSettings;
 import org.jclouds.vcloud.director.v1_5.domain.network.VAppNetworkConfiguration;
-import org.jclouds.vcloud.director.v1_5.domain.network.NetworkConnection.IpAddressAllocationMode;
 import org.jclouds.vcloud.director.v1_5.domain.org.AdminOrg;
 import org.jclouds.vcloud.director.v1_5.domain.org.CustomOrgLdapSettings;
+import org.jclouds.vcloud.director.v1_5.domain.org.CustomOrgLdapSettings.AuthenticationMechanism;
+import org.jclouds.vcloud.director.v1_5.domain.org.CustomOrgLdapSettings.ConnectorType;
 import org.jclouds.vcloud.director.v1_5.domain.org.Org;
 import org.jclouds.vcloud.director.v1_5.domain.org.OrgEmailSettings;
 import org.jclouds.vcloud.director.v1_5.domain.org.OrgGeneralSettings;
 import org.jclouds.vcloud.director.v1_5.domain.org.OrgLdapGroupAttributes;
 import org.jclouds.vcloud.director.v1_5.domain.org.OrgLdapSettings;
+import org.jclouds.vcloud.director.v1_5.domain.org.OrgLdapSettings.LdapMode;
 import org.jclouds.vcloud.director.v1_5.domain.org.OrgLdapUserAttributes;
 import org.jclouds.vcloud.director.v1_5.domain.org.OrgLeaseSettings;
 import org.jclouds.vcloud.director.v1_5.domain.org.OrgNetwork;
 import org.jclouds.vcloud.director.v1_5.domain.org.OrgPasswordPolicySettings;
 import org.jclouds.vcloud.director.v1_5.domain.org.OrgSettings;
 import org.jclouds.vcloud.director.v1_5.domain.org.OrgVAppTemplateLeaseSettings;
-import org.jclouds.vcloud.director.v1_5.domain.org.CustomOrgLdapSettings.AuthenticationMechanism;
-import org.jclouds.vcloud.director.v1_5.domain.org.CustomOrgLdapSettings.ConnectorType;
-import org.jclouds.vcloud.director.v1_5.domain.org.OrgLdapSettings.LdapMode;
 import org.jclouds.vcloud.director.v1_5.domain.params.ControlAccessParams;
 import org.jclouds.vcloud.director.v1_5.domain.query.ContainerType;
 import org.jclouds.vcloud.director.v1_5.domain.query.QueryResultRecordType;
@@ -1255,9 +1255,8 @@ public class Checks {
       // Check required fields
       assertNotNull(val.getNetwork(), String.format(NOT_NULL_OBJ_FIELD_FMT, "Network", "NetworkConnection"));
       assertNotNull(val.getIpAddressAllocationMode(), String.format(NOT_NULL_OBJ_FIELD_FMT, "IpAddressAllocationMode", "NetworkConnection"));
-      IpAddressAllocationMode mode = NetworkConnection.IpAddressAllocationMode.valueOf(val.getIpAddressAllocationMode());
-      assertTrue(NetworkConnection.IpAddressAllocationMode.ALL.contains(mode), 
-               String.format(REQUIRED_VALUE_OBJECT_FMT, "IpAddressAllocationMode", "NetworkConnection", val.getIpAddressAllocationMode(), Iterables.toString(NetworkConnection.IpAddressAllocationMode.ALL)));
+      assertNotEquals(val.getIpAddressAllocationMode(), NetworkConnection.IpAddressAllocationMode.UNRECOGNIZED,
+            String.format(REQUIRED_VALUE_OBJECT_FMT, "IpAddressAllocationMode", "NetworkConnection", val.getIpAddressAllocationMode(), Iterables.toString(NetworkConnection.IpAddressAllocationMode.ALL)));
       
       // Check optional fields
       if (val.getIpAddress() != null) {
diff --git a/labs/vcloud-director/src/test/java/org/jclouds/vcloud/director/v1_5/features/VAppClientLiveTest.java b/labs/vcloud-director/src/test/java/org/jclouds/vcloud/director/v1_5/features/VAppClientLiveTest.java
index 476fa75c4e..edb255169c 100644
--- a/labs/vcloud-director/src/test/java/org/jclouds/vcloud/director/v1_5/features/VAppClientLiveTest.java
+++ b/labs/vcloud-director/src/test/java/org/jclouds/vcloud/director/v1_5/features/VAppClientLiveTest.java
@@ -19,8 +19,8 @@
 package org.jclouds.vcloud.director.v1_5.features;
 
 import static com.google.common.base.Predicates.and;
-import static com.google.common.collect.Iterables.find;
 import static com.google.common.collect.Iterables.contains;
+import static com.google.common.collect.Iterables.find;
 import static com.google.common.collect.Iterables.getFirst;
 import static org.jclouds.vcloud.director.v1_5.VCloudDirectorLiveTestConstants.CONDITION_FMT;
 import static org.jclouds.vcloud.director.v1_5.VCloudDirectorLiveTestConstants.CORRECT_VALUE_OBJECT_FMT;
@@ -58,8 +58,8 @@ import static org.jclouds.vcloud.director.v1_5.predicates.LinkPredicates.typeEqu
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertFalse;
 import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertNull;
 import static org.testng.Assert.assertTrue;
-import static org.testng.Assert.fail;
 
 import java.math.BigInteger;
 import java.net.URI;
@@ -68,15 +68,14 @@ import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.TimeUnit;
 
-import org.jclouds.io.Payloads;
 import org.jclouds.dmtf.cim.OSType;
 import org.jclouds.dmtf.cim.ResourceAllocationSettingData;
 import org.jclouds.dmtf.ovf.MsgType;
 import org.jclouds.dmtf.ovf.NetworkSection;
 import org.jclouds.dmtf.ovf.ProductSection;
 import org.jclouds.dmtf.ovf.StartupSection;
+import org.jclouds.io.Payloads;
 import org.jclouds.vcloud.director.v1_5.AbstractVAppClientLiveTest;
-import org.jclouds.vcloud.director.v1_5.VCloudDirectorException;
 import org.jclouds.vcloud.director.v1_5.VCloudDirectorMediaType;
 import org.jclouds.vcloud.director.v1_5.domain.AccessSetting;
 import org.jclouds.vcloud.director.v1_5.domain.Checks;
@@ -1286,11 +1285,7 @@ public class VAppClientLiveTest extends AbstractVAppClientLiveTest {
       Task deleteVApp = vAppClient.deleteVApp(temp.getHref());
       assertTrue(retryTaskSuccess.apply(deleteVApp), String.format(TASK_COMPLETE_TIMELY, "deleteVApp"));
 
-      try {
-         vAppClient.getVApp(temp.getHref());
-         fail("The VApp "+temp+" should have been deleted");
-      } catch (VCloudDirectorException vcde) {
-         assertEquals(vcde.getError().getMajorErrorCode(), Integer.valueOf(403), "The error code for deleted vApp should have been 'Forbidden' (403)");
-      }
+      VApp deleted = vAppClient.getVApp(temp.getHref());
+      assertNull(deleted, "The VApp "+temp.getName()+" should have been deleted");
    }
 }
diff --git a/labs/vcloud-director/src/test/java/org/jclouds/vcloud/director/v1_5/handlers/InvalidateSessionAndRetryOn401AndLogoutOnCloseTest.java b/labs/vcloud-director/src/test/java/org/jclouds/vcloud/director/v1_5/handlers/InvalidateSessionAndRetryOn401AndLogoutOnCloseTest.java
index 24183b5695..ec0f1dc55e 100644
--- a/labs/vcloud-director/src/test/java/org/jclouds/vcloud/director/v1_5/handlers/InvalidateSessionAndRetryOn401AndLogoutOnCloseTest.java
+++ b/labs/vcloud-director/src/test/java/org/jclouds/vcloud/director/v1_5/handlers/InvalidateSessionAndRetryOn401AndLogoutOnCloseTest.java
@@ -42,6 +42,7 @@ import com.google.common.cache.LoadingCache;
  */
 @Test(groups = "unit", testName = "InvalidateSessionAndRetryOn401AndLogoutOnCloseTest")
 public class InvalidateSessionAndRetryOn401AndLogoutOnCloseTest {
+   @SuppressWarnings("unchecked")
    @Test
    public void test401ShouldInvalidateSessionAndRetry() {
       HttpCommand command = createMock(HttpCommand.class);
diff --git a/labs/vcloud-director/src/test/java/org/jclouds/vcloud/director/v1_5/internal/BaseVCloudDirectorClientLiveTest.java b/labs/vcloud-director/src/test/java/org/jclouds/vcloud/director/v1_5/internal/BaseVCloudDirectorClientLiveTest.java
index 12b093af8e..29148e5ff0 100644
--- a/labs/vcloud-director/src/test/java/org/jclouds/vcloud/director/v1_5/internal/BaseVCloudDirectorClientLiveTest.java
+++ b/labs/vcloud-director/src/test/java/org/jclouds/vcloud/director/v1_5/internal/BaseVCloudDirectorClientLiveTest.java
@@ -179,8 +179,6 @@ public abstract class BaseVCloudDirectorClientLiveTest extends BaseContextLiveTe
             .overrides(overrides)
             .build();
 
-      System.err.println("*** " + endpoint + " ***");
-
       context = testSession.getUserContext();
       adminContext = testSession.getAdminContext();
 
@@ -210,7 +208,7 @@ public abstract class BaseVCloudDirectorClientLiveTest extends BaseContextLiveTe
 
    public static Reference getRoleReferenceFor(String name, RestContext adminContext) {
       RoleReferences roles = adminContext.getApi().getQueryClient().roleReferencesQueryAll();
-      // wrapped in a builder to strip out unwanted xml cruft that the api chokes on
+      // backend in a builder to strip out unwanted xml cruft that the api chokes on
       return Reference.builder().fromReference(Iterables.find(roles.getReferences(), ReferencePredicates.nameEquals(name))).build();
    }
 
@@ -407,7 +405,7 @@ public abstract class BaseVCloudDirectorClientLiveTest extends BaseContextLiveTe
       // Build the configuration object
       NetworkConfiguration networkConfiguration = NetworkConfiguration.builder()
             .parentNetwork(parentNetwork.get())
-            .fenceMode(Network.FenceMode.ISOLATED)
+            .fenceMode(Network.FenceMode.BRIDGED)
             .build();
 
       return networkConfiguration;
@@ -452,7 +450,7 @@ public abstract class BaseVCloudDirectorClientLiveTest extends BaseContextLiveTe
       }
 
       // Shutdown and power off the VApp if necessary
-      if (vApp.getStatus().equals(Status.POWERED_ON.getValue())) {
+      if (vApp.getStatus() == Status.POWERED_ON) {
          try {
             Task shutdownTask = vAppClient.shutdown(vAppURI);
             taskDoneEventually(shutdownTask);
diff --git a/labs/vcloud-director/src/test/java/org/jclouds/vcloud/director/v1_5/internal/VCloudDirectorTestSession.java b/labs/vcloud-director/src/test/java/org/jclouds/vcloud/director/v1_5/internal/VCloudDirectorTestSession.java
index 858e98d7db..4199435c16 100644
--- a/labs/vcloud-director/src/test/java/org/jclouds/vcloud/director/v1_5/internal/VCloudDirectorTestSession.java
+++ b/labs/vcloud-director/src/test/java/org/jclouds/vcloud/director/v1_5/internal/VCloudDirectorTestSession.java
@@ -1,12 +1,8 @@
 package org.jclouds.vcloud.director.v1_5.internal;
 
-import static com.google.common.base.Objects.equal;
-import static org.jclouds.vcloud.director.v1_5.VCloudDirectorLiveTestConstants.REF_REQ_LIVE;
-import static org.testng.Assert.assertNotNull;
-import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.assertEquals;
 
 import java.io.Closeable;
-import java.net.URI;
 import java.util.Properties;
 
 import org.jclouds.ContextBuilder;
@@ -14,16 +10,17 @@ import org.jclouds.logging.log4j.config.Log4JLoggingModule;
 import org.jclouds.rest.RestContext;
 import org.jclouds.sshj.config.SshjSshClientModule;
 import org.jclouds.vcloud.director.v1_5.VCloudDirectorContext;
+import org.jclouds.vcloud.director.v1_5.VCloudDirectorMediaType;
 import org.jclouds.vcloud.director.v1_5.admin.VCloudDirectorAdminAsyncClient;
 import org.jclouds.vcloud.director.v1_5.admin.VCloudDirectorAdminClient;
 import org.jclouds.vcloud.director.v1_5.domain.Link;
 import org.jclouds.vcloud.director.v1_5.domain.Reference;
 import org.jclouds.vcloud.director.v1_5.domain.Role.DefaultRoles;
 import org.jclouds.vcloud.director.v1_5.domain.User;
+import org.jclouds.vcloud.director.v1_5.predicates.LinkPredicates;
 import org.jclouds.vcloud.director.v1_5.predicates.ReferencePredicates;
-import org.jclouds.vcloud.director.v1_5.user.VCloudDirectorAsyncClient;
-import org.jclouds.vcloud.director.v1_5.user.VCloudDirectorClient;
 
+import com.google.common.base.Predicates;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Iterables;
 import com.google.common.io.Closeables;
@@ -73,11 +70,8 @@ public class VCloudDirectorTestSession implements Closeable {
       }
    }
 
+   private VCloudDirectorContext userContext;
    private RestContext adminContext;
-   private RestContext userContext;
-
-   private User createdAdminUser;
-   private User createdUser;
 
    private VCloudDirectorTestSession(String provider, String identity, String credential, Properties overrides, String endpoint) {
       ContextBuilder builder = ContextBuilder.newBuilder(provider)
@@ -85,77 +79,39 @@ public class VCloudDirectorTestSession implements Closeable {
             .endpoint(endpoint)
             .modules(ImmutableSet. of(new Log4JLoggingModule(), new SshjSshClientModule()))
             .overrides(overrides);
-      VCloudDirectorContext rootContext = VCloudDirectorContext.class.cast(builder.build());
+      userContext = VCloudDirectorContext.class.cast(builder.build());
 
-      if (rootContext.getApi().getCurrentSession().getLinks().contains(Link.builder()
-	         .rel("down")
-	         .type("application/vnd.vmware.admin.vcloud+xml")
-	         .href(URI.create(endpoint+"/admin/"))
-	         .build())) {
+      // Look for the admin link in the current session
+      Link admin = Iterables.tryFind(
+	            userContext.getApi().getCurrentSession().getLinks(),
+	            Predicates.and(LinkPredicates.relEquals(Link.Rel.DOWN), ReferencePredicates.typeEquals(VCloudDirectorMediaType.ADMIN)))
+            .orNull();
 
-         adminContext = rootContext.getAdminContext();
+      // Get the admin context if the link exists
+      if (admin != null) {
+         adminContext = userContext.getAdminContext();
 
-         Reference orgRef = Iterables.getFirst(rootContext.getApi().getOrgClient().getOrgList().getOrgs(), null)
+         // Lookup the user details
+         Reference orgRef = Iterables.getFirst(userContext.getApi().getOrgClient().getOrgList().getOrgs(), null)
                .toAdminReference(endpoint);
-         assertNotNull(orgRef, String.format(REF_REQ_LIVE, "admin org"));
-
-         Reference userRef = Iterables.find(adminContext.getApi().getOrgClient().getOrg(orgRef.getHref()).getUsers(),
+         Reference userRef = Iterables.find(
+               adminContext.getApi().getOrgClient().getOrg(orgRef.getHref()).getUsers(),
                ReferencePredicates.nameEquals(adminContext.getApi().getCurrentSession().getUser()));
-
          User user = adminContext.getApi().getUserClient().getUser(userRef.getHref());
-         Reference orgAdmin = user.getRole();
-         assertTrue(equal(orgAdmin.getName(), DefaultRoles.ORG_ADMIN.value()), "must give org admin or user-only credentials");
 
-         String adminIdentity = "testAdmin"+BaseVCloudDirectorClientLiveTest.getTestDateTimeStamp();
-         String adminCredential = "testAdminPassword";
-
-         createdAdminUser = rootContext.getAdminContext().getApi().getUserClient().createUser(orgRef.getHref(), User.builder()
-            .name(adminIdentity)
-            .password(adminCredential)
-            .description("test user with user-level privileges")
-            .role(orgAdmin)
-            .deployedVmQuota(BaseVCloudDirectorClientLiveTest.REQUIRED_ADMIN_VM_QUOTA)
-            .isEnabled(true)
-            .build());
-
-         Closeables.closeQuietly(rootContext);
-
-         builder.credentials(adminIdentity, adminCredential);
-         adminContext = VCloudDirectorContext.class.cast(builder.build()).getAdminContext();
-
-         String userIdentity = "test"+BaseVCloudDirectorClientLiveTest.getTestDateTimeStamp();
-         String userCredential = "testPassword";
-
-         createdUser = adminContext.getApi().getUserClient().createUser(orgRef.getHref(), User.builder()
-            .name(userIdentity)
-            .password(userCredential)
-            .description("test user with user-level privileges")
-            .role(BaseVCloudDirectorClientLiveTest.getRoleReferenceFor(DefaultRoles.USER.value(), adminContext))
-            .deployedVmQuota(BaseVCloudDirectorClientLiveTest.REQUIRED_USER_VM_QUOTA)
-            .isEnabled(true)
-            .build());
-
-         builder.credentials(userIdentity, userCredential);
-         userContext = VCloudDirectorContext.class.cast(builder.build());
-      } else {
-         userContext = rootContext;
+         // Check that the user has the org admin role
+         Reference userRole = user.getRole();
+         assertEquals(userRole.getName(), DefaultRoles.ORG_ADMIN.value());
       }
    }
 
    @Override
    public void close() {
-      if (createdUser != null) {
-         adminContext.getApi().getUserClient().deleteUser(createdUser.getHref());
-      }
-      if (userContext != null) userContext.close();
-      if (createdAdminUser != null) {
-         // TODO: may have to preserve root context if we can't delete the user for it's own context here
-         adminContext.getApi().getUserClient().deleteUser(createdAdminUser.getHref());
-      }
-      if (adminContext != null) adminContext.close();
+      Closeables.closeQuietly(userContext);
+      Closeables.closeQuietly(adminContext);
    }
 
-   public RestContext getUserContext() {
+   public VCloudDirectorContext getUserContext() {
       return userContext;
    }
 
diff --git a/labs/vcloud-director/src/test/java/org/jclouds/vcloud/director/v1_5/login/SessionClientLiveTest.java b/labs/vcloud-director/src/test/java/org/jclouds/vcloud/director/v1_5/login/SessionClientLiveTest.java
index f733e733d4..3cb1e1743f 100644
--- a/labs/vcloud-director/src/test/java/org/jclouds/vcloud/director/v1_5/login/SessionClientLiveTest.java
+++ b/labs/vcloud-director/src/test/java/org/jclouds/vcloud/director/v1_5/login/SessionClientLiveTest.java
@@ -23,15 +23,16 @@ import static org.testng.Assert.assertNotNull;
 import static org.testng.Assert.assertTrue;
 
 import java.net.URI;
-import java.util.Properties;
 
-import org.jclouds.Constants;
-import org.jclouds.apis.ApiMetadata;
+import org.jclouds.ContextBuilder;
 import org.jclouds.apis.BaseContextLiveTest;
-import org.jclouds.rest.AnonymousRestApiMetadata;
+import org.jclouds.providers.AnonymousProviderMetadata;
+import org.jclouds.providers.ProviderMetadata;
 import org.jclouds.rest.RestContext;
 import org.jclouds.vcloud.director.testng.FormatApiResultsListener;
+import org.jclouds.vcloud.director.v1_5.VCloudDirectorConstants;
 import org.jclouds.vcloud.director.v1_5.domain.SessionWithToken;
+import org.jclouds.vcloud.director.v1_5.user.VCloudDirectorClient;
 import org.testng.annotations.BeforeGroups;
 import org.testng.annotations.Listeners;
 import org.testng.annotations.Test;
@@ -39,18 +40,20 @@ import org.testng.annotations.Test;
 import com.google.common.reflect.TypeToken;
 
 /**
- * Tests behavior of {@code SessionClient}. Note this class is tested completely independently of
- * VCloudClient as it is a dependency of the VCloud context working.
+ * Tests behavior of {@link SessionClient}. Note this class is tested completely independently of
+ * {@link VCloudDirectorClient} as it is a dependency of the {@code vcloud-director} context working.
  * 
  * @author Adrian Cole
  */
 @Listeners(FormatApiResultsListener.class)
-@Test(groups = { "live", "user", "login" }, testName = "SessionClientLiveTest")
+@Test(groups = { "live", "user" }, testName = "SessionClientLiveTest")
 public class SessionClientLiveTest extends BaseContextLiveTest> {
+
    public SessionClientLiveTest() {
       provider = "vcloud-director";
    }
 
+   @Override
    @BeforeGroups(groups = { "live" })
    public void setupContext() {
       super.setupContext();
@@ -60,25 +63,6 @@ public class SessionClientLiveTest extends BaseContextLiveTest> contextType() {
-      return new TypeToken>(){
-
-         /** The serialVersionUID */
-         private static final long serialVersionUID = -3625362618882122604L;};
+      return VCloudDirectorConstants.SESSION_CONTEXT_TYPE;
    }
+
+   @Override
+   protected ProviderMetadata createProviderMetadata() {
+      return AnonymousProviderMetadata.forClientMappedToAsyncClientOnEndpoint(SessionClient.class, SessionAsyncClient.class, endpoint);
+   }
+
+   @Override
+   protected ContextBuilder newBuilder() {
+      ProviderMetadata pm = createProviderMetadata();
+      ContextBuilder builder = ContextBuilder.newBuilder(pm);
+      return builder;
+   }
+
 }
diff --git a/labs/virtualbox/src/main/java/org/jclouds/virtualbox/VirtualBoxApiMetadata.java b/labs/virtualbox/src/main/java/org/jclouds/virtualbox/VirtualBoxApiMetadata.java
index 7a6d3cdec3..00d3069fda 100644
--- a/labs/virtualbox/src/main/java/org/jclouds/virtualbox/VirtualBoxApiMetadata.java
+++ b/labs/virtualbox/src/main/java/org/jclouds/virtualbox/VirtualBoxApiMetadata.java
@@ -105,7 +105,7 @@ public class VirtualBoxApiMetadata extends BaseApiMetadata {
          .version("4.1.4")
          .buildVersion("4.1.8r75467")
          .defaultProperties(VirtualBoxApiMetadata.defaultProperties())
-         .wrapper(ComputeServiceContext.class)
+         .view(ComputeServiceContext.class)
          .defaultModules(ImmutableSet.>of(DefaultCacheNodeStoreModule.class, VirtualBoxComputeServiceContextModule.class));
       }
 
diff --git a/labs/virtualbox/src/main/java/org/jclouds/virtualbox/config/VirtualBoxComputeServiceContextModule.java b/labs/virtualbox/src/main/java/org/jclouds/virtualbox/config/VirtualBoxComputeServiceContextModule.java
index 120c862921..399813766a 100644
--- a/labs/virtualbox/src/main/java/org/jclouds/virtualbox/config/VirtualBoxComputeServiceContextModule.java
+++ b/labs/virtualbox/src/main/java/org/jclouds/virtualbox/config/VirtualBoxComputeServiceContextModule.java
@@ -27,7 +27,6 @@ import java.io.File;
 import java.io.InputStream;
 import java.net.URI;
 import java.util.Map;
-import java.util.Set;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.TimeUnit;
 
@@ -40,12 +39,11 @@ import org.jclouds.byon.Node;
 import org.jclouds.byon.functions.NodeToNodeMetadata;
 import org.jclouds.byon.suppliers.SupplyFromProviderURIOrNodesProperty;
 import org.jclouds.compute.ComputeServiceAdapter;
-import org.jclouds.compute.ComputeServiceAdapter.NodeAndInitialCredentials;
 import org.jclouds.compute.ComputeServiceContext;
 import org.jclouds.compute.ImageExtension;
+import org.jclouds.compute.ComputeServiceAdapter.NodeAndInitialCredentials;
 import org.jclouds.compute.config.ComputeServiceAdapterContextModule;
 import org.jclouds.compute.domain.Hardware;
-import org.jclouds.compute.domain.HardwareBuilder;
 import org.jclouds.compute.domain.Image;
 import org.jclouds.compute.domain.NodeMetadata;
 import org.jclouds.compute.domain.NodeState;
@@ -81,7 +79,6 @@ import org.jclouds.virtualbox.functions.admin.ImagesToYamlImagesFromYamlDescript
 import org.jclouds.virtualbox.functions.admin.PreseedCfgServer;
 import org.jclouds.virtualbox.functions.admin.StartVBoxIfNotAlreadyRunning;
 import org.jclouds.virtualbox.predicates.SshResponds;
-import org.testng.internal.annotations.Sets;
 import org.virtualbox_4_1.IMachine;
 import org.virtualbox_4_1.LockType;
 import org.virtualbox_4_1.MachineState;
diff --git a/labs/virtualbox/src/main/java/org/jclouds/virtualbox/domain/ErrorCode.java b/labs/virtualbox/src/main/java/org/jclouds/virtualbox/domain/ErrorCode.java
index 96255ac145..d8ba972968 100644
--- a/labs/virtualbox/src/main/java/org/jclouds/virtualbox/domain/ErrorCode.java
+++ b/labs/virtualbox/src/main/java/org/jclouds/virtualbox/domain/ErrorCode.java
@@ -76,9 +76,9 @@ public enum ErrorCode {
     * @return an ErrorCode representing the given fault code.
     */
    public static ErrorCode valueOf(VBoxException vboxException) {
-      final Throwable wrapped = vboxException.getWrapped();
-      if (wrapped instanceof RuntimeFaultMsg) {
-         final RuntimeFaultMsg faultCode = (RuntimeFaultMsg) wrapped;
+      final Throwable backend = vboxException.getWrapped();
+      if (backend instanceof RuntimeFaultMsg) {
+         final RuntimeFaultMsg faultCode = (RuntimeFaultMsg) backend;
          final int resultCode = faultCode.getFaultInfo().getResultCode();
          final ErrorCode errorCode = table.get(unsignedIntToLong(resultCode));
          if (errorCode != null) {
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 33477e5d2d..44f21bca60 100644
--- a/labs/virtualbox/src/test/java/org/jclouds/virtualbox/BaseVirtualBoxClientLiveTest.java
+++ b/labs/virtualbox/src/test/java/org/jclouds/virtualbox/BaseVirtualBoxClientLiveTest.java
@@ -137,7 +137,7 @@ public class BaseVirtualBoxClientLiveTest extends BaseComputeServiceContextLiveT
    @BeforeClass(groups = { "integration", "live" })
    public void setupContext() {
       super.setupContext();
-      context.utils().injector().injectMembers(this);
+      view.utils().injector().injectMembers(this);
 
       YamlImage image = getDefaultImage();
 
@@ -145,13 +145,13 @@ public class BaseVirtualBoxClientLiveTest extends BaseComputeServiceContextLiveT
       masterVmName = VIRTUALBOX_IMAGE_PREFIX + image.id;
       isosDir = workingDir + File.separator + "isos";
 
-      hostVersion = Iterables.get(Splitter.on('r').split(context.utils().injector().getInstance(Key.get(String.class, BuildVersion.class))), 0);
+      hostVersion = Iterables.get(Splitter.on('r').split(view.utils().injector().getInstance(Key.get(String.class, BuildVersion.class))), 0);
       operatingSystemIso = String.format("%s/%s.iso", isosDir, image.name);
       guestAdditionsIso = String.format("%s/VBoxGuestAdditions_%s.iso", isosDir, hostVersion);
 
       // try and get a master from the cache, this will initialize the config/download isos and
       // prepare everything IF a master is not available, subsequent calls should be pretty fast
-      Template template = context.getComputeService().templateBuilder().build();
+      Template template = view.getComputeService().templateBuilder().build();
       checkNotNull(mastersCache.apply(template.getImage()));
    }
 
@@ -195,7 +195,7 @@ public class BaseVirtualBoxClientLiveTest extends BaseComputeServiceContextLiveT
       VmSpec sourceVmSpec = VmSpec.builder().id(masterName).name(masterName).osTypeId("").memoryMB(512)
                .cleanUpMode(CleanupMode.Full).controller(ideController).forceOverwrite(true).build();
 
-      Injector injector = context.utils().injector();
+      Injector injector = view.utils().injector();
       Function configProperties = injector.getInstance(ValueOfConfigurationKeyOrNull.class);
       IsoSpec isoSpec = IsoSpec
                .builder()
@@ -226,8 +226,8 @@ public class BaseVirtualBoxClientLiveTest extends BaseComputeServiceContextLiveT
 
    @AfterClass(groups = "live")
    protected void tearDown() throws Exception {
-      if (context != null)
-         context.close();
+      if (view != null)
+         view.close();
    }
 
    @AfterSuite
diff --git a/labs/virtualbox/src/test/java/org/jclouds/virtualbox/compute/VirtualBoxComputeServiceAdapterLiveTest.java b/labs/virtualbox/src/test/java/org/jclouds/virtualbox/compute/VirtualBoxComputeServiceAdapterLiveTest.java
index 525331adf8..ad5d2144a4 100644
--- a/labs/virtualbox/src/test/java/org/jclouds/virtualbox/compute/VirtualBoxComputeServiceAdapterLiveTest.java
+++ b/labs/virtualbox/src/test/java/org/jclouds/virtualbox/compute/VirtualBoxComputeServiceAdapterLiveTest.java
@@ -52,7 +52,7 @@ public class VirtualBoxComputeServiceAdapterLiveTest extends BaseVirtualBoxClien
    public void testCreatedNodeHasExpectedNameAndWeCanConnectViaSsh() {
       String group = "foo";
       String name = "foo-ef4";
-      Template template = context.getComputeService().templateBuilder().build();
+      Template template = view.getComputeService().templateBuilder().build();
       machine = adapter.createNodeWithGroupEncodedIntoName(group, name, template);
       assertTrue(machine.getNode().getName().contains(group));
       assertTrue(machine.getNode().getName().contains(name));
@@ -61,7 +61,7 @@ public class VirtualBoxComputeServiceAdapterLiveTest extends BaseVirtualBoxClien
    }
 
    protected void doConnectViaSsh(IMachine machine, LoginCredentials creds) {
-      SshClient ssh = context.utils().injector().getInstance(IMachineToSshClient.class).apply(machine);
+      SshClient ssh = view.utils().injector().getInstance(IMachineToSshClient.class).apply(machine);
       try {
          ssh.connect();
          ExecResponse hello = ssh.exec("echo hello");
diff --git a/labs/virtualbox/src/test/java/org/jclouds/virtualbox/functions/CloneAndRegisterMachineFromIMachineIfNotAlreadyExistsLiveTest.java b/labs/virtualbox/src/test/java/org/jclouds/virtualbox/functions/CloneAndRegisterMachineFromIMachineIfNotAlreadyExistsLiveTest.java
index 8c8b1445ac..e159029794 100644
--- a/labs/virtualbox/src/test/java/org/jclouds/virtualbox/functions/CloneAndRegisterMachineFromIMachineIfNotAlreadyExistsLiveTest.java
+++ b/labs/virtualbox/src/test/java/org/jclouds/virtualbox/functions/CloneAndRegisterMachineFromIMachineIfNotAlreadyExistsLiveTest.java
@@ -75,7 +75,7 @@ public class CloneAndRegisterMachineFromIMachineIfNotAlreadyExistsLiveTest exten
       VmSpec instanceVmSpec = VmSpec.builder().id(instanceName).name(instanceName).osTypeId("").memoryMB(512)
                .cleanUpMode(CleanupMode.Full).controller(ideController).forceOverwrite(true).build();
 
-      Injector injector = context.utils().injector();
+      Injector injector = view.utils().injector();
       Function configProperties = injector.getInstance(ValueOfConfigurationKeyOrNull.class);
       IsoSpec isoSpec = IsoSpec
                .builder()
@@ -108,7 +108,7 @@ public class CloneAndRegisterMachineFromIMachineIfNotAlreadyExistsLiveTest exten
    private IMachine getVmWithGuestAdditionsInstalled() {
       MasterSpec masterSpecForTest = super.getMasterSpecForTest();
       try {
-         Injector injector = context.utils().injector();
+         Injector injector = view.utils().injector();
          return injector.getInstance(CreateAndInstallVm.class).apply(masterSpecForTest);
       } catch (IllegalStateException e) {
          // already created
diff --git a/labs/virtualbox/src/test/java/org/jclouds/virtualbox/functions/CreateAndInstallVmLiveTest.java b/labs/virtualbox/src/test/java/org/jclouds/virtualbox/functions/CreateAndInstallVmLiveTest.java
index 45bd5dfa11..b3b22ffc3a 100644
--- a/labs/virtualbox/src/test/java/org/jclouds/virtualbox/functions/CreateAndInstallVmLiveTest.java
+++ b/labs/virtualbox/src/test/java/org/jclouds/virtualbox/functions/CreateAndInstallVmLiveTest.java
@@ -133,7 +133,7 @@ public class CreateAndInstallVmLiveTest extends BaseVirtualBoxClientLiveTest {
       VmSpec instanceVmSpec = VmSpec.builder().id(instanceName).name(instanceName).osTypeId("").memoryMB(512)
                .cleanUpMode(CleanupMode.Full).controller(ideController).forceOverwrite(true).build();
 
-      injector = context.utils().injector();
+      injector = view.utils().injector();
       Function configProperties = injector.getInstance(ValueOfConfigurationKeyOrNull.class);
       IsoSpec isoSpec = IsoSpec
                .builder()
@@ -190,7 +190,7 @@ public class CreateAndInstallVmLiveTest extends BaseVirtualBoxClientLiveTest {
    private IMachine getVmWithGuestAdditionsInstalled() {
       MasterSpec masterSpecForTest = super.getMasterSpecForTest();
       try {
-         Injector injector = context.utils().injector();
+         Injector injector = view.utils().injector();
          return injector.getInstance(CreateAndInstallVm.class).apply(masterSpecForTest);
       } catch (IllegalStateException e) {
          // already created
diff --git a/labs/virtualbox/src/test/java/org/jclouds/virtualbox/functions/CreateAndRegisterMachineFromIsoIfNotAlreadyExistsLiveTest.java b/labs/virtualbox/src/test/java/org/jclouds/virtualbox/functions/CreateAndRegisterMachineFromIsoIfNotAlreadyExistsLiveTest.java
index dafab24618..72c9aff546 100644
--- a/labs/virtualbox/src/test/java/org/jclouds/virtualbox/functions/CreateAndRegisterMachineFromIsoIfNotAlreadyExistsLiveTest.java
+++ b/labs/virtualbox/src/test/java/org/jclouds/virtualbox/functions/CreateAndRegisterMachineFromIsoIfNotAlreadyExistsLiveTest.java
@@ -84,7 +84,7 @@ public class CreateAndRegisterMachineFromIsoIfNotAlreadyExistsLiveTest extends B
                .iso(IsoSpec.builder().sourcePath(operatingSystemIso).installationScript("").build()).vm(vmSpec)
                .network(networkSpec).build();
       // undoVm(vmSpec);
-      IMachine debianNode = context.utils().injector()
+      IMachine debianNode = view.utils().injector()
                .getInstance(CreateAndRegisterMachineFromIsoIfNotAlreadyExists.class).apply(machineSpec);
       IMachine machine = manager.get().getVBox().findMachine(vmName);
       assertEquals(debianNode.getName(), machine.getName());
@@ -107,7 +107,7 @@ public class CreateAndRegisterMachineFromIsoIfNotAlreadyExistsLiveTest extends B
       NetworkSpec networkSpec = NetworkSpec.builder().build();
       MasterSpec machineSpec = MasterSpec.builder().iso(isoSpec).vm(vmSpec).network(networkSpec).build();
       try {
-         Injector injector = context.utils().injector();
+         Injector injector = view.utils().injector();
          injector.getInstance(CreateAndRegisterMachineFromIsoIfNotAlreadyExists.class).apply(machineSpec);
          fail();
       } catch (VBoxException e) {
diff --git a/labs/virtualbox/src/test/java/org/jclouds/virtualbox/predicates/GuestAdditionsInstallerLiveTest.java b/labs/virtualbox/src/test/java/org/jclouds/virtualbox/predicates/GuestAdditionsInstallerLiveTest.java
index e611e50848..8c79df17fb 100644
--- a/labs/virtualbox/src/test/java/org/jclouds/virtualbox/predicates/GuestAdditionsInstallerLiveTest.java
+++ b/labs/virtualbox/src/test/java/org/jclouds/virtualbox/predicates/GuestAdditionsInstallerLiveTest.java
@@ -72,7 +72,7 @@ public class GuestAdditionsInstallerLiveTest extends BaseVirtualBoxClientLiveTes
    @BeforeClass(groups = "live")
    public void setupContext() {
       super.setupContext();
-      injector = context.utils().injector();
+      injector = view.utils().injector();
 
       String instanceName = VIRTUALBOX_IMAGE_PREFIX
                + CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_HYPHEN, getClass().getSimpleName());
@@ -152,7 +152,7 @@ public class GuestAdditionsInstallerLiveTest extends BaseVirtualBoxClientLiveTes
    private IMachine getVmWithGuestAdditionsInstalled() {
       MasterSpec masterSpecForTest = super.getMasterSpecForTest();
       try {
-         Injector injector = context.utils().injector();
+         Injector injector = view.utils().injector();
          return injector.getInstance(CreateAndInstallVm.class).apply(masterSpecForTest);
       } catch (IllegalStateException e) {
          // already created
diff --git a/labs/virtualbox/src/test/java/org/jclouds/virtualbox/predicates/IMachinePredicatesLiveTest.java b/labs/virtualbox/src/test/java/org/jclouds/virtualbox/predicates/IMachinePredicatesLiveTest.java
index a1e2815b9d..1b2295a124 100644
--- a/labs/virtualbox/src/test/java/org/jclouds/virtualbox/predicates/IMachinePredicatesLiveTest.java
+++ b/labs/virtualbox/src/test/java/org/jclouds/virtualbox/predicates/IMachinePredicatesLiveTest.java
@@ -79,7 +79,7 @@ public class IMachinePredicatesLiveTest extends BaseVirtualBoxClientLiveTest {
       VmSpec instanceVmSpec = VmSpec.builder().id(instanceName).name(instanceName).osTypeId("").memoryMB(512)
                .cleanUpMode(CleanupMode.Full).controller(ideController).forceOverwrite(true).build();
 
-      Injector injector = context.utils().injector();
+      Injector injector = view.utils().injector();
       Function configProperties = injector.getInstance(ValueOfConfigurationKeyOrNull.class);
       IsoSpec isoSpec = IsoSpec
                .builder()
@@ -111,7 +111,7 @@ public class IMachinePredicatesLiveTest extends BaseVirtualBoxClientLiveTest {
    private IMachine getVmWithGuestAdditionsInstalled() {
       MasterSpec masterSpecForTest = super.getMasterSpecForTest();
       try {
-         Injector injector = context.utils().injector();
+         Injector injector = view.utils().injector();
          return injector.getInstance(CreateAndInstallVm.class).apply(masterSpecForTest);
       } catch (IllegalStateException e) {
          // already created
diff --git a/labs/virtualbox/src/test/java/org/jclouds/virtualbox/util/MachineControllerLiveTest.java b/labs/virtualbox/src/test/java/org/jclouds/virtualbox/util/MachineControllerLiveTest.java
index 8d90ea2028..2291d625c7 100644
--- a/labs/virtualbox/src/test/java/org/jclouds/virtualbox/util/MachineControllerLiveTest.java
+++ b/labs/virtualbox/src/test/java/org/jclouds/virtualbox/util/MachineControllerLiveTest.java
@@ -76,7 +76,7 @@ public class MachineControllerLiveTest extends BaseVirtualBoxClientLiveTest {
       VmSpec instanceVmSpec = VmSpec.builder().id(instanceName).name(instanceName).osTypeId("").memoryMB(512)
                .cleanUpMode(CleanupMode.Full).controller(ideController).forceOverwrite(true).build();
 
-      Injector injector = context.utils().injector();
+      Injector injector = view.utils().injector();
       Function configProperties = injector.getInstance(ValueOfConfigurationKeyOrNull.class);
       IsoSpec isoSpec = IsoSpec
                .builder()
@@ -121,7 +121,7 @@ public class MachineControllerLiveTest extends BaseVirtualBoxClientLiveTest {
    private IMachine getVmWithGuestAdditionsInstalled() {
       MasterSpec masterSpecForTest = super.getMasterSpecForTest();
       try {
-         Injector injector = context.utils().injector();
+         Injector injector = view.utils().injector();
          return injector.getInstance(CreateAndInstallVm.class).apply(masterSpecForTest);
       } catch (IllegalStateException e) {
          // already created
diff --git a/labs/virtualbox/src/test/java/org/jclouds/virtualbox/util/MachineUtilsLiveTest.java b/labs/virtualbox/src/test/java/org/jclouds/virtualbox/util/MachineUtilsLiveTest.java
index d5c9725f51..39bac6d52f 100644
--- a/labs/virtualbox/src/test/java/org/jclouds/virtualbox/util/MachineUtilsLiveTest.java
+++ b/labs/virtualbox/src/test/java/org/jclouds/virtualbox/util/MachineUtilsLiveTest.java
@@ -76,7 +76,7 @@ public class MachineUtilsLiveTest extends BaseVirtualBoxClientLiveTest {
       VmSpec instanceVmSpec = VmSpec.builder().id(instanceName).name(instanceName).osTypeId("").memoryMB(512)
                .cleanUpMode(CleanupMode.Full).controller(ideController).forceOverwrite(true).build();
 
-      Injector injector = context.utils().injector();
+      Injector injector = view.utils().injector();
       Function configProperties = injector.getInstance(ValueOfConfigurationKeyOrNull.class);
       IsoSpec isoSpec = IsoSpec
                .builder()
@@ -123,7 +123,7 @@ public class MachineUtilsLiveTest extends BaseVirtualBoxClientLiveTest {
    private IMachine getVmWithGuestAdditionsInstalled() {
       MasterSpec masterSpecForTest = super.getMasterSpecForTest();
       try {
-         Injector injector = context.utils().injector();
+         Injector injector = view.utils().injector();
          return injector.getInstance(CreateAndInstallVm.class).apply(masterSpecForTest);
       } catch (IllegalStateException e) {
          // already created
diff --git a/labs/virtualbox/src/test/resources/test_guest_additions_installer_init.sh b/labs/virtualbox/src/test/resources/test_guest_additions_installer_init.sh
index cccddd00ef..53bae7b1cd 100644
--- a/labs/virtualbox/src/test/resources/test_guest_additions_installer_init.sh
+++ b/labs/virtualbox/src/test/resources/test_guest_additions_installer_init.sh
@@ -90,7 +90,7 @@ function ensure_cmd_or_install_package_apt(){
   local cmd=$1
   local pkg=$2
   
-  hash $cmd 2>/dev/null || apt-get-install $pkg || ( apt-get-update && apt-get-install $pkg )
+  hash $cmd 2>/dev/null || ( apt-get-update && apt-get-install $pkg )
 }
 
 function ensure_cmd_or_install_package_yum(){
diff --git a/loadbalancer/src/main/java/org/jclouds/loadbalancer/LoadBalancerServiceContext.java b/loadbalancer/src/main/java/org/jclouds/loadbalancer/LoadBalancerServiceContext.java
index 4940137d9f..395ff30658 100644
--- a/loadbalancer/src/main/java/org/jclouds/loadbalancer/LoadBalancerServiceContext.java
+++ b/loadbalancer/src/main/java/org/jclouds/loadbalancer/LoadBalancerServiceContext.java
@@ -20,7 +20,7 @@ package org.jclouds.loadbalancer;
 
 import java.io.Closeable;
 
-import org.jclouds.Wrapper;
+import org.jclouds.View;
 import org.jclouds.loadbalancer.internal.LoadBalancerServiceContextImpl;
 import org.jclouds.rest.RestContext;
 import org.jclouds.rest.Utils;
@@ -35,7 +35,7 @@ import com.google.inject.ImplementedBy;
  * 
  */
 @ImplementedBy(LoadBalancerServiceContextImpl.class)
-public interface LoadBalancerServiceContext extends Closeable, Wrapper {
+public interface LoadBalancerServiceContext extends Closeable, View {
 
    LoadBalancerService getLoadBalancerService();
 
@@ -50,8 +50,8 @@ public interface LoadBalancerServiceContext extends Closeable, Wrapper {
    /**
     * will be removed in jclouds 1.6
     * 
-    * @see Wrapper#getInputType
-    * @see Wrapper#unwrap
+    * @see View#getInputType
+    * @see View#unwrap
     */
    @Deprecated
     RestContext getProviderSpecificContext();
diff --git a/loadbalancer/src/main/java/org/jclouds/loadbalancer/internal/LoadBalancerServiceContextImpl.java b/loadbalancer/src/main/java/org/jclouds/loadbalancer/internal/LoadBalancerServiceContextImpl.java
index 022a7b116d..47b295cddf 100644
--- a/loadbalancer/src/main/java/org/jclouds/loadbalancer/internal/LoadBalancerServiceContextImpl.java
+++ b/loadbalancer/src/main/java/org/jclouds/loadbalancer/internal/LoadBalancerServiceContextImpl.java
@@ -20,12 +20,11 @@ package org.jclouds.loadbalancer.internal;
 
 import static com.google.common.base.Preconditions.checkNotNull;
 
-import java.io.Closeable;
-
 import javax.inject.Inject;
 import javax.inject.Singleton;
 
-import org.jclouds.internal.BaseWrapper;
+import org.jclouds.Context;
+import org.jclouds.internal.BaseView;
 import org.jclouds.loadbalancer.LoadBalancerService;
 import org.jclouds.loadbalancer.LoadBalancerServiceContext;
 import org.jclouds.location.Provider;
@@ -39,14 +38,14 @@ import com.google.common.reflect.TypeToken;
  * @author Adrian Cole
  */
 @Singleton
-public class LoadBalancerServiceContextImpl extends BaseWrapper implements LoadBalancerServiceContext {
+public class LoadBalancerServiceContextImpl extends BaseView implements LoadBalancerServiceContext {
    private final LoadBalancerService loadBalancerService;
    private final Utils utils;
 
    @Inject
-   public LoadBalancerServiceContextImpl(@Provider Closeable wrapped,
-            @Provider TypeToken wrappedType, LoadBalancerService loadBalancerService, Utils utils) {
-      super(wrapped, wrappedType);
+   public LoadBalancerServiceContextImpl(@Provider Context backend,
+            @Provider TypeToken backendType, LoadBalancerService loadBalancerService, Utils utils) {
+      super(backend, backendType);
       this.utils = utils;
       this.loadBalancerService = checkNotNull(loadBalancerService, "loadBalancerService");
    }
@@ -69,26 +68,26 @@ public class LoadBalancerServiceContextImpl extends BaseWrapper implements LoadB
    @SuppressWarnings("unchecked")
    @Override
    public  RestContext getProviderSpecificContext() {
-      return (RestContext) getWrapped();
+      return (RestContext) delegate();
    }
 
    @Override
    public void close() {
-      Closeables.closeQuietly(getWrapped());
+      Closeables.closeQuietly(delegate());
    }
 
    public int hashCode() {
-      return getWrapped().hashCode();
+      return delegate().hashCode();
    }
 
    @Override
    public String toString() {
-      return getWrapped().toString();
+      return delegate().toString();
    }
 
    @Override
    public boolean equals(Object obj) {
-      return getWrapped().equals(obj);
+      return delegate().equals(obj);
    }
 
 }
diff --git a/loadbalancer/src/test/java/org/jclouds/loadbalancer/BaseLoadBalancerServiceLiveTest.java b/loadbalancer/src/test/java/org/jclouds/loadbalancer/BaseLoadBalancerServiceLiveTest.java
index f814e722e8..9ae48242e5 100644
--- a/loadbalancer/src/test/java/org/jclouds/loadbalancer/BaseLoadBalancerServiceLiveTest.java
+++ b/loadbalancer/src/test/java/org/jclouds/loadbalancer/BaseLoadBalancerServiceLiveTest.java
@@ -30,7 +30,7 @@ import java.util.concurrent.TimeoutException;
 
 import org.jclouds.Constants;
 import org.jclouds.ContextBuilder;
-import org.jclouds.apis.BaseContextLiveTest;
+import org.jclouds.apis.BaseViewLiveTest;
 import org.jclouds.compute.ComputeServiceContext;
 import org.jclouds.compute.RunNodesException;
 import org.jclouds.compute.domain.NodeMetadata;
@@ -58,7 +58,7 @@ import com.google.inject.Module;
  * @author Adrian Cole
  */
 @Test(groups = "live", singleThreaded = true)
-public abstract class BaseLoadBalancerServiceLiveTest extends BaseContextLiveTest {
+public abstract class BaseLoadBalancerServiceLiveTest extends BaseViewLiveTest {
 
    protected String imageId;
    protected String loginUser;
@@ -185,7 +185,7 @@ public abstract class BaseLoadBalancerServiceLiveTest extends BaseContextLiveTes
    }
    
    @Override
-   protected TypeToken contextType() {
+   protected TypeToken viewType() {
       return TypeToken.of(LoadBalancerServiceContext.class);
    }
 }
diff --git a/loadbalancer/src/test/java/org/jclouds/loadbalancer/internal/BaseLoadBalancerServiceApiMetadataTest.java b/loadbalancer/src/test/java/org/jclouds/loadbalancer/internal/BaseLoadBalancerServiceApiMetadataTest.java
index 4f054772ea..4745c311ae 100644
--- a/loadbalancer/src/test/java/org/jclouds/loadbalancer/internal/BaseLoadBalancerServiceApiMetadataTest.java
+++ b/loadbalancer/src/test/java/org/jclouds/loadbalancer/internal/BaseLoadBalancerServiceApiMetadataTest.java
@@ -18,7 +18,7 @@
  */
 package org.jclouds.loadbalancer.internal;
 
-import org.jclouds.Wrapper;
+import org.jclouds.View;
 import org.jclouds.apis.ApiMetadata;
 import org.jclouds.apis.internal.BaseApiMetadataTest;
 import org.jclouds.loadbalancer.LoadBalancerServiceContext;
@@ -35,7 +35,7 @@ import com.google.common.reflect.TypeToken;
 public abstract class BaseLoadBalancerServiceApiMetadataTest extends BaseApiMetadataTest {
 
    public BaseLoadBalancerServiceApiMetadataTest(ApiMetadata toTest) {
-     super(toTest, ImmutableSet.>of(TypeToken.of(LoadBalancerServiceContext.class)));
+     super(toTest, ImmutableSet.>of(TypeToken.of(LoadBalancerServiceContext.class)));
    }
 
 }
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 8bee94934b..2092ec5300 100644
--- a/pom.xml
+++ b/pom.xml
@@ -61,16 +61,16 @@
                         javadoc
                         package
                         
-                            aggregate
+                            aggregate-jar
                         
                     
                                 
                 
-                    ${sourceEncoding}                        
+                    -J-Xmx512m
+                    ${project.build.sourceEncoding}
                     true
                     
-                        http://java.sun.com/javase/6/docs/api/
-                        http://java.sun.com/javaee/6/docs/api/
+                        http://download.oracle.com/javase/6/docs/api/