merged conflicts

This commit is contained in:
Rainbowbreeze 2010-09-17 10:33:28 +02:00
commit 1c4e706aed
593 changed files with 12185 additions and 5881 deletions

View File

@ -28,18 +28,19 @@ our dev version is 1.0-SNAPSHOT
our compute api supports: ec2, gogrid, rackspace, rimuhosting, vcloud, trmk-ecloud, our compute api supports: ec2, gogrid, rackspace, rimuhosting, vcloud, trmk-ecloud,
trmk-vcloudexpress, eucalyptus, bluelock-vclouddirector, trmk-vcloudexpress, eucalyptus, bluelock-vclouddirector,
bluelock-vcloudexpress, ibmdev, slicehost bluelock-vcloudexpress, slicehost, stub (in-memory)
* note * the pom dependency org.jclouds/jclouds-allcompute gives you access to * note * the pom dependency org.jclouds/jclouds-allcompute gives you access to
to all of these providers to all of these providers
our blobstore api supports: s3, rackspace, azure, atmos online, att synaptic, our blobstore api supports: s3, rackspace, azure, atmos online, att synaptic,
walrus, googlestorage, transient (in-memory) walrus, googlestorage, transient (in-memory), filesystem (on-disk)
* note * the pom dependency org.jclouds/jclouds-allblobstore gives you access to * note * the pom dependency org.jclouds/jclouds-allblobstore gives you access to
to all of these providers to all of these providers
we also have rest clients for: chef, opscodeplatform, pcs2 (mezeo), sdn (nirvanix), twitter we also have rest clients for: chef, opscodeplatform, twitter, as well a number of features
in the sandbox
If you want access to all jclouds components, include the maven dependency org.jclouds/jclouds-all If you want access to all jclouds components, include the maven dependency org.jclouds/jclouds-all

View File

@ -39,16 +39,6 @@
<artifactId>jclouds-allblobstore</artifactId> <artifactId>jclouds-allblobstore</artifactId>
<version>${project.version}</version> <version>${project.version}</version>
</dependency> </dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>jclouds-pcs2</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>jclouds-sdn</artifactId>
<version>${project.version}</version>
</dependency>
<dependency> <dependency>
<groupId>${project.groupId}</groupId> <groupId>${project.groupId}</groupId>
<artifactId>jclouds-twitter</artifactId> <artifactId>jclouds-twitter</artifactId>
@ -64,10 +54,5 @@
<artifactId>jclouds-opscodeplatform</artifactId> <artifactId>jclouds-opscodeplatform</artifactId>
<version>${project.version}</version> <version>${project.version}</version>
</dependency> </dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>jclouds-boxdotnet</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies> </dependencies>
</project> </project>

View File

@ -64,11 +64,6 @@
<artifactId>jclouds-gogrid</artifactId> <artifactId>jclouds-gogrid</artifactId>
<version>${project.version}</version> <version>${project.version}</version>
</dependency> </dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>jclouds-ibmdev</artifactId>
<version>${project.version}</version>
</dependency>
<dependency> <dependency>
<groupId>${project.groupId}</groupId> <groupId>${project.groupId}</groupId>
<artifactId>jclouds-slicehost</artifactId> <artifactId>jclouds-slicehost</artifactId>

View File

@ -54,7 +54,7 @@
</repository> </repository>
<repository> <repository>
<id>jclouds-rimu-snapshots-nexus</id> <id>jclouds-rimu-snapshots-nexus</id>
<url>http://jclouds.rimuhosting.com:8081/nexus/content/repositories/snapshots</url> <url>https://oss.sonatype.org/content/repositories/snapshots</url>
<snapshots> <snapshots>
<enabled>true</enabled> <enabled>true</enabled>
</snapshots> </snapshots>

View File

@ -54,7 +54,7 @@
</repository> </repository>
<repository> <repository>
<id>jclouds-rimu-snapshots-nexus</id> <id>jclouds-rimu-snapshots-nexus</id>
<url>http://jclouds.rimuhosting.com:8081/nexus/content/repositories/snapshots</url> <url>https://oss.sonatype.org/content/repositories/snapshots</url>
<snapshots> <snapshots>
<enabled>true</enabled> <enabled>true</enabled>
</snapshots> </snapshots>

View File

@ -243,58 +243,31 @@
<outputDirectory>providers/azure</outputDirectory> <outputDirectory>providers/azure</outputDirectory>
</fileSet> </fileSet>
<!-- providers: mezeo --> <!-- providers: slicehost -->
<fileSet> <fileSet>
<directory>mezeo/pcs2/target</directory> <directory>slicehost/target</directory>
<includes> <includes>
<include>jclouds-pcs2-${project.version}.jar</include> <include>jclouds-slicehost-${project.version}.jar</include>
</includes> </includes>
<outputDirectory>providers/mezeo/lib</outputDirectory> <outputDirectory>providers/slicehost/lib</outputDirectory>
</fileSet> </fileSet>
<fileSet> <fileSet>
<directory>mezeo/pcs2/target</directory> <directory>slicehost/target</directory>
<includes> <includes>
<include>jclouds-pcs2-${project.version}-sources.jar</include> <include>jclouds-slicehost-${project.version}-sources.jar</include>
</includes> </includes>
<outputDirectory>providers/mezeo/src</outputDirectory> <outputDirectory>providers/slicehost/src</outputDirectory>
</fileSet> </fileSet>
<fileSet> <fileSet>
<directory>mezeo/pcs2/target/apidocs</directory> <directory>slicehost/target/apidocs</directory>
<outputDirectory>providers/mezeo/docs</outputDirectory> <outputDirectory>providers/slicehost/docs</outputDirectory>
</fileSet> </fileSet>
<fileSet> <fileSet>
<directory>mezeo/pcs2</directory> <directory>slicehost</directory>
<includes> <includes>
<include>README.txt</include> <include>README.txt</include>
</includes> </includes>
<outputDirectory>providers/mezeo</outputDirectory> <outputDirectory>providers/slicehost</outputDirectory>
</fileSet>
<!-- providers: nirvanix-->
<fileSet>
<directory>nirvanix/sdn/target</directory>
<includes>
<include>jclouds-sdn-${project.version}.jar</include>
</includes>
<outputDirectory>providers/nirvanix/lib</outputDirectory>
</fileSet>
<fileSet>
<directory>nirvanix/sdn/target</directory>
<includes>
<include>jclouds-sdn-${project.version}-sources.jar</include>
</includes>
<outputDirectory>providers/nirvanix/src</outputDirectory>
</fileSet>
<fileSet>
<directory>nirvanix/sdn/target/apidocs</directory>
<outputDirectory>providers/nirvanix/docs</outputDirectory>
</fileSet>
<fileSet>
<directory>nirvanix/sdn</directory>
<includes>
<include>README.txt</include>
</includes>
<outputDirectory>providers/nirvanix</outputDirectory>
</fileSet> </fileSet>
<!-- providers: rackspace --> <!-- providers: rackspace -->
@ -324,6 +297,33 @@
<outputDirectory>providers/rackspace</outputDirectory> <outputDirectory>providers/rackspace</outputDirectory>
</fileSet> </fileSet>
<!-- providers: gogrid -->
<fileSet>
<directory>gogrid/target</directory>
<includes>
<include>jclouds-gogrid-${project.version}.jar</include>
</includes>
<outputDirectory>providers/gogrid/lib</outputDirectory>
</fileSet>
<fileSet>
<directory>gogrid/target</directory>
<includes>
<include>jclouds-gogrid-${project.version}-sources.jar</include>
</includes>
<outputDirectory>providers/gogrid/src</outputDirectory>
</fileSet>
<fileSet>
<directory>gogrid/target/apidocs</directory>
<outputDirectory>providers/gogrid/docs</outputDirectory>
</fileSet>
<fileSet>
<directory>gogrid</directory>
<includes>
<include>README.txt</include>
</includes>
<outputDirectory>providers/gogrid</outputDirectory>
</fileSet>
<!-- providers: rimuhosting --> <!-- providers: rimuhosting -->
<fileSet> <fileSet>
<directory>rimuhosting/target</directory> <directory>rimuhosting/target</directory>
@ -351,7 +351,62 @@
<outputDirectory>providers/rimuhosting</outputDirectory> <outputDirectory>providers/rimuhosting</outputDirectory>
</fileSet> </fileSet>
<!-- providers: bluelock -->
<fileSet>
<directory>vcloud/core/target</directory>
<includes>
<include>jclouds-vcloud-${project.version}.jar</include>
</includes>
<outputDirectory>providers/bluelock/lib</outputDirectory>
</fileSet>
<fileSet>
<directory>vcloud/core/target</directory>
<includes>
<include>jclouds-vcloud-${project.version}-sources.jar</include>
</includes>
<outputDirectory>providers/bluelock/src</outputDirectory>
</fileSet>
<fileSet>
<directory>vcloud/bluelock/target</directory>
<includes>
<include>jclouds-bluelock-${project.version}.jar</include>
</includes>
<outputDirectory>providers/bluelock/lib</outputDirectory>
</fileSet>
<fileSet>
<directory>vcloud/bluelock/target</directory>
<includes>
<include>jclouds-bluelock-${project.version}-sources.jar</include>
</includes>
<outputDirectory>providers/bluelock/src</outputDirectory>
</fileSet>
<fileSet>
<directory>vcloud/bluelock/target/apidocs</directory>
<outputDirectory>providers/bluelock/docs</outputDirectory>
</fileSet>
<fileSet>
<directory>vcloud/bluelock</directory>
<includes>
<include>README.txt</include>
</includes>
<outputDirectory>providers/bluelock</outputDirectory>
</fileSet>
<!-- providers: terremark --> <!-- providers: terremark -->
<fileSet>
<directory>vcloud/core/target</directory>
<includes>
<include>jclouds-vcloud-${project.version}.jar</include>
</includes>
<outputDirectory>providers/terremark/lib</outputDirectory>
</fileSet>
<fileSet>
<directory>vcloud/core/target</directory>
<includes>
<include>jclouds-vcloud-${project.version}-sources.jar</include>
</includes>
<outputDirectory>providers/terremark/src</outputDirectory>
</fileSet>
<fileSet> <fileSet>
<directory>vcloud/terremark/target</directory> <directory>vcloud/terremark/target</directory>
<includes> <includes>
@ -378,6 +433,74 @@
<outputDirectory>providers/terremark</outputDirectory> <outputDirectory>providers/terremark</outputDirectory>
</fileSet> </fileSet>
<!-- providers: chef -->
<fileSet>
<directory>chef/target</directory>
<includes>
<include>jclouds-chef-${project.version}.jar</include>
</includes>
<outputDirectory>providers/chef/lib</outputDirectory>
</fileSet>
<fileSet>
<directory>chef/target</directory>
<includes>
<include>jclouds-chef-${project.version}-sources.jar</include>
</includes>
<outputDirectory>providers/chef/src</outputDirectory>
</fileSet>
<fileSet>
<directory>chef/target/apidocs</directory>
<outputDirectory>providers/chef/docs</outputDirectory>
</fileSet>
<fileSet>
<directory>chef</directory>
<includes>
<include>README.txt</include>
</includes>
<outputDirectory>providers/chef</outputDirectory>
</fileSet>
<!-- providers: opscodeplatform -->
<fileSet>
<directory>chef/target</directory>
<includes>
<include>jclouds-chef-${project.version}.jar</include>
</includes>
<outputDirectory>providers/opscodeplatform/lib</outputDirectory>
</fileSet>
<fileSet>
<directory>chef/target</directory>
<includes>
<include>jclouds-chef-${project.version}-sources.jar</include>
</includes>
<outputDirectory>providers/opscodeplatform/src</outputDirectory>
</fileSet>
<fileSet>
<directory>opscodeplatform/target</directory>
<includes>
<include>jclouds-opscodeplatform-${project.version}.jar</include>
</includes>
<outputDirectory>providers/opscodeplatform/lib</outputDirectory>
</fileSet>
<fileSet>
<directory>opscodeplatform/target</directory>
<includes>
<include>jclouds-opscodeplatform-${project.version}-sources.jar</include>
</includes>
<outputDirectory>providers/opscodeplatform/src</outputDirectory>
</fileSet>
<fileSet>
<directory>opscodeplatform/target/apidocs</directory>
<outputDirectory>providers/opscodeplatform/docs</outputDirectory>
</fileSet>
<fileSet>
<directory>opscodeplatform</directory>
<includes>
<include>README.txt</include>
</includes>
<outputDirectory>providers/opscodeplatform</outputDirectory>
</fileSet>
<!-- providers: twitter --> <!-- providers: twitter -->
<fileSet> <fileSet>
<directory>twitter/target</directory> <directory>twitter/target</directory>

View File

@ -70,6 +70,7 @@ import com.google.common.util.concurrent.ListenableFuture;
*/ */
@RequestFilters(SignRequest.class) @RequestFilters(SignRequest.class)
@SkipEncoding('/') @SkipEncoding('/')
@Path("/rest/namespace")
public interface AtmosStorageAsyncClient { public interface AtmosStorageAsyncClient {
/** /**
* Creates a default implementation of AtmosObject * Creates a default implementation of AtmosObject
@ -80,17 +81,16 @@ public interface AtmosStorageAsyncClient {
* @see AtmosStorageClient#listDirectories * @see AtmosStorageClient#listDirectories
*/ */
@GET @GET
@Path("/rest/namespace") @Path("")
@ResponseParser(ParseDirectoryListFromContentAndHeaders.class) @ResponseParser(ParseDirectoryListFromContentAndHeaders.class)
@Consumes(MediaType.TEXT_XML) @Consumes(MediaType.TEXT_XML)
ListenableFuture<BoundedSet<? extends DirectoryEntry>> listDirectories( ListenableFuture<BoundedSet<? extends DirectoryEntry>> listDirectories(ListOptions... options);
ListOptions... options);
/** /**
* @see AtmosStorageClient#listDirectory * @see AtmosStorageClient#listDirectory
*/ */
@GET @GET
@Path("/rest/namespace/{directoryName}/") @Path("/{directoryName}/")
@ResponseParser(ParseDirectoryListFromContentAndHeaders.class) @ResponseParser(ParseDirectoryListFromContentAndHeaders.class)
@ExceptionParser(ThrowContainerNotFoundOn404.class) @ExceptionParser(ThrowContainerNotFoundOn404.class)
@Consumes(MediaType.TEXT_XML) @Consumes(MediaType.TEXT_XML)
@ -101,7 +101,7 @@ public interface AtmosStorageAsyncClient {
* @see AtmosStorageClient#createDirectory * @see AtmosStorageClient#createDirectory
*/ */
@POST @POST
@Path("/rest/namespace/{directoryName}/") @Path("/{directoryName}/")
@ExceptionParser(ReturnEndpointIfAlreadyExists.class) @ExceptionParser(ReturnEndpointIfAlreadyExists.class)
@Consumes(MediaType.WILDCARD) @Consumes(MediaType.WILDCARD)
ListenableFuture<URI> createDirectory(@PathParam("directoryName") String directoryName); ListenableFuture<URI> createDirectory(@PathParam("directoryName") String directoryName);
@ -110,7 +110,7 @@ public interface AtmosStorageAsyncClient {
* @see AtmosStorageClient#createFile * @see AtmosStorageClient#createFile
*/ */
@POST @POST
@Path("/rest/namespace/{parent}/{name}") @Path("/{parent}/{name}")
@Consumes(MediaType.WILDCARD) @Consumes(MediaType.WILDCARD)
ListenableFuture<URI> createFile( ListenableFuture<URI> createFile(
@PathParam("parent") String parent, @PathParam("parent") String parent,
@ -120,7 +120,7 @@ public interface AtmosStorageAsyncClient {
* @see AtmosStorageClient#updateFile * @see AtmosStorageClient#updateFile
*/ */
@PUT @PUT
@Path("/rest/namespace/{parent}/{name}") @Path("/{parent}/{name}")
@ExceptionParser(ThrowKeyNotFoundOn404.class) @ExceptionParser(ThrowKeyNotFoundOn404.class)
@Consumes(MediaType.WILDCARD) @Consumes(MediaType.WILDCARD)
ListenableFuture<Void> updateFile( ListenableFuture<Void> updateFile(
@ -133,7 +133,7 @@ public interface AtmosStorageAsyncClient {
@GET @GET
@ResponseParser(ParseObjectFromHeadersAndHttpContent.class) @ResponseParser(ParseObjectFromHeadersAndHttpContent.class)
@ExceptionParser(ReturnNullOnNotFoundOr404.class) @ExceptionParser(ReturnNullOnNotFoundOr404.class)
@Path("/rest/namespace/{path}") @Path("/{path}")
@Consumes(MediaType.WILDCARD) @Consumes(MediaType.WILDCARD)
ListenableFuture<AtmosObject> readFile(@PathParam("path") String path, GetOptions... options); ListenableFuture<AtmosObject> readFile(@PathParam("path") String path, GetOptions... options);
@ -143,7 +143,7 @@ public interface AtmosStorageAsyncClient {
@HEAD @HEAD
@ResponseParser(ParseObjectFromHeadersAndHttpContent.class) @ResponseParser(ParseObjectFromHeadersAndHttpContent.class)
@ExceptionParser(ReturnNullOnNotFoundOr404.class) @ExceptionParser(ReturnNullOnNotFoundOr404.class)
@Path("/rest/namespace/{path}") @Path("/{path}")
@Consumes(MediaType.WILDCARD) @Consumes(MediaType.WILDCARD)
ListenableFuture<AtmosObject> headFile(@PathParam("path") String path); ListenableFuture<AtmosObject> headFile(@PathParam("path") String path);
@ -154,7 +154,7 @@ public interface AtmosStorageAsyncClient {
@ResponseParser(ParseSystemMetadataFromHeaders.class) @ResponseParser(ParseSystemMetadataFromHeaders.class)
@ExceptionParser(ReturnNullOnNotFoundOr404.class) @ExceptionParser(ReturnNullOnNotFoundOr404.class)
// currently throws 403 errors @QueryParams(keys = "metadata/system") // currently throws 403 errors @QueryParams(keys = "metadata/system")
@Path("/rest/namespace/{path}") @Path("/{path}")
@Consumes(MediaType.WILDCARD) @Consumes(MediaType.WILDCARD)
ListenableFuture<SystemMetadata> getSystemMetadata(@PathParam("path") String path); ListenableFuture<SystemMetadata> getSystemMetadata(@PathParam("path") String path);
@ -164,7 +164,7 @@ public interface AtmosStorageAsyncClient {
@HEAD @HEAD
@ResponseParser(ParseSystemMetadataFromHeaders.class) @ResponseParser(ParseSystemMetadataFromHeaders.class)
@ExceptionParser(ReturnNullOnNotFoundOr404.class) @ExceptionParser(ReturnNullOnNotFoundOr404.class)
@Path("/rest/namespace/{path}") @Path("/{path}")
@QueryParams(keys = "metadata/user") @QueryParams(keys = "metadata/user")
@Consumes(MediaType.WILDCARD) @Consumes(MediaType.WILDCARD)
ListenableFuture<UserMetadata> getUserMetadata(@PathParam("path") String path); ListenableFuture<UserMetadata> getUserMetadata(@PathParam("path") String path);
@ -174,7 +174,7 @@ public interface AtmosStorageAsyncClient {
*/ */
@DELETE @DELETE
@ExceptionParser(ReturnVoidOnNotFoundOr404.class) @ExceptionParser(ReturnVoidOnNotFoundOr404.class)
@Path("/rest/namespace/{path}") @Path("/{path}")
@Consumes(MediaType.WILDCARD) @Consumes(MediaType.WILDCARD)
ListenableFuture<Void> deletePath(@PathParam("path") String path); ListenableFuture<Void> deletePath(@PathParam("path") String path);
@ -183,7 +183,7 @@ public interface AtmosStorageAsyncClient {
*/ */
@HEAD @HEAD
@ExceptionParser(ReturnFalseOnNotFoundOr404.class) @ExceptionParser(ReturnFalseOnNotFoundOr404.class)
@Path("/rest/namespace/{path}") @Path("/{path}")
@Consumes(MediaType.WILDCARD) @Consumes(MediaType.WILDCARD)
ListenableFuture<Boolean> pathExists(@PathParam("path") String path); ListenableFuture<Boolean> pathExists(@PathParam("path") String path);

View File

@ -0,0 +1,81 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.atmosonline.saas.blobstore;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.jclouds.blobstore.util.BlobStoreUtils.cleanRequest;
import java.lang.reflect.Method;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.jclouds.atmosonline.saas.AtmosStorageAsyncClient;
import org.jclouds.atmosonline.saas.blobstore.functions.BlobToObject;
import org.jclouds.atmosonline.saas.domain.AtmosObject;
import org.jclouds.blobstore.BlobRequestSigner;
import org.jclouds.blobstore.domain.Blob;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.options.GetOptions;
import org.jclouds.rest.internal.RestAnnotationProcessor;
/**
*
* @author Adrian Cole
*/
@Singleton
public class AtmosBlobRequestSigner implements BlobRequestSigner {
private final RestAnnotationProcessor<AtmosStorageAsyncClient> processor;
private final BlobToObject blobToObject;
private final Method getMethod;
private final Method deleteMethod;
private final Method createMethod;
@Inject
public AtmosBlobRequestSigner(RestAnnotationProcessor<AtmosStorageAsyncClient> processor, BlobToObject blobToObject)
throws SecurityException, NoSuchMethodException {
this.processor = checkNotNull(processor, "processor");
this.blobToObject = checkNotNull(blobToObject, "blobToObject");
this.getMethod = AtmosStorageAsyncClient.class.getMethod("readFile", String.class, GetOptions[].class);
this.deleteMethod = AtmosStorageAsyncClient.class.getMethod("deletePath", String.class);
this.createMethod = AtmosStorageAsyncClient.class.getMethod("createFile", String.class, AtmosObject.class);
}
@Override
public HttpRequest signGetBlob(String container, String name) {
return cleanRequest(processor.createRequest(getMethod, getPath(container, name)));
}
@Override
public HttpRequest signPutBlob(String container, Blob blob) {
return cleanRequest(processor.createRequest(createMethod, container, blobToObject.apply(blob)));
}
@Override
public HttpRequest signRemoveBlob(String container, String name) {
return cleanRequest(processor.createRequest(deleteMethod, getPath(container, name)));
}
private String getPath(String container, String name) {
return checkNotNull(container, "container") + "/" + checkNotNull(name, "name");
}
}

View File

@ -26,9 +26,11 @@ import javax.inject.Singleton;
import org.jclouds.atmosonline.saas.AtmosStorageAsyncClient; import org.jclouds.atmosonline.saas.AtmosStorageAsyncClient;
import org.jclouds.atmosonline.saas.AtmosStorageClient; import org.jclouds.atmosonline.saas.AtmosStorageClient;
import org.jclouds.atmosonline.saas.blobstore.AtmosAsyncBlobStore; import org.jclouds.atmosonline.saas.blobstore.AtmosAsyncBlobStore;
import org.jclouds.atmosonline.saas.blobstore.AtmosBlobRequestSigner;
import org.jclouds.atmosonline.saas.blobstore.AtmosBlobStore; import org.jclouds.atmosonline.saas.blobstore.AtmosBlobStore;
import org.jclouds.atmosonline.saas.blobstore.strategy.FindMD5InUserMetadata; import org.jclouds.atmosonline.saas.blobstore.strategy.FindMD5InUserMetadata;
import org.jclouds.blobstore.AsyncBlobStore; import org.jclouds.blobstore.AsyncBlobStore;
import org.jclouds.blobstore.BlobRequestSigner;
import org.jclouds.blobstore.BlobStore; import org.jclouds.blobstore.BlobStore;
import org.jclouds.blobstore.BlobStoreContext; import org.jclouds.blobstore.BlobStoreContext;
import org.jclouds.blobstore.attr.ConsistencyModel; import org.jclouds.blobstore.attr.ConsistencyModel;
@ -65,6 +67,7 @@ public class AtmosBlobStoreContextModule extends AbstractModule {
new TypeLiteral<BlobStoreContextImpl<AtmosStorageClient, AtmosStorageAsyncClient>>() { new TypeLiteral<BlobStoreContextImpl<AtmosStorageClient, AtmosStorageAsyncClient>>() {
}).in(Scopes.SINGLETON); }).in(Scopes.SINGLETON);
bind(ContainsValueInListStrategy.class).to(FindMD5InUserMetadata.class); bind(ContainsValueInListStrategy.class).to(FindMD5InUserMetadata.class);
bind(BlobRequestSigner.class).to(AtmosBlobRequestSigner.class);
} }
@Provides @Provides

View File

@ -182,8 +182,7 @@ public class AtmosStorageAsyncClientTest extends RestClientTest<AtmosStorageAsyn
} }
public void testReadFile() throws SecurityException, NoSuchMethodException, IOException { public void testReadFile() throws SecurityException, NoSuchMethodException, IOException {
Method method = AtmosStorageAsyncClient.class.getMethod("readFile", String.class, Array.newInstance( Method method = AtmosStorageAsyncClient.class.getMethod("readFile", String.class, GetOptions[].class);
GetOptions.class, 0).getClass());
HttpRequest request = processor.createRequest(method, "dir/file"); HttpRequest request = processor.createRequest(method, "dir/file");
assertRequestLineEquals(request, "GET https://accesspoint.atmosonline.com/rest/namespace/dir/file HTTP/1.1"); assertRequestLineEquals(request, "GET https://accesspoint.atmosonline.com/rest/namespace/dir/file HTTP/1.1");

View File

@ -0,0 +1,145 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.atmosonline.saas.blobstore;
import static org.testng.Assert.assertEquals;
import java.io.IOException;
import java.util.Properties;
import org.jclouds.atmosonline.saas.AtmosStorageAsyncClient;
import org.jclouds.atmosonline.saas.config.AtmosStorageRestClientModule;
import org.jclouds.atmosonline.saas.filters.SignRequest;
import org.jclouds.blobstore.BlobRequestSigner;
import org.jclouds.blobstore.domain.Blob;
import org.jclouds.blobstore.domain.Blob.Factory;
import org.jclouds.date.TimeStamp;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.RequiresHttp;
import org.jclouds.io.payloads.PhantomPayload;
import org.jclouds.rest.ConfiguresRestClient;
import org.jclouds.rest.RestClientTest;
import org.jclouds.rest.RestContextFactory;
import org.jclouds.rest.RestContextFactory.ContextSpec;
import org.jclouds.rest.internal.RestAnnotationProcessor;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import com.google.common.base.Supplier;
import com.google.inject.Module;
import com.google.inject.TypeLiteral;
@Test(groups = "unit", testName = "emcsaas.AtmosBlobRequestSignerTest")
public class AtmosBlobRequestSignerTest extends RestClientTest<AtmosStorageAsyncClient> {
private BlobRequestSigner signer;
private Factory blobFactory;
public void testSignGetBlob() throws ArrayIndexOutOfBoundsException, SecurityException, IllegalArgumentException,
NoSuchMethodException, IOException {
HttpRequest request = signer.signGetBlob("container", "name");
assertRequestLineEquals(request, "GET https://accesspoint.atmosonline.com/rest/namespace/container/name HTTP/1.1");
assertNonPayloadHeadersEqual(
request,
"Accept: */*\nDate: Thu, 05 Jun 2008 16:38:19 GMT\nx-emc-signature: Mhe5tqaKv04BlMvEjreNKkHHxzk=\nx-emc-uid: identity\n");
assertPayloadEquals(request, null, null, false);
assertEquals(request.getFilters().size(), 0);
}
public void testSignRemoveBlob() throws ArrayIndexOutOfBoundsException, SecurityException, IllegalArgumentException,
NoSuchMethodException, IOException {
HttpRequest request = signer.signRemoveBlob("container", "name");
assertRequestLineEquals(request,
"DELETE https://accesspoint.atmosonline.com/rest/namespace/container/name HTTP/1.1");
assertNonPayloadHeadersEqual(
request,
"Accept: */*\nDate: Thu, 05 Jun 2008 16:38:19 GMT\nx-emc-signature: Q3zmO6KNAViNXquiCZSMx/0nuuc=\nx-emc-uid: identity\n");
assertPayloadEquals(request, null, null, false);
assertEquals(request.getFilters().size(), 0);
}
public void testSignPutBlob() throws ArrayIndexOutOfBoundsException, SecurityException, IllegalArgumentException,
NoSuchMethodException, IOException {
Blob blob = blobFactory.create(null);
blob.getMetadata().setName("name");
blob.setPayload(new PhantomPayload(2l, new byte[] { 0, 2, 4, 8 }));
blob.getPayload().setContentType("text/plain");
HttpRequest request = signer.signPutBlob("container", blob);
assertRequestLineEquals(request,
"POST https://accesspoint.atmosonline.com/rest/namespace/container/name HTTP/1.1");
assertNonPayloadHeadersEqual(
request,
"Accept: */*\nDate: Thu, 05 Jun 2008 16:38:19 GMT\nx-emc-signature: aLpB1oQaCA27AXT6Nzam7s0f0pI=\nx-emc-uid: identity\n");
assertContentHeadersEqual(request, "text/plain", (long) 2l, new byte[] { 0, 2, 4, 8 });
assertEquals(request.getFilters().size(), 0);
}
@BeforeClass
protected void setupFactory() throws IOException {
super.setupFactory();
this.blobFactory = injector.getInstance(Blob.Factory.class);
this.signer = injector.getInstance(BlobRequestSigner.class);
}
@Override
protected void checkFilters(HttpRequest request) {
assertEquals(request.getFilters().size(), 1);
assertEquals(request.getFilters().get(0).getClass(), SignRequest.class);
}
@Override
protected TypeLiteral<RestAnnotationProcessor<AtmosStorageAsyncClient>> createTypeLiteral() {
return new TypeLiteral<RestAnnotationProcessor<AtmosStorageAsyncClient>>() {
};
}
@Override
protected Module createModule() {
return new TestAtmosStorageRestClientModule();
}
@RequiresHttp
@ConfiguresRestClient
private static final class TestAtmosStorageRestClientModule extends AtmosStorageRestClientModule {
@Override
protected void configure() {
super.configure();
}
@Override
protected String provideTimeStamp(@TimeStamp Supplier<String> cache) {
return "Thu, 05 Jun 2008 16:38:19 GMT";
}
}
@Override
public ContextSpec<?, ?> createContextSpec() {
return new RestContextFactory().createContextSpec("atmosonline", "identity", "credential", new Properties());
}
}

View File

@ -0,0 +1,32 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.atmosonline.saas.blobstore.integration;
import org.jclouds.blobstore.integration.internal.BaseBlobSignerLiveTest;
import org.testng.annotations.Test;
/**
*
* @author Adrian Cole
*/
@Test(groups = { "live" }, testName = "emcsaas.AtmosBlobSignerLiveTest")
public class AtmosBlobSignerLiveTest extends BaseBlobSignerLiveTest {
}

View File

@ -39,7 +39,7 @@ public class AtmosStorageTestInitializer extends TransientBlobStoreTestInitializ
@Override @Override
protected BlobStoreContext createLiveContext(Module configurationModule, String url, String app, protected BlobStoreContext createLiveContext(Module configurationModule, String url, String app,
String identity, String credential) throws IOException { String identity, String credential) throws IOException {
return new BlobStoreContextFactory().createContext("atmosonline", identity, credential, ImmutableSet return new BlobStoreContextFactory().createContext("synaptic", identity, credential, ImmutableSet
.of(configurationModule, new Log4JLoggingModule()), new Properties()); .of(configurationModule, new Log4JLoggingModule()), new Properties());
} }

View File

@ -45,8 +45,8 @@ public class EC2PropertiesBuilder extends PropertiesBuilder {
properties.setProperty(PROPERTY_ENDPOINT, "https://ec2.us-east-1.amazonaws.com"); properties.setProperty(PROPERTY_ENDPOINT, "https://ec2.us-east-1.amazonaws.com");
properties.setProperty(PROPERTY_API_VERSION, EC2AsyncClient.VERSION); properties.setProperty(PROPERTY_API_VERSION, EC2AsyncClient.VERSION);
properties.setProperty(PROPERTY_ELB_ENDPOINT, "https://elasticloadbalancing.us-east-1.amazonaws.com"); properties.setProperty(PROPERTY_ELB_ENDPOINT, "https://elasticloadbalancing.us-east-1.amazonaws.com");
// alestic, canonical, and rightscale // amazon, alestic, canonical, and rightscale
properties.setProperty(PROPERTY_EC2_AMI_OWNERS, "063491364108,099720109477,411009282317"); properties.setProperty(PROPERTY_EC2_AMI_OWNERS, "137112412989,063491364108,099720109477,411009282317");
// amis that work with the cluster instances // amis that work with the cluster instances
properties.setProperty(PROPERTY_EC2_CC_AMIs, "us-east-1/ami-7ea24a17"); properties.setProperty(PROPERTY_EC2_CC_AMIs, "us-east-1/ami-7ea24a17");
// auth fail sometimes happens in EC2, as the rc.local script that injects the // auth fail sometimes happens in EC2, as the rc.local script that injects the

View File

@ -17,30 +17,31 @@
* ==================================================================== * ====================================================================
*/ */
package org.jclouds.vcloud.bluelock; package org.jclouds.aws.ec2;
import static org.jclouds.Constants.PROPERTY_ENDPOINT; import static org.jclouds.Constants.PROPERTY_ENDPOINT;
import static org.jclouds.vcloud.reference.VCloudConstants.PROPERTY_VCLOUD_DEFAULT_NETWORK; import static org.jclouds.aws.ec2.reference.EC2Constants.PROPERTY_EC2_AMI_OWNERS;
import static org.jclouds.aws.ec2.reference.EC2Constants.PROPERTY_EC2_CC_AMIs;
import java.util.Properties; import java.util.Properties;
import org.jclouds.vcloud.VCloudExpressPropertiesBuilder;
/** /**
* Builds properties used in bluelock VCloud Clients * Builds properties used in Eucalyptus Clients
* *
* @author Adrian Cole * @author Adrian Cole
*/ */
public class BlueLockVCloudExpressPropertiesBuilder extends VCloudExpressPropertiesBuilder { public class NovaPropertiesBuilder extends EC2PropertiesBuilder {
@Override @Override
protected Properties defaultProperties() { protected Properties defaultProperties() {
Properties properties = super.defaultProperties(); Properties properties = super.defaultProperties();
properties.setProperty(PROPERTY_ENDPOINT, "https://express.bluelock.com/api"); properties.setProperty(PROPERTY_ENDPOINT, "YOU_MUST_SET_" + PROPERTY_ENDPOINT);
properties.setProperty(PROPERTY_VCLOUD_DEFAULT_NETWORK, "Internal In and Out"); properties.setProperty(PROPERTY_EC2_AMI_OWNERS, "*");
properties.setProperty(PROPERTY_EC2_CC_AMIs, "");
return properties; return properties;
} }
public BlueLockVCloudExpressPropertiesBuilder(Properties properties) { public NovaPropertiesBuilder(Properties properties) {
super(properties); super(properties);
} }
} }

View File

@ -45,7 +45,7 @@ import org.jclouds.aws.ec2.domain.PlacementGroup.State;
import org.jclouds.compute.ComputeServiceContext; import org.jclouds.compute.ComputeServiceContext;
import org.jclouds.compute.domain.Image; import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.NodeMetadata; import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.Size; import org.jclouds.compute.domain.Hardware;
import org.jclouds.compute.domain.TemplateBuilder; import org.jclouds.compute.domain.TemplateBuilder;
import org.jclouds.compute.internal.BaseComputeService; import org.jclouds.compute.internal.BaseComputeService;
import org.jclouds.compute.options.TemplateOptions; import org.jclouds.compute.options.TemplateOptions;
@ -75,7 +75,7 @@ public class EC2ComputeService extends BaseComputeService {
@Inject @Inject
protected EC2ComputeService(ComputeServiceContext context, Supplier<Set<? extends Image>> images, protected EC2ComputeService(ComputeServiceContext context, Supplier<Set<? extends Image>> images,
Supplier<Set<? extends Size>> sizes, Supplier<Set<? extends Location>> locations, Supplier<Set<? extends Hardware>> sizes, Supplier<Set<? extends Location>> locations,
ListNodesStrategy listNodesStrategy, GetNodeMetadataStrategy getNodeMetadataStrategy, ListNodesStrategy listNodesStrategy, GetNodeMetadataStrategy getNodeMetadataStrategy,
RunNodesAndAddToSetStrategy runNodesAndAddToSetStrategy, RebootNodeStrategy rebootNodeStrategy, RunNodesAndAddToSetStrategy runNodesAndAddToSetStrategy, RebootNodeStrategy rebootNodeStrategy,
DestroyNodeStrategy destroyNodeStrategy, Provider<TemplateBuilder> templateBuilderProvider, DestroyNodeStrategy destroyNodeStrategy, Provider<TemplateBuilder> templateBuilderProvider,

View File

@ -24,6 +24,7 @@ import static com.google.common.collect.Maps.newLinkedHashMap;
import static org.jclouds.Constants.PROPERTY_SESSION_INTERVAL; import static org.jclouds.Constants.PROPERTY_SESSION_INTERVAL;
import static org.jclouds.aws.ec2.reference.EC2Constants.PROPERTY_EC2_AMI_OWNERS; import static org.jclouds.aws.ec2.reference.EC2Constants.PROPERTY_EC2_AMI_OWNERS;
import static org.jclouds.aws.ec2.reference.EC2Constants.PROPERTY_EC2_CC_AMIs; import static org.jclouds.aws.ec2.reference.EC2Constants.PROPERTY_EC2_CC_AMIs;
import static org.jclouds.compute.domain.OsFamily.AMZN_LINUX;
import static org.jclouds.compute.domain.OsFamily.CENTOS; import static org.jclouds.compute.domain.OsFamily.CENTOS;
import static org.jclouds.compute.domain.OsFamily.UBUNTU; import static org.jclouds.compute.domain.OsFamily.UBUNTU;
@ -36,7 +37,6 @@ import java.util.concurrent.TimeUnit;
import javax.inject.Named; import javax.inject.Named;
import javax.inject.Singleton; import javax.inject.Singleton;
import org.jclouds.aws.Region;
import org.jclouds.aws.ec2.EC2AsyncClient; import org.jclouds.aws.ec2.EC2AsyncClient;
import org.jclouds.aws.ec2.EC2Client; import org.jclouds.aws.ec2.EC2Client;
import org.jclouds.aws.ec2.compute.EC2ComputeService; import org.jclouds.aws.ec2.compute.EC2ComputeService;
@ -54,13 +54,12 @@ import org.jclouds.aws.ec2.compute.strategy.EC2ListNodesStrategy;
import org.jclouds.aws.ec2.compute.strategy.EC2LoadBalanceNodesStrategy; import org.jclouds.aws.ec2.compute.strategy.EC2LoadBalanceNodesStrategy;
import org.jclouds.aws.ec2.compute.strategy.EC2RebootNodeStrategy; import org.jclouds.aws.ec2.compute.strategy.EC2RebootNodeStrategy;
import org.jclouds.aws.ec2.compute.strategy.EC2RunNodesAndAddToSetStrategy; import org.jclouds.aws.ec2.compute.strategy.EC2RunNodesAndAddToSetStrategy;
import org.jclouds.aws.ec2.compute.suppliers.EC2HardwareSupplier;
import org.jclouds.aws.ec2.compute.suppliers.EC2LocationSupplier; import org.jclouds.aws.ec2.compute.suppliers.EC2LocationSupplier;
import org.jclouds.aws.ec2.compute.suppliers.EC2SizeSupplier;
import org.jclouds.aws.ec2.compute.suppliers.RegionAndNameToImageSupplier; import org.jclouds.aws.ec2.compute.suppliers.RegionAndNameToImageSupplier;
import org.jclouds.aws.ec2.domain.KeyPair; import org.jclouds.aws.ec2.domain.KeyPair;
import org.jclouds.aws.ec2.domain.PlacementGroup; import org.jclouds.aws.ec2.domain.PlacementGroup;
import org.jclouds.aws.ec2.domain.RunningInstance; import org.jclouds.aws.ec2.domain.RunningInstance;
import org.jclouds.aws.ec2.functions.RunningInstanceToStorageMappingUnix;
import org.jclouds.aws.ec2.predicates.InstancePresent; import org.jclouds.aws.ec2.predicates.InstancePresent;
import org.jclouds.aws.ec2.predicates.PlacementGroupAvailable; import org.jclouds.aws.ec2.predicates.PlacementGroupAvailable;
import org.jclouds.aws.ec2.predicates.PlacementGroupDeleted; import org.jclouds.aws.ec2.predicates.PlacementGroupDeleted;
@ -69,8 +68,8 @@ import org.jclouds.compute.ComputeService;
import org.jclouds.compute.ComputeServiceContext; import org.jclouds.compute.ComputeServiceContext;
import org.jclouds.compute.config.BaseComputeServiceContextModule; import org.jclouds.compute.config.BaseComputeServiceContextModule;
import org.jclouds.compute.config.ComputeServiceTimeoutsModule; import org.jclouds.compute.config.ComputeServiceTimeoutsModule;
import org.jclouds.compute.domain.Hardware;
import org.jclouds.compute.domain.Image; import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.Size;
import org.jclouds.compute.domain.TemplateBuilder; import org.jclouds.compute.domain.TemplateBuilder;
import org.jclouds.compute.internal.ComputeServiceContextImpl; import org.jclouds.compute.internal.ComputeServiceContextImpl;
import org.jclouds.compute.options.TemplateOptions; import org.jclouds.compute.options.TemplateOptions;
@ -84,6 +83,7 @@ import org.jclouds.compute.strategy.RunNodesAndAddToSetStrategy;
import org.jclouds.domain.Location; import org.jclouds.domain.Location;
import org.jclouds.predicates.RetryablePredicate; import org.jclouds.predicates.RetryablePredicate;
import org.jclouds.rest.RestContext; import org.jclouds.rest.RestContext;
import org.jclouds.rest.annotations.Provider;
import org.jclouds.rest.internal.RestContextImpl; import org.jclouds.rest.internal.RestContextImpl;
import org.jclouds.rest.suppliers.RetryOnTimeOutButNotOnAuthorizationExceptionSupplier; import org.jclouds.rest.suppliers.RetryOnTimeOutButNotOnAuthorizationExceptionSupplier;
@ -99,7 +99,6 @@ import com.google.inject.Key;
import com.google.inject.Provides; import com.google.inject.Provides;
import com.google.inject.Scopes; import com.google.inject.Scopes;
import com.google.inject.TypeLiteral; import com.google.inject.TypeLiteral;
import com.google.inject.name.Names;
/** /**
* Configures the {@link ComputeServiceContext}; requires {@link EC2ComputeService} bound. * Configures the {@link ComputeServiceContext}; requires {@link EC2ComputeService} bound.
@ -148,8 +147,6 @@ public class EC2ComputeServiceContextModule extends BaseComputeServiceContextMod
bind(GetNodeMetadataStrategy.class).to(EC2GetNodeMetadataStrategy.class); bind(GetNodeMetadataStrategy.class).to(EC2GetNodeMetadataStrategy.class);
bind(RebootNodeStrategy.class).to(EC2RebootNodeStrategy.class); bind(RebootNodeStrategy.class).to(EC2RebootNodeStrategy.class);
bind(DestroyNodeStrategy.class).to(EC2DestroyNodeStrategy.class); bind(DestroyNodeStrategy.class).to(EC2DestroyNodeStrategy.class);
bind(new TypeLiteral<Function<RunningInstance, Map<String, String>>>() {
}).annotatedWith(Names.named("volumeMapping")).to(RunningInstanceToStorageMappingUnix.class).in(Scopes.SINGLETON);
} }
@Provides @Provides
@ -168,9 +165,13 @@ public class EC2ComputeServiceContextModule extends BaseComputeServiceContextMod
@Override @Override
protected TemplateBuilder provideTemplate(Injector injector, TemplateBuilder template) { protected TemplateBuilder provideTemplate(Injector injector, TemplateBuilder template) {
String region = injector.getInstance(Key.get(String.class, Region.class)); String provider = injector.getInstance(Key.get(String.class, Provider.class));
return "Eucalyptus".equals(region) ? template.osFamily(CENTOS).smallest() : template.os64Bit(false).osFamily( if ("eucalyptus".equals(provider))
UBUNTU).osVersionMatches(".*10\\.?04.*").osDescriptionMatches("^ubuntu-images.*"); return template.osFamily(CENTOS);
else if ("nova".equals(provider))
return template.osFamily(UBUNTU);
else
return template.osFamily(AMZN_LINUX).os64Bit(true);
} }
@Provides @Provides
@ -255,8 +256,8 @@ public class EC2ComputeServiceContextModule extends BaseComputeServiceContextMod
} }
@Override @Override
protected Supplier<Set<? extends Size>> getSourceSizeSupplier(Injector injector) { protected Supplier<Set<? extends Hardware>> getSourceSizeSupplier(Injector injector) {
return injector.getInstance(EC2SizeSupplier.class); return injector.getInstance(EC2HardwareSupplier.class);
} }
@Override @Override

View File

@ -0,0 +1,197 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.aws.ec2.compute.domain;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Predicates.not;
import static org.jclouds.compute.predicates.ImagePredicates.any;
import static org.jclouds.compute.predicates.ImagePredicates.idIn;
import static org.jclouds.compute.predicates.ImagePredicates.is64Bit;
import java.util.Arrays;
import org.jclouds.aws.ec2.domain.InstanceType;
import org.jclouds.aws.ec2.domain.RootDeviceType;
import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.Processor;
import org.jclouds.compute.domain.Volume;
import org.jclouds.compute.domain.internal.HardwareImpl;
import org.jclouds.compute.domain.internal.VolumeImpl;
import org.jclouds.domain.Location;
import com.google.common.base.Predicate;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
/**
*
* @author Adrian Cole
* @see <a
* href="http://docs.amazonwebservices.com/AWSEC2/latest/UserGuide/index.html?instance-types.html"
* />
*/
public class EC2Hardware extends HardwareImpl {
/** The serialVersionUID */
private static final long serialVersionUID = 8605688733788974797L;
private final String instanceType;
/**
* evaluates true if the Image has the following rootDeviceType
*
* @param type
* rootDeviceType of the image
* @return predicate
*/
public static Predicate<Image> hasRootDeviceType(final RootDeviceType type) {
checkNotNull(type, "type must be defined");
return new Predicate<Image>() {
@Override
public boolean apply(Image image) {
return type.toString().equals(image.getUserMetadata().get("rootDeviceType"));
}
@Override
public String toString() {
return "hasRootDeviceType(" + type + ")";
}
};
}
EC2Hardware(String instanceType, Iterable<? extends Processor> processors, Integer ram,
Iterable<? extends Volume> volumes, RootDeviceType rootDeviceType) {
this(null, instanceType, processors, ram, volumes, hasRootDeviceType(rootDeviceType));
}
EC2Hardware(Location location, String instanceType, Iterable<? extends Processor> processors, Integer ram,
Iterable<? extends Volume> volumes, Predicate<Image> supportsImage) {
super(instanceType, instanceType, instanceType, location, null, ImmutableMap.<String, String> of(), processors,
ram, volumes, supportsImage);
this.instanceType = instanceType;
}
EC2Hardware(String instanceType, Iterable<? extends Processor> processors, Integer ram,
Iterable<? extends Volume> volumes, boolean is64Bit) {
this(null, instanceType, processors, ram, volumes, is64Bit ? is64Bit() : not(is64Bit()));
}
public EC2Hardware(Location location, String instanceType, Iterable<? extends Processor> processors, Integer ram,
Iterable<? extends Volume> volumes, String[] ids) {
this(location, instanceType, processors, ram, volumes, (ids.length == 0 ? is64Bit() : idIn(Arrays.asList(ids))));
}
/**
* Returns the EC2 InstanceType associated with this size.
*/
public String getInstanceType() {
return instanceType;
}
/**
* @see InstanceType#M1_SMALL
*/
public static final EC2Hardware M1_SMALL = new EC2Hardware(InstanceType.M1_SMALL, ImmutableList.of(new Processor(
1.0, 1.0)), 1740, ImmutableList.of(new VolumeImpl(10.0f, "/dev/sda1", true, false), new VolumeImpl(150.0f,
"/dev/sda2", false, false)), false);
/**
* In Nova, m1.small can run 64bit images.
*
* @see InstanceType#M1_SMALL
*/
public static final EC2Hardware M1_SMALL_NOVA = new EC2Hardware(null, InstanceType.M1_SMALL, ImmutableList
.of(new Processor(1.0, 1.0)), 1740, ImmutableList.of(new VolumeImpl(10.0f, "/dev/sda1", true, false),
new VolumeImpl(150.0f, "/dev/sda2", false, false)), any());
/**
* @see InstanceType#T1_MICRO
*/
public static final EC2Hardware T1_MICRO = new EC2Hardware(InstanceType.T1_MICRO, ImmutableList.of(new Processor(
1.0, 1.0)), 630, ImmutableList.<Volume> of(), RootDeviceType.EBS);
/**
* @see InstanceType#M1_LARGE
*/
public static final EC2Hardware M1_LARGE = new EC2Hardware(InstanceType.M1_LARGE, ImmutableList.of(new Processor(
2.0, 2.0)), 7680, ImmutableList.of(new VolumeImpl(10.0f, "/dev/sda1", true, false), new VolumeImpl(420.0f,
"/dev/sdb", false, false), new VolumeImpl(420.0f, "/dev/sdc", false, false)), true);
/**
* @see InstanceType#M1_XLARGE
*/
public static final EC2Hardware M1_XLARGE = new EC2Hardware(InstanceType.M1_XLARGE, ImmutableList.of(new Processor(
4.0, 2.0)), 15360, ImmutableList.of(new VolumeImpl(10.0f, "/dev/sda1", true, false), new VolumeImpl(420.0f,
"/dev/sdb", false, false), new VolumeImpl(420.0f, "/dev/sdc", false, false), new VolumeImpl(420.0f,
"/dev/sdd", false, false), new VolumeImpl(420.0f, "/dev/sde", false, false)), true);
/**
* @see InstanceType#M2_XLARGE
*/
public static final EC2Hardware M2_XLARGE = new EC2Hardware(InstanceType.M2_XLARGE, ImmutableList.of(new Processor(
2.0, 3.25)), 17510, ImmutableList.of(new VolumeImpl(420.0f, "/dev/sda1", true, false)), true);
/**
* @see InstanceType#M2_2XLARGE
*/
public static final EC2Hardware M2_2XLARGE = new EC2Hardware(InstanceType.M2_2XLARGE, ImmutableList
.of(new Processor(4.0, 3.25)), 35020, ImmutableList.of(new VolumeImpl(10.0f, "/dev/sda1", true, false),
new VolumeImpl(840.0f, "/dev/sdb", false, false)), true);
/**
* @see InstanceType#M2_4XLARGE
*/
public static final EC2Hardware M2_4XLARGE = new EC2Hardware(InstanceType.M2_4XLARGE, ImmutableList
.of(new Processor(8.0, 3.25)), 70041, ImmutableList.of(new VolumeImpl(10.0f, "/dev/sda1", true, false),
new VolumeImpl(840.0f, "/dev/sdb", false, false), new VolumeImpl(840.0f, "/dev/sdc", false, false)), true);
/**
* @see InstanceType#C1_MEDIUM
*/
public static final EC2Hardware C1_MEDIUM = new EC2Hardware(InstanceType.C1_MEDIUM, ImmutableList.of(new Processor(
2.0, 2.5)), 1740, ImmutableList.of(new VolumeImpl(10.0f, "/dev/sda1", true, false), new VolumeImpl(340.0f,
"/dev/sda2", false, false)), false);
/**
* @see InstanceType#C1_XLARGE
*/
public static final EC2Hardware C1_XLARGE = new EC2Hardware(InstanceType.C1_XLARGE, ImmutableList.of(new Processor(
8.0, 2.5)), 7168, ImmutableList.of(new VolumeImpl(10.0f, "/dev/sda1", true, false), new VolumeImpl(420.0f,
"/dev/sdb", false, false), new VolumeImpl(420.0f, "/dev/sdc", false, false), new VolumeImpl(420.0f,
"/dev/sdd", false, false), new VolumeImpl(420.0f, "/dev/sde", false, false)), true);
@Override
public int hashCode() {
final int prime = 31;
int result = super.hashCode();
result = prime * result + ((instanceType == null) ? 0 : instanceType.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (!super.equals(obj))
return false;
if (getClass() != obj.getClass())
return false;
EC2Hardware other = (EC2Hardware) obj;
if (instanceType == null) {
if (other.instanceType != null)
return false;
} else if (!instanceType.equals(other.instanceType))
return false;
return true;
}
}

View File

@ -1,121 +0,0 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.aws.ec2.compute.domain;
import static com.google.common.base.Predicates.not;
import static org.jclouds.compute.predicates.ImagePredicates.idIn;
import static org.jclouds.compute.predicates.ImagePredicates.is64Bit;
import java.util.Arrays;
import org.jclouds.aws.ec2.domain.InstanceType;
import org.jclouds.compute.domain.internal.SizeImpl;
import org.jclouds.domain.Location;
import com.google.common.collect.ImmutableMap;
/**
*
* @author Adrian Cole
*/
public class EC2Size extends SizeImpl {
/** The serialVersionUID */
private static final long serialVersionUID = 8605688733788974797L;
private final String instanceType;
EC2Size(String instanceType, Double cores, Integer ram, Integer disk, boolean is64Bit) {
super(instanceType, instanceType, instanceType, null, null, ImmutableMap.<String, String> of(), cores, ram, disk,
is64Bit ? is64Bit() : not(is64Bit()));
this.instanceType = instanceType;
}
public EC2Size(Location location, String instanceType, Double cores, Integer ram, Integer disk, String[] ids) {
super(instanceType, instanceType, instanceType, location, null, ImmutableMap.<String, String> of(), cores, ram,
disk, (ids.length == 0 ? is64Bit() : idIn(Arrays.asList(ids))));
this.instanceType = instanceType;
}
/**
* Returns the EC2 InstanceType associated with this size.
*/
public String getInstanceType() {
return instanceType;
}
/**
* @see InstanceType#M1_SMALL
*/
public static final EC2Size M1_SMALL = new EC2Size(InstanceType.M1_SMALL, 1.0, 1740, 160, false);
/**
* @see InstanceType#M1_LARGE
*/
public static final EC2Size M1_LARGE = new EC2Size(InstanceType.M1_LARGE, 4.0, 7680, 850, true);
/**
* @see InstanceType#M1_XLARGE
*/
public static final EC2Size M1_XLARGE = new EC2Size(InstanceType.M1_XLARGE, 8.0, 15360, 1690, true);
/**
* @see InstanceType#M2_XLARGE
*/
public static final EC2Size M2_XLARGE = new EC2Size(InstanceType.M2_XLARGE, 6.5, 17510, 420, true);
/**
* @see InstanceType#M2_2XLARGE
*/
public static final EC2Size M2_2XLARGE = new EC2Size(InstanceType.M2_2XLARGE, 13.0, 35020, 850, true);
/**
* @see InstanceType#M2_4XLARGE
*/
public static final EC2Size M2_4XLARGE = new EC2Size(InstanceType.M2_4XLARGE, 26.0, 70041, 1690, true);
/**
* @see InstanceType#C1_MEDIUM
*/
public static final EC2Size C1_MEDIUM = new EC2Size(InstanceType.C1_MEDIUM, 5.0, 1740, 350, false);
/**
* @see InstanceType#C1_XLARGE
*/
public static final EC2Size C1_XLARGE = new EC2Size(InstanceType.C1_XLARGE, 20.0, 7168, 1690, true);
@Override
public int hashCode() {
final int prime = 31;
int result = super.hashCode();
result = prime * result + ((instanceType == null) ? 0 : instanceType.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (!super.equals(obj))
return false;
if (getClass() != obj.getClass())
return false;
EC2Size other = (EC2Size) obj;
if (instanceType == null) {
if (other.instanceType != null)
return false;
} else if (!instanceType.equals(other.instanceType))
return false;
return true;
}
}

View File

@ -26,7 +26,6 @@ import javax.inject.Inject;
import javax.inject.Named; import javax.inject.Named;
import javax.inject.Singleton; import javax.inject.Singleton;
import org.jclouds.aws.AWSResponseException;
import org.jclouds.aws.ec2.EC2Client; import org.jclouds.aws.ec2.EC2Client;
import org.jclouds.aws.ec2.compute.domain.RegionNameAndIngressRules; import org.jclouds.aws.ec2.compute.domain.RegionNameAndIngressRules;
import org.jclouds.aws.ec2.domain.IpProtocol; import org.jclouds.aws.ec2.domain.IpProtocol;
@ -72,13 +71,8 @@ public class CreateSecurityGroupIfNeeded implements Function<RegionNameAndIngres
if (ports.length > 0) { if (ports.length > 0) {
authorizeGroupToItself(region, name); authorizeGroupToItself(region, name);
} }
} catch (AWSResponseException e) { } catch (IllegalStateException e) {
if (e.getError().getCode().equals("InvalidGroup.Duplicate")
|| e.getError().getMessage().endsWith("already exists")) {
logger.debug("<< reused securityGroup(%s)", name); logger.debug("<< reused securityGroup(%s)", name);
} else {
throw e;
}
} }
} }

View File

@ -46,6 +46,7 @@ import org.jclouds.domain.Location;
import org.jclouds.domain.LocationScope; import org.jclouds.domain.LocationScope;
import org.jclouds.domain.internal.LocationImpl; import org.jclouds.domain.internal.LocationImpl;
import org.jclouds.logging.Logger; import org.jclouds.logging.Logger;
import org.jclouds.rest.annotations.Provider;
import com.google.common.base.Function; import com.google.common.base.Function;
import com.google.common.base.Predicate; import com.google.common.base.Predicate;
@ -62,6 +63,17 @@ public class ImageParser implements Function<org.jclouds.aws.ec2.domain.Image, I
@Named(ComputeServiceConstants.COMPUTE_LOGGER) @Named(ComputeServiceConstants.COMPUTE_LOGGER)
protected Logger logger = Logger.NULL; protected Logger logger = Logger.NULL;
// nebula/ubuntu-karmic
// nebula/karmic-large
public static final Pattern NEBULA_PATTERN = Pattern.compile("nebula/(ubuntu-)?(.*)(-.*)?");
// 137112412989/amzn-ami-0.9.7-beta.i386-ebs
// 137112412989/amzn-ami-0.9.7-beta.x86_64-ebs
// amzn-ami-us-east-1/amzn-ami-0.9.7-beta.x86_64.manifest.xml
// amzn-ami-us-east-1/amzn-ami-0.9.7-beta.i386.manifest.xml
public static final Pattern AMZN_PATTERN = Pattern
.compile(".*/amzn-ami-(.*)\\.(i386|x86_64)(-ebs|\\.manifest.xml)?");
public static final Pattern CANONICAL_PATTERN = Pattern.compile(".*/([^-]*)-([^-]*)-.*-(.*)(\\.manifest.xml)?"); public static final Pattern CANONICAL_PATTERN = Pattern.compile(".*/([^-]*)-([^-]*)-.*-(.*)(\\.manifest.xml)?");
// ex rightscale-us-east/CentOS_5.4_x64_v4.4.10.manifest.xml // ex rightscale-us-east/CentOS_5.4_x64_v4.4.10.manifest.xml
@ -76,22 +88,19 @@ public class ImageParser implements Function<org.jclouds.aws.ec2.domain.Image, I
private final Supplier<Set<? extends Location>> locations; private final Supplier<Set<? extends Location>> locations;
private final Supplier<Location> defaultLocation; private final Supplier<Location> defaultLocation;
private final String provider;
@Inject @Inject
ImageParser(PopulateDefaultLoginCredentialsForImageStrategy credentialProvider, ImageParser(PopulateDefaultLoginCredentialsForImageStrategy credentialProvider,
Supplier<Set<? extends Location>> locations, Supplier<Location> defaultLocation) { Supplier<Set<? extends Location>> locations, Supplier<Location> defaultLocation, @Provider String provider) {
this.credentialProvider = checkNotNull(credentialProvider, "credentialProvider"); this.credentialProvider = checkNotNull(credentialProvider, "credentialProvider");
this.locations = checkNotNull(locations, "locations"); this.locations = checkNotNull(locations, "locations");
this.defaultLocation = checkNotNull(defaultLocation, "defaultLocation"); this.defaultLocation = checkNotNull(defaultLocation, "defaultLocation");
this.provider = checkNotNull(provider, "provider");
} }
@Override @Override
public Image apply(final org.jclouds.aws.ec2.domain.Image from) { public Image apply(final org.jclouds.aws.ec2.domain.Image from) {
if (from.getImageLocation().indexOf("test") != -1) {
logger.trace("skipping test image(%s)", from.getId());
return null;
}
if (from.getImageType() != ImageType.MACHINE) { if (from.getImageType() != ImageType.MACHINE) {
logger.trace("skipping as not a machine image(%s)", from.getId()); logger.trace("skipping as not a machine image(%s)", from.getId());
return null; return null;
@ -100,7 +109,7 @@ public class ImageParser implements Function<org.jclouds.aws.ec2.domain.Image, I
String description = from.getDescription() != null ? from.getDescription() : from.getImageLocation(); String description = from.getDescription() != null ? from.getDescription() : from.getImageLocation();
String version = null; String version = null;
OsFamily osFamily = parseOsFamilyOrNull(from.getImageLocation()); OsFamily osFamily = parseOsFamilyOrNull(provider, from.getImageLocation());
String osName = null; String osName = null;
String osArch = from.getVirtualizationType(); String osArch = from.getVirtualizationType();
String osVersion = parseVersionOrReturnEmptyString(osFamily, from.getImageLocation()); String osVersion = parseVersionOrReturnEmptyString(osFamily, from.getImageLocation());
@ -108,9 +117,16 @@ public class ImageParser implements Function<org.jclouds.aws.ec2.domain.Image, I
boolean is64Bit = from.getArchitecture() == Architecture.X86_64; boolean is64Bit = from.getArchitecture() == Architecture.X86_64;
try { try {
Matcher matcher = getMatcherAndFind(from.getImageLocation()); Matcher matcher = getMatcherAndFind(from.getImageLocation());
if (matcher.pattern() == AMZN_PATTERN) {
osFamily = OsFamily.AMZN_LINUX;
version = osVersion = matcher.group(1);
} else if (matcher.pattern() == NEBULA_PATTERN) {
osVersion = parseVersionOrReturnEmptyString(osFamily, matcher.group(2));
} else {
osFamily = OsFamily.fromValue(matcher.group(1)); osFamily = OsFamily.fromValue(matcher.group(1));
osVersion = parseVersionOrReturnEmptyString(osFamily, matcher.group(2)); osVersion = parseVersionOrReturnEmptyString(osFamily, matcher.group(2));
version = matcher.group(3).replace(".manifest.xml", ""); version = matcher.group(3).replace(".manifest.xml", "");
}
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
logger.debug("<< didn't match os(%s)", from.getImageLocation()); logger.debug("<< didn't match os(%s)", from.getImageLocation());
} catch (NoSuchElementException e) { } catch (NoSuchElementException e) {
@ -136,7 +152,8 @@ public class ImageParser implements Function<org.jclouds.aws.ec2.domain.Image, I
} }
OperatingSystem os = new OperatingSystem(osFamily, osName, osVersion, osArch, osDescription, is64Bit); OperatingSystem os = new OperatingSystem(osFamily, osName, osVersion, osArch, osDescription, is64Bit);
return new ImageImpl(from.getId(), name, from.getRegion() + "/" + from.getId(), location, null, ImmutableMap return new ImageImpl(from.getId(), name, from.getRegion() + "/" + from.getId(), location, null, ImmutableMap
.<String, String> of("owner", from.getImageOwnerId()), os, description, version, defaultCredentials); .<String, String> of("owner", from.getImageOwnerId(), "rootDeviceType", from.getRootDeviceType()
.toString()), os, description, version, defaultCredentials);
} }
@ -146,7 +163,8 @@ public class ImageParser implements Function<org.jclouds.aws.ec2.domain.Image, I
* if no configured matcher matches the manifest. * if no configured matcher matches the manifest.
*/ */
private Matcher getMatcherAndFind(String manifest) { private Matcher getMatcherAndFind(String manifest) {
for (Pattern pattern : new Pattern[] { CANONICAL_PATTERN, RIGHTIMAGE_PATTERN, RIGHTSCALE_PATTERN }) { for (Pattern pattern : new Pattern[] { AMZN_PATTERN, NEBULA_PATTERN, CANONICAL_PATTERN, RIGHTIMAGE_PATTERN,
RIGHTSCALE_PATTERN }) {
Matcher matcher = pattern.matcher(manifest); Matcher matcher = pattern.matcher(manifest);
if (matcher.find()) if (matcher.find())
return matcher; return matcher;

View File

@ -26,24 +26,30 @@ import java.net.URI;
import java.util.Map; import java.util.Map;
import java.util.NoSuchElementException; import java.util.NoSuchElementException;
import java.util.Set; import java.util.Set;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentMap; import java.util.concurrent.ConcurrentMap;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton; import javax.inject.Singleton;
import org.jclouds.aws.ec2.EC2Client; import org.jclouds.aws.ec2.EC2Client;
import org.jclouds.aws.ec2.compute.domain.RegionAndName; import org.jclouds.aws.ec2.compute.domain.RegionAndName;
import org.jclouds.aws.ec2.domain.InstanceState; import org.jclouds.aws.ec2.domain.InstanceState;
import org.jclouds.aws.ec2.domain.KeyPair; import org.jclouds.aws.ec2.domain.KeyPair;
import org.jclouds.aws.ec2.domain.RootDeviceType;
import org.jclouds.aws.ec2.domain.RunningInstance; import org.jclouds.aws.ec2.domain.RunningInstance;
import org.jclouds.aws.ec2.domain.RunningInstance.EbsBlockDevice;
import org.jclouds.aws.ec2.options.DescribeImagesOptions; import org.jclouds.aws.ec2.options.DescribeImagesOptions;
import org.jclouds.compute.domain.Hardware;
import org.jclouds.compute.domain.Image; import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.NodeMetadata; import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.NodeState; import org.jclouds.compute.domain.NodeState;
import org.jclouds.compute.domain.Volume;
import org.jclouds.compute.domain.internal.NodeMetadataImpl; import org.jclouds.compute.domain.internal.NodeMetadataImpl;
import org.jclouds.compute.domain.internal.VolumeImpl;
import org.jclouds.compute.strategy.PopulateDefaultLoginCredentialsForImageStrategy; import org.jclouds.compute.strategy.PopulateDefaultLoginCredentialsForImageStrategy;
import org.jclouds.compute.util.ComputeServiceUtils;
import org.jclouds.domain.Credentials; import org.jclouds.domain.Credentials;
import org.jclouds.domain.Location; import org.jclouds.domain.Location;
import org.jclouds.logging.Logger; import org.jclouds.logging.Logger;
@ -52,9 +58,9 @@ import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Function; import com.google.common.base.Function;
import com.google.common.base.Predicate; import com.google.common.base.Predicate;
import com.google.common.base.Supplier; import com.google.common.base.Supplier;
import com.google.common.collect.ComputationException;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables; import com.google.common.collect.Iterables;
import com.google.common.collect.Maps;
/** /**
* @author Adrian Cole * @author Adrian Cole
@ -76,19 +82,19 @@ public class RunningInstanceToNodeMetadata implements Function<RunningInstance,
private final Map<RegionAndName, KeyPair> credentialsMap; private final Map<RegionAndName, KeyPair> credentialsMap;
private final PopulateDefaultLoginCredentialsForImageStrategy credentialProvider; private final PopulateDefaultLoginCredentialsForImageStrategy credentialProvider;
private final Supplier<Set<? extends Location>> locations; private final Supplier<Set<? extends Location>> locations;
private final Function<RunningInstance, Map<String, String>> instanceToStorageMapping; private final Supplier<Set<? extends Hardware>> hardware;
private final ConcurrentMap<RegionAndName, Image> imageMap; private final ConcurrentMap<RegionAndName, Image> imageMap;
@Inject @Inject
RunningInstanceToNodeMetadata(EC2Client client, Map<RegionAndName, KeyPair> credentialsMap, RunningInstanceToNodeMetadata(EC2Client client, Map<RegionAndName, KeyPair> credentialsMap,
PopulateDefaultLoginCredentialsForImageStrategy credentialProvider, PopulateDefaultLoginCredentialsForImageStrategy credentialProvider,
ConcurrentMap<RegionAndName, Image> imageMap, Supplier<Set<? extends Location>> locations, ConcurrentMap<RegionAndName, Image> imageMap, Supplier<Set<? extends Location>> locations,
@Named("volumeMapping") Function<RunningInstance, Map<String, String>> instanceToStorageMapping) { Supplier<Set<? extends Hardware>> hardware) {
this.client = checkNotNull(client, "client"); this.client = checkNotNull(client, "client");
this.credentialsMap = checkNotNull(credentialsMap, "credentialsMap"); this.credentialsMap = checkNotNull(credentialsMap, "credentialsMap");
this.credentialProvider = checkNotNull(credentialProvider, "credentialProvider"); this.credentialProvider = checkNotNull(credentialProvider, "credentialProvider");
this.locations = checkNotNull(locations, "locations"); this.locations = checkNotNull(locations, "locations");
this.instanceToStorageMapping = checkNotNull(instanceToStorageMapping, "instanceToStorageMapping"); this.hardware = checkNotNull(hardware, "hardware");
this.imageMap = checkNotNull(imageMap, "imageMap"); this.imageMap = checkNotNull(imageMap, "imageMap");
} }
@ -110,15 +116,47 @@ public class RunningInstanceToNodeMetadata implements Function<RunningInstance,
Set<String> publicAddresses = nullSafeSet(instance.getIpAddress()); Set<String> publicAddresses = nullSafeSet(instance.getIpAddress());
Set<String> privateAddresses = nullSafeSet(instance.getPrivateIpAddress()); Set<String> privateAddresses = nullSafeSet(instance.getPrivateIpAddress());
Map<String, String> extra = getExtra(instance); Hardware hardware = getHardwareForInstance(instance);
Location location = getLocationForAvailabilityZone(instance); if (hardware != null) {
hardware = ComputeServiceUtils.replacesVolumes(hardware, addEBS(instance, hardware.getVolumes()));
}
Location location = getLocationForAvailabilityZoneOrRegion(instance);
Image image = resolveImageForInstanceInLocation(instance, location); Image image = resolveImageForInstanceInLocation(instance, location);
return new NodeMetadataImpl(id, name, instance.getRegion() + "/" + instance.getId(), location, uri, userMetadata, return new NodeMetadataImpl(id, name, instance.getRegion() + "/" + instance.getId(), location, uri, userMetadata,
tag, instance.getRegion() + "/" + instance.getImageId(), image != null ? image.getOperatingSystem() tag, hardware, instance.getRegion() + "/" + instance.getImageId(), image != null ? image
: null, state, publicAddresses, privateAddresses, extra, credentials); .getOperatingSystem() : null, state, publicAddresses, privateAddresses, credentials);
}
@VisibleForTesting
static Iterable<? extends Volume> addEBS(final RunningInstance instance, Iterable<? extends Volume> volumes) {
Iterable<Volume> ebsVolumes = Iterables.transform(instance.getEbsBlockDevices().entrySet(),
new Function<Entry<String, EbsBlockDevice>, Volume>() {
@Override
public Volume apply(Entry<String, EbsBlockDevice> from) {
return new VolumeImpl(from.getValue().getVolumeId(), Volume.Type.SAN, null, from.getKey(),
instance.getRootDeviceName() != null
&& instance.getRootDeviceName().equals(from.getKey()), true);
}
});
if (instance.getRootDeviceType() == RootDeviceType.EBS) {
volumes = Iterables.filter(volumes, new Predicate<Volume>() {
@Override
public boolean apply(Volume input) {
return !input.isBootDevice();
}
});
}
return Iterables.concat(volumes, ebsVolumes);
} }
private Credentials getCredentialsForInstanceWithTag(final RunningInstance instance, String tag) { private Credentials getCredentialsForInstanceWithTag(final RunningInstance instance, String tag) {
@ -152,9 +190,32 @@ public class RunningInstanceToNodeMetadata implements Function<RunningInstance,
return tag; return tag;
} }
private Location getLocationForAvailabilityZone(final RunningInstance instance) { @VisibleForTesting
final String locationId = instance.getAvailabilityZone(); Hardware getHardwareForInstance(final RunningInstance instance) {
try {
return Iterables.find(hardware.get(), new Predicate<Hardware>() {
@Override
public boolean apply(Hardware input) {
return input.getId().equals(instance.getInstanceType());
}
});
} catch (NoSuchElementException e) {
logger.debug("couldn't match instance type %s in: %s", instance.getInstanceType(), hardware.get());
return null;
}
}
private Location getLocationForAvailabilityZoneOrRegion(final RunningInstance instance) {
Location location = findLocationWithId(instance.getAvailabilityZone());
if (location == null)
location = findLocationWithId(instance.getRegion());
return location;
}
private Location findLocationWithId(final String locationId) {
try {
Location location = Iterables.find(locations.get(), new Predicate<Location>() { Location location = Iterables.find(locations.get(), new Predicate<Location>() {
@Override @Override
@ -164,6 +225,11 @@ public class RunningInstanceToNodeMetadata implements Function<RunningInstance,
}); });
return location; return location;
} catch (NoSuchElementException e) {
logger.debug("couldn't match instance location %s in: %s", locationId, locations.get());
return null;
}
} }
@VisibleForTesting @VisibleForTesting
@ -174,34 +240,12 @@ public class RunningInstanceToNodeMetadata implements Function<RunningInstance,
image = imageMap.get(key); image = imageMap.get(key);
} catch (NullPointerException nex) { } catch (NullPointerException nex) {
logger.debug("could not find a matching image for instance %s in location %s", instance, location); logger.debug("could not find a matching image for instance %s in location %s", instance, location);
} catch (ComputationException nex) {
logger.debug("could not find a matching image for instance %s in location %s", instance, location);
} }
return image; return image;
} }
/**
* Set extras for the node.
*
* Extras are derived from either additional API calls or hard-coded values.
*
* @param instance
* instance for which the extras are retrieved
* @return map with extras
*/
@VisibleForTesting
Map<String, String> getExtra(RunningInstance instance) {
Map<String, String> extra = Maps.newHashMap();
extra.put("virtualizationType", instance.getVirtualizationType());
if (instance.getPlacementGroup() != null)
extra.put("placementGroup", instance.getPlacementGroup());
if (instance.getSubnetId() != null)
extra.put("subnetId", instance.getSubnetId());
// put storage info
/* TODO: only valid for UNIX */
extra.putAll(instanceToStorageMapping.apply(instance));
return extra;
}
@VisibleForTesting @VisibleForTesting
String getPrivateKeyOrNull(RunningInstance instance, String tag) { String getPrivateKeyOrNull(RunningInstance instance, String tag) {
KeyPair keyPair = credentialsMap.get(new RegionAndName(instance.getRegion(), instance.getKeyName())); KeyPair keyPair = credentialsMap.get(new RegionAndName(instance.getRegion(), instance.getKeyName()));
@ -210,8 +254,13 @@ public class RunningInstanceToNodeMetadata implements Function<RunningInstance,
@VisibleForTesting @VisibleForTesting
String getLoginAccountFor(RunningInstance from) { String getLoginAccountFor(RunningInstance from) {
org.jclouds.aws.ec2.domain.Image image = Iterables.getOnlyElement(client.getAMIServices().describeImagesInRegion( org.jclouds.aws.ec2.domain.Image image = null;
from.getRegion(), DescribeImagesOptions.Builder.imageIds(from.getImageId()))); try {
image = Iterables.getOnlyElement(client.getAMIServices().describeImagesInRegion(from.getRegion(),
DescribeImagesOptions.Builder.imageIds(from.getImageId())));
} catch (NoSuchElementException e) {
logger.debug("couldn't find image %s/%s", from.getRegion(), from.getImageId());
}
return checkNotNull(credentialProvider.execute(image), "login from image: " + from.getImageId()).identity; return checkNotNull(credentialProvider.execute(image), "login from image: " + from.getImageId()).identity;
} }

View File

@ -31,14 +31,15 @@ import javax.inject.Provider;
import org.jclouds.aws.ec2.compute.domain.RegionAndName; import org.jclouds.aws.ec2.compute.domain.RegionAndName;
import org.jclouds.aws.ec2.compute.options.EC2TemplateOptions; import org.jclouds.aws.ec2.compute.options.EC2TemplateOptions;
import org.jclouds.compute.domain.Hardware;
import org.jclouds.compute.domain.Image; import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.Size;
import org.jclouds.compute.domain.TemplateBuilder; import org.jclouds.compute.domain.TemplateBuilder;
import org.jclouds.compute.domain.internal.TemplateBuilderImpl; import org.jclouds.compute.domain.internal.TemplateBuilderImpl;
import org.jclouds.compute.options.TemplateOptions; import org.jclouds.compute.options.TemplateOptions;
import org.jclouds.domain.Location; import org.jclouds.domain.Location;
import com.google.common.base.Supplier; import com.google.common.base.Supplier;
import com.google.common.collect.ComputationException;
/** /**
* *
@ -50,7 +51,7 @@ public class EC2TemplateBuilderImpl extends TemplateBuilderImpl {
@Inject @Inject
protected EC2TemplateBuilderImpl(Supplier<Set<? extends Location>> locations, Supplier<Set<? extends Image>> images, protected EC2TemplateBuilderImpl(Supplier<Set<? extends Location>> locations, Supplier<Set<? extends Image>> images,
Supplier<Set<? extends Size>> sizes, Supplier<Location> defaultLocation, Supplier<Set<? extends Hardware>> sizes, Supplier<Location> defaultLocation,
Provider<TemplateOptions> optionsProvider, Provider<TemplateOptions> optionsProvider,
@Named("DEFAULT") Provider<TemplateBuilder> defaultTemplateProvider, @Named("DEFAULT") Provider<TemplateBuilder> defaultTemplateProvider,
ConcurrentMap<RegionAndName, Image> imageMap) { ConcurrentMap<RegionAndName, Image> imageMap) {
@ -91,6 +92,8 @@ public class EC2TemplateBuilderImpl extends TemplateBuilderImpl {
return imageMap.get(key); return imageMap.get(key);
} catch (NullPointerException nex) { } catch (NullPointerException nex) {
throw new NoSuchElementException(String.format("image %s/%s not found", key.getRegion(), key.getName())); throw new NoSuchElementException(String.format("image %s/%s not found", key.getRegion(), key.getName()));
} catch (ComputationException nex) {
throw new NoSuchElementException(String.format("image %s/%s not found", key.getRegion(), key.getName()));
} }
} }
return null; return null;
@ -103,7 +106,7 @@ public class EC2TemplateBuilderImpl extends TemplateBuilderImpl {
* if the image is not found * if the image is not found
*/ */
@Override @Override
protected Image resolveImage(Size size, Iterable<? extends Image> supportedImages) { protected Image resolveImage(Hardware size, Iterable<? extends Image> supportedImages) {
try { try {
return super.resolveImage(size, supportedImages); return super.resolveImage(size, supportedImages);
} catch (NoSuchElementException e) { } catch (NoSuchElementException e) {

View File

@ -30,7 +30,7 @@ import javax.inject.Inject;
import javax.inject.Named; import javax.inject.Named;
import javax.inject.Singleton; import javax.inject.Singleton;
import org.jclouds.aws.ec2.compute.domain.EC2Size; import org.jclouds.aws.ec2.compute.domain.EC2Hardware;
import org.jclouds.aws.ec2.compute.domain.RegionAndName; import org.jclouds.aws.ec2.compute.domain.RegionAndName;
import org.jclouds.aws.ec2.compute.domain.RegionNameAndIngressRules; import org.jclouds.aws.ec2.compute.domain.RegionNameAndIngressRules;
import org.jclouds.aws.ec2.compute.functions.CreatePlacementGroupIfNeeded; import org.jclouds.aws.ec2.compute.functions.CreatePlacementGroupIfNeeded;
@ -79,9 +79,9 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions
} }
public RunInstancesOptions execute(String region, String tag, Template template) { public RunInstancesOptions execute(String region, String tag, Template template) {
checkArgument(template.getSize() instanceof EC2Size, "unexpected image type. should be EC2Size, was: " checkArgument(template.getHardware() instanceof EC2Hardware, "unexpected image type. should be EC2Size, was: "
+ template.getSize().getClass()); + template.getHardware().getClass());
EC2Size ec2Size = EC2Size.class.cast(template.getSize()); EC2Hardware ec2Size = EC2Hardware.class.cast(template.getHardware());
RunInstancesOptions instanceOptions = asType(ec2Size.getInstanceType()).withAdditionalInfo(tag); RunInstancesOptions instanceOptions = asType(ec2Size.getInstanceType()).withAdditionalInfo(tag);

View File

@ -20,7 +20,6 @@
package org.jclouds.aws.ec2.compute.strategy; package org.jclouds.aws.ec2.compute.strategy;
import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import javax.inject.Singleton; import javax.inject.Singleton;
@ -37,18 +36,18 @@ public class EC2PopulateDefaultLoginCredentialsForImageStrategy implements
@Override @Override
public Credentials execute(Object resourceToAuthenticate) { public Credentials execute(Object resourceToAuthenticate) {
checkNotNull(resourceToAuthenticate); Credentials credentials = new Credentials("root", null);
if (resourceToAuthenticate != null) {
checkArgument(resourceToAuthenticate instanceof Image, "Resource must be an image (for EC2)"); checkArgument(resourceToAuthenticate instanceof Image, "Resource must be an image (for EC2)");
Image image = (Image) resourceToAuthenticate; Image image = (Image) resourceToAuthenticate;
Credentials credentials;
// canonical/alestic images use the ubuntu user to login // canonical/alestic images use the ubuntu user to login
if (image.getImageOwnerId().matches("063491364108|099720109477")) if (image.getImageOwnerId().matches("063491364108|099720109477")) {
credentials = new Credentials("ubuntu", null); credentials = new Credentials("ubuntu", null);
else // http://aws.typepad.com/aws/2010/09/introducing-amazon-linux-ami.html
credentials = new Credentials("root", null); } else if (image.getImageOwnerId().equals("137112412989")) {
credentials = new Credentials("ec2-user", null);
}
}
return credentials; return credentials;
} }
} }

View File

@ -30,16 +30,20 @@ import javax.inject.Inject;
import javax.inject.Named; import javax.inject.Named;
import javax.inject.Singleton; import javax.inject.Singleton;
import org.jclouds.aws.ec2.compute.domain.EC2Size; import org.jclouds.aws.ec2.compute.domain.EC2Hardware;
import org.jclouds.aws.ec2.domain.InstanceType; import org.jclouds.aws.ec2.domain.InstanceType;
import org.jclouds.compute.domain.Size; import org.jclouds.compute.domain.Hardware;
import org.jclouds.compute.domain.Processor;
import org.jclouds.compute.domain.internal.VolumeImpl;
import org.jclouds.compute.reference.ComputeServiceConstants; import org.jclouds.compute.reference.ComputeServiceConstants;
import org.jclouds.domain.Location; import org.jclouds.domain.Location;
import org.jclouds.domain.LocationScope; import org.jclouds.domain.LocationScope;
import org.jclouds.logging.Logger; import org.jclouds.logging.Logger;
import org.jclouds.rest.annotations.Provider;
import com.google.common.base.Predicate; import com.google.common.base.Predicate;
import com.google.common.base.Supplier; import com.google.common.base.Supplier;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
/** /**
@ -47,22 +51,25 @@ import com.google.common.collect.ImmutableSet;
* @author Adrian Cole * @author Adrian Cole
*/ */
@Singleton @Singleton
public class EC2SizeSupplier implements Supplier<Set<? extends Size>> { public class EC2HardwareSupplier implements Supplier<Set<? extends Hardware>> {
@Resource @Resource
@Named(ComputeServiceConstants.COMPUTE_LOGGER) @Named(ComputeServiceConstants.COMPUTE_LOGGER)
protected Logger logger = Logger.NULL; protected Logger logger = Logger.NULL;
private final Supplier<Set<? extends Location>> locations; private final Supplier<Set<? extends Location>> locations;
private final String[] ccAmis; private final String[] ccAmis;
private final String providerName;
@Inject @Inject
EC2SizeSupplier(Supplier<Set<? extends Location>> locations, @Named(PROPERTY_EC2_CC_AMIs) String[] ccAmis) { EC2HardwareSupplier(Supplier<Set<? extends Location>> locations, @Provider String providerName,
@Named(PROPERTY_EC2_CC_AMIs) String[] ccAmis) {
this.locations = locations; this.locations = locations;
this.ccAmis = ccAmis; this.ccAmis = ccAmis;
this.providerName = providerName;
} }
@Override @Override
public Set<? extends Size> get() { public Set<? extends Hardware> get() {
Set<Size> sizes = newHashSet(); Set<Hardware> sizes = newHashSet();
for (String ccAmi : ccAmis) { for (String ccAmi : ccAmis) {
final String region = ccAmi.split("/")[0]; final String region = ccAmi.split("/")[0];
Location location = find(locations.get(), new Predicate<Location>() { Location location = find(locations.get(), new Predicate<Location>() {
@ -73,10 +80,14 @@ public class EC2SizeSupplier implements Supplier<Set<? extends Size>> {
} }
}); });
sizes.add(new EC2Size(location, InstanceType.CC1_4XLARGE, 33.5, 23 * 1024, 1690, ccAmis)); sizes.add(new EC2Hardware(location, InstanceType.CC1_4XLARGE, ImmutableList.of(new Processor(4.0, 4.0),
new Processor(4.0, 4.0)), 23 * 1024, ImmutableList.of(
new VolumeImpl(10.0f, "/dev/sda1", true, false), new VolumeImpl(840.0f, "/dev/sdb", false, false),
new VolumeImpl(840.0f, "/dev/sdc", false, false)), ccAmis));
} }
sizes.addAll(ImmutableSet.<Size> of(EC2Size.C1_MEDIUM, EC2Size.C1_XLARGE, EC2Size.M1_LARGE, EC2Size.M1_SMALL, sizes.addAll(ImmutableSet.<Hardware> of(EC2Hardware.T1_MICRO, EC2Hardware.C1_MEDIUM, EC2Hardware.C1_XLARGE,
EC2Size.M1_XLARGE, EC2Size.M2_XLARGE, EC2Size.M2_2XLARGE, EC2Size.M2_4XLARGE)); EC2Hardware.M1_LARGE, "nova".equals(providerName) ? EC2Hardware.M1_SMALL_NOVA : EC2Hardware.M1_SMALL,
EC2Hardware.M1_XLARGE, EC2Hardware.M2_XLARGE, EC2Hardware.M2_2XLARGE, EC2Hardware.M2_4XLARGE));
return sizes; return sizes;
} }
} }

View File

@ -32,6 +32,16 @@ import org.jclouds.aws.ec2.EC2AsyncClient;
* *
*/ */
public class InstanceType { public class InstanceType {
/**
* Micro Instance
* <ul>
* <li>613 MB of memory</li>
* <li>up to 2 ECUs (for short periodic bursts)</li>
* <li>No instance storage (EBS storage only)</li>
* <li>32-bit or 64-bit platform</li>
* </ul>
*/
public static final String T1_MICRO = "t1.micro";
/** /**
* Small Instance * Small Instance
* <ul> * <ul>

View File

@ -37,6 +37,10 @@ public enum RootDeviceType {
return CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.LOWER_HYPHEN, name()); return CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.LOWER_HYPHEN, name());
} }
public String toString() {
return value();
}
public static RootDeviceType fromValue(String v) { public static RootDeviceType fromValue(String v) {
return valueOf(CaseFormat.LOWER_HYPHEN.to(CaseFormat.UPPER_UNDERSCORE, v)); return valueOf(CaseFormat.LOWER_HYPHEN.to(CaseFormat.UPPER_UNDERSCORE, v));
} }

View File

@ -152,6 +152,8 @@ public class RunningInstance implements Comparable<RunningInstance> {
@Nullable @Nullable
private final String subnetId; private final String subnetId;
@Nullable @Nullable
private final String spotInstanceRequestId;
@Nullable
private final String vpcId; private final String vpcId;
private final RootDeviceType rootDeviceType; private final RootDeviceType rootDeviceType;
@Nullable @Nullable
@ -168,8 +170,9 @@ public class RunningInstance implements Comparable<RunningInstance> {
Date launchTime, MonitoringState monitoringState, String availabilityZone, @Nullable String placementGroup, Date launchTime, MonitoringState monitoringState, String availabilityZone, @Nullable String placementGroup,
String virtualizationType, @Nullable String platform, @Nullable String privateDnsName, String virtualizationType, @Nullable String platform, @Nullable String privateDnsName,
@Nullable String privateIpAddress, Set<String> productCodes, @Nullable String ramdiskId, @Nullable String privateIpAddress, Set<String> productCodes, @Nullable String ramdiskId,
@Nullable String reason, @Nullable String subnetId, @Nullable String vpcId, RootDeviceType rootDeviceType, @Nullable String reason, @Nullable String subnetId, @Nullable String spotInstanceRequestId,
@Nullable String rootDeviceName, Map<String, EbsBlockDevice> ebsBlockDevices) { @Nullable String vpcId, RootDeviceType rootDeviceType, @Nullable String rootDeviceName,
Map<String, EbsBlockDevice> ebsBlockDevices) {
Iterables.addAll(this.groupIds, checkNotNull(groupIds, "groupIds")); Iterables.addAll(this.groupIds, checkNotNull(groupIds, "groupIds"));
this.region = checkNotNull(region, "region"); this.region = checkNotNull(region, "region");
this.amiLaunchIndex = amiLaunchIndex; // nullable on runinstances. this.amiLaunchIndex = amiLaunchIndex; // nullable on runinstances.
@ -183,16 +186,17 @@ public class RunningInstance implements Comparable<RunningInstance> {
this.keyName = keyName; this.keyName = keyName;
this.launchTime = checkNotNull(launchTime, "launchTime"); this.launchTime = checkNotNull(launchTime, "launchTime");
this.monitoringState = monitoringState; this.monitoringState = monitoringState;
this.availabilityZone = checkNotNull(availabilityZone, "availabilityZone"); this.availabilityZone = availabilityZone; // nullable on Nova.
this.placementGroup = placementGroup; this.placementGroup = placementGroup;
this.virtualizationType = virtualizationType; this.virtualizationType = virtualizationType;
this.platform = platform; this.platform = platform;
this.privateDnsName = privateDnsName; // nullable on runinstances. this.privateDnsName = privateDnsName; // nullable on Nova.
this.privateIpAddress = privateIpAddress; this.privateIpAddress = privateIpAddress;
Iterables.addAll(this.productCodes, checkNotNull(productCodes, "productCodes")); Iterables.addAll(this.productCodes, checkNotNull(productCodes, "productCodes"));
this.ramdiskId = ramdiskId; this.ramdiskId = ramdiskId;
this.reason = reason; this.reason = reason;
this.subnetId = subnetId; this.subnetId = subnetId;
this.spotInstanceRequestId = spotInstanceRequestId;
this.vpcId = vpcId; this.vpcId = vpcId;
this.rootDeviceType = checkNotNull(rootDeviceType, "rootDeviceType"); this.rootDeviceType = checkNotNull(rootDeviceType, "rootDeviceType");
this.rootDeviceName = rootDeviceName; this.rootDeviceName = rootDeviceName;
@ -352,6 +356,13 @@ public class RunningInstance implements Comparable<RunningInstance> {
return reason; return reason;
} }
/**
* The ID of the Spot Instance request
*/
public String getSpotInstanceRequestId() {
return spotInstanceRequestId;
}
/** /**
* Specifies the subnet ID in which the instance is running (Amazon Virtual Private Cloud). * Specifies the subnet ID in which the instance is running (Amazon Virtual Private Cloud).
*/ */
@ -394,20 +405,18 @@ public class RunningInstance implements Comparable<RunningInstance> {
int result = 1; int result = 1;
result = prime * result + ((amiLaunchIndex == null) ? 0 : amiLaunchIndex.hashCode()); result = prime * result + ((amiLaunchIndex == null) ? 0 : amiLaunchIndex.hashCode());
result = prime * result + ((availabilityZone == null) ? 0 : availabilityZone.hashCode()); result = prime * result + ((availabilityZone == null) ? 0 : availabilityZone.hashCode());
result = prime * result + ((placementGroup == null) ? 0 : placementGroup.hashCode());
result = prime * result + ((virtualizationType == null) ? 0 : virtualizationType.hashCode());
result = prime * result + ((dnsName == null) ? 0 : dnsName.hashCode()); result = prime * result + ((dnsName == null) ? 0 : dnsName.hashCode());
result = prime * result + ((ebsBlockDevices == null) ? 0 : ebsBlockDevices.hashCode()); result = prime * result + ((ebsBlockDevices == null) ? 0 : ebsBlockDevices.hashCode());
result = prime * result + ((groupIds == null) ? 0 : groupIds.hashCode()); result = prime * result + ((groupIds == null) ? 0 : groupIds.hashCode());
result = prime * result + ((imageId == null) ? 0 : imageId.hashCode()); result = prime * result + ((imageId == null) ? 0 : imageId.hashCode());
result = prime * result + ((instanceId == null) ? 0 : instanceId.hashCode()); result = prime * result + ((instanceId == null) ? 0 : instanceId.hashCode());
result = prime * result + ((instanceState == null) ? 0 : instanceState.hashCode());
result = prime * result + ((instanceType == null) ? 0 : instanceType.hashCode()); result = prime * result + ((instanceType == null) ? 0 : instanceType.hashCode());
result = prime * result + ((ipAddress == null) ? 0 : ipAddress.hashCode()); result = prime * result + ((ipAddress == null) ? 0 : ipAddress.hashCode());
result = prime * result + ((kernelId == null) ? 0 : kernelId.hashCode()); result = prime * result + ((kernelId == null) ? 0 : kernelId.hashCode());
result = prime * result + ((keyName == null) ? 0 : keyName.hashCode()); result = prime * result + ((keyName == null) ? 0 : keyName.hashCode());
result = prime * result + ((launchTime == null) ? 0 : launchTime.hashCode()); result = prime * result + ((launchTime == null) ? 0 : launchTime.hashCode());
result = prime * result + ((monitoringState == null) ? 0 : monitoringState.hashCode()); result = prime * result + ((monitoringState == null) ? 0 : monitoringState.hashCode());
result = prime * result + ((placementGroup == null) ? 0 : placementGroup.hashCode());
result = prime * result + ((platform == null) ? 0 : platform.hashCode()); result = prime * result + ((platform == null) ? 0 : platform.hashCode());
result = prime * result + ((privateDnsName == null) ? 0 : privateDnsName.hashCode()); result = prime * result + ((privateDnsName == null) ? 0 : privateDnsName.hashCode());
result = prime * result + ((privateIpAddress == null) ? 0 : privateIpAddress.hashCode()); result = prime * result + ((privateIpAddress == null) ? 0 : privateIpAddress.hashCode());
@ -415,7 +424,11 @@ public class RunningInstance implements Comparable<RunningInstance> {
result = prime * result + ((ramdiskId == null) ? 0 : ramdiskId.hashCode()); result = prime * result + ((ramdiskId == null) ? 0 : ramdiskId.hashCode());
result = prime * result + ((reason == null) ? 0 : reason.hashCode()); result = prime * result + ((reason == null) ? 0 : reason.hashCode());
result = prime * result + ((region == null) ? 0 : region.hashCode()); result = prime * result + ((region == null) ? 0 : region.hashCode());
result = prime * result + ((rootDeviceName == null) ? 0 : rootDeviceName.hashCode());
result = prime * result + ((rootDeviceType == null) ? 0 : rootDeviceType.hashCode());
result = prime * result + ((spotInstanceRequestId == null) ? 0 : spotInstanceRequestId.hashCode());
result = prime * result + ((subnetId == null) ? 0 : subnetId.hashCode()); result = prime * result + ((subnetId == null) ? 0 : subnetId.hashCode());
result = prime * result + ((virtualizationType == null) ? 0 : virtualizationType.hashCode());
result = prime * result + ((vpcId == null) ? 0 : vpcId.hashCode()); result = prime * result + ((vpcId == null) ? 0 : vpcId.hashCode());
return result; return result;
} }
@ -439,16 +452,6 @@ public class RunningInstance implements Comparable<RunningInstance> {
return false; return false;
} else if (!availabilityZone.equals(other.availabilityZone)) } else if (!availabilityZone.equals(other.availabilityZone))
return false; return false;
if (placementGroup == null) {
if (other.placementGroup != null)
return false;
} else if (!placementGroup.equals(other.placementGroup))
return false;
if (virtualizationType == null) {
if (other.virtualizationType != null)
return false;
} else if (!virtualizationType.equals(other.virtualizationType))
return false;
if (dnsName == null) { if (dnsName == null) {
if (other.dnsName != null) if (other.dnsName != null)
return false; return false;
@ -474,11 +477,6 @@ public class RunningInstance implements Comparable<RunningInstance> {
return false; return false;
} else if (!instanceId.equals(other.instanceId)) } else if (!instanceId.equals(other.instanceId))
return false; return false;
if (instanceState == null) {
if (other.instanceState != null)
return false;
} else if (!instanceState.equals(other.instanceState))
return false;
if (instanceType == null) { if (instanceType == null) {
if (other.instanceType != null) if (other.instanceType != null)
return false; return false;
@ -509,6 +507,11 @@ public class RunningInstance implements Comparable<RunningInstance> {
return false; return false;
} else if (!monitoringState.equals(other.monitoringState)) } else if (!monitoringState.equals(other.monitoringState))
return false; return false;
if (placementGroup == null) {
if (other.placementGroup != null)
return false;
} else if (!placementGroup.equals(other.placementGroup))
return false;
if (platform == null) { if (platform == null) {
if (other.platform != null) if (other.platform != null)
return false; return false;
@ -544,11 +547,31 @@ public class RunningInstance implements Comparable<RunningInstance> {
return false; return false;
} else if (!region.equals(other.region)) } else if (!region.equals(other.region))
return false; return false;
if (rootDeviceName == null) {
if (other.rootDeviceName != null)
return false;
} else if (!rootDeviceName.equals(other.rootDeviceName))
return false;
if (rootDeviceType == null) {
if (other.rootDeviceType != null)
return false;
} else if (!rootDeviceType.equals(other.rootDeviceType))
return false;
if (spotInstanceRequestId == null) {
if (other.spotInstanceRequestId != null)
return false;
} else if (!spotInstanceRequestId.equals(other.spotInstanceRequestId))
return false;
if (subnetId == null) { if (subnetId == null) {
if (other.subnetId != null) if (other.subnetId != null)
return false; return false;
} else if (!subnetId.equals(other.subnetId)) } else if (!subnetId.equals(other.subnetId))
return false; return false;
if (virtualizationType == null) {
if (other.virtualizationType != null)
return false;
} else if (!virtualizationType.equals(other.virtualizationType))
return false;
if (vpcId == null) { if (vpcId == null) {
if (other.vpcId != null) if (other.vpcId != null)
return false; return false;
@ -567,8 +590,8 @@ public class RunningInstance implements Comparable<RunningInstance> {
+ launchTime + ", monitoringState=" + monitoringState + ", platform=" + platform + ", privateDnsName=" + launchTime + ", monitoringState=" + monitoringState + ", platform=" + platform + ", privateDnsName="
+ privateDnsName + ", privateIpAddress=" + privateIpAddress + ", productCodes=" + productCodes + privateDnsName + ", privateIpAddress=" + privateIpAddress + ", productCodes=" + productCodes
+ ", ramdiskId=" + ramdiskId + ", reason=" + reason + ", region=" + region + ", rootDeviceName=" + ", ramdiskId=" + ramdiskId + ", reason=" + reason + ", region=" + region + ", rootDeviceName="
+ rootDeviceName + ", rootDeviceType=" + rootDeviceType + ", subnetId=" + subnetId + ", vpcId=" + vpcId + rootDeviceName + ", rootDeviceType=" + rootDeviceType + ", spotInstanceRequestId="
+ "]"; + spotInstanceRequestId + ", subnetId=" + subnetId + ", vpcId=" + vpcId + "]";
} }
} }

View File

@ -1,180 +0,0 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.aws.ec2.functions;
import com.google.common.base.Function;
import com.google.common.collect.Maps;
import org.jclouds.aws.ec2.domain.InstanceType;
import org.jclouds.aws.ec2.domain.RunningInstance;
import java.util.Map;
import static org.jclouds.compute.reference.ComputeServiceConstants.LOCAL_PARTITION_GB_PATTERN;
/**
* Map the instance to storage information known about it. This information is statically set as
* described by Amazon.
*
* Note that having the partitions available doesn't mean they're formatted/mounted by default. The
* links below describe what partitions are formatted initially. To format/mount an available
* device, refer to <a href="http://meinit.nl/howto-use-amazon-elastic-compute-cloud-ec2">this
* article</a>.
*
* @see <a href="http://docs.amazonwebservices.com/AWSEC2/2010-06-15/UserGuide/index.html?instance-storage-concepts.html"
* />
* @see <a
* href="http://docs.amazonwebservices.com/AWSEC2/latest/UserGuide/index.html?instance-types.html"
* />
*
* @author Oleksiy Yarmula
*/
public class RunningInstanceToStorageMappingUnix implements Function<RunningInstance, Map<String, String>> {
public final static String ROOT_PARTITION_NAME_UNIX = "/dev/sda1";
@Override
public Map<String, String> apply(RunningInstance instance) {
final String instanceType = instance.getInstanceType();
Map<String, String> mapping = Maps.newHashMap();
// root partition
mapping.put(String.format(LOCAL_PARTITION_GB_PATTERN, ROOT_PARTITION_NAME_UNIX),
getRootPartitionSizeForInstanceType(instanceType) + "");
// primary partition (always formatted/mounted)
mapping.put(String.format(LOCAL_PARTITION_GB_PATTERN, getPrimaryPartitionDeviceName(instanceType)),
getPrimaryPartitionSizeForInstanceType(instanceType) + "");
// additional partitions if any
for (Map.Entry<String, Integer> entry : getAdditionalPartitionsMapping(instanceType).entrySet()) {
mapping.put(String.format(LOCAL_PARTITION_GB_PATTERN, entry.getKey()), entry.getValue() + "");
}
return mapping;
}
/**
* Retrieve the root partition size. Note, this is usually a rather small partition. Refer to
* {@link #getPrimaryPartitionSizeForInstanceType} to determine the size of the primary (usually,
* biggest) partition. In some cases, for large instances there are several partitions of the
* size of primary partition.
*
* @param instanceType
* for which the root partition size is to be determined
* @return size in GB
*
* @see <a href="http://docs.amazonwebservices.com/AWSEC2/2010-06-15/UserGuide/index.html?instance-storage-concepts.html"
* />
* @see <a href=
* "http://docs.amazonwebservices.com/AWSEC2/latest/UserGuide/index.html?instance-types.html"
* />
*/
public int getRootPartitionSizeForInstanceType(String instanceType) {
/*
* per documentation at
* http://docs.amazonwebservices.com/AWSEC2/latest/UserGuide/index.html?instance-types.html M2
* XLARGE doesn't have the root partition TODO verify
*/
if (InstanceType.M2_XLARGE.equals(instanceType))
return 0;
// other types have 10 GB root partition
return 10;
}
public static String getPrimaryPartitionDeviceName(String instanceType) {
if (InstanceType.M1_SMALL.equals(instanceType) || InstanceType.C1_MEDIUM.equals(instanceType))
return "/dev/sda2";
return "/dev/sdb";
}
/**
* Retrieve the primary partition size.
*
* This is usually the biggest partition. In some cases, for large instances there are several
* partitions of the size of primary partition.
*
* @param instanceType
* for which the primary partition size is to be determined
* @return size in GB
*/
public static int getPrimaryPartitionSizeForInstanceType(String instanceType) {
if (InstanceType.M1_SMALL.equals(instanceType)) {
return 150;
} else if (InstanceType.C1_MEDIUM.equals(instanceType)) {
return 340;
} else if (InstanceType.M1_LARGE.equals(instanceType)) {
return 420;
} else if (InstanceType.M1_XLARGE.equals(instanceType)) {
return 420;
} else if (InstanceType.C1_XLARGE.equals(instanceType)) {
return 420;
} else if (InstanceType.M2_XLARGE.equals(instanceType)) {
return 420;
} else if (InstanceType.M2_2XLARGE.equals(instanceType)) {
return 840;
} else if (InstanceType.M2_4XLARGE.equals(instanceType)) {
return 840;
} else if (InstanceType.CC1_4XLARGE.equals(instanceType))
return 840;
return 150;// TODO make this more graceful
}
/**
* Retrieve additional devices mapping (non-root and non-primary) for the instance type.
*
* @param instanceType
* @return map with device name(s) and size(s) or empty map if the instance doesn't have any
* additional
*
* @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/UserGuide/index.html?concepts-amis-and-instances.html#instance-types"
* />
*/
public static Map<String, Integer> getAdditionalPartitionsMapping(String instanceType) {
Map<String, Integer> mapping = Maps.newHashMap();
int size = 0;
if (InstanceType.M1_LARGE.equals(instanceType) || InstanceType.M1_XLARGE.equals(instanceType)
|| InstanceType.C1_XLARGE.equals(instanceType)) {
size = 420;
} else if (InstanceType.M2_4XLARGE.equals(instanceType) || instanceType.startsWith("cc")) {
size = 840;
}
// m1.large, m1.xlarge, and c1.xlarge
if (InstanceType.M1_LARGE.equals(instanceType) || InstanceType.M1_XLARGE.equals(instanceType)
|| InstanceType.C1_XLARGE.equals(instanceType) || InstanceType.M2_4XLARGE.equals(instanceType)
|| instanceType.startsWith("cc")) {
mapping.put("/dev/sdc", size);
}
if (InstanceType.M1_XLARGE.equals(instanceType) || InstanceType.C1_XLARGE.equals(instanceType)) {
mapping.put("/dev/sdd", size);
}
if (InstanceType.M1_XLARGE.equals(instanceType) || InstanceType.C1_XLARGE.equals(instanceType)) {
mapping.put("/dev/sde", size);
}
return mapping;
}
}

View File

@ -37,7 +37,7 @@ import org.jclouds.concurrent.Timeout;
* *
* @author Adrian Cole * @author Adrian Cole
*/ */
@Timeout(duration = 45, timeUnit = TimeUnit.SECONDS) @Timeout(duration = 60, timeUnit = TimeUnit.SECONDS)
public interface AvailabilityZoneAndRegionClient { public interface AvailabilityZoneAndRegionClient {
/** /**

View File

@ -86,6 +86,7 @@ public abstract class BaseReservationHandler<T> extends HandlerForGeneratedReque
private Set<String> productCodes = Sets.newHashSet(); private Set<String> productCodes = Sets.newHashSet();
private String ramdiskId; private String ramdiskId;
private String reason; private String reason;
private String spotInstanceRequestId;
private String subnetId; private String subnetId;
private String vpcId; private String vpcId;
protected boolean inInstances; protected boolean inInstances;
@ -144,7 +145,14 @@ public abstract class BaseReservationHandler<T> extends HandlerForGeneratedReque
} else if (qName.equals("instanceId")) { } else if (qName.equals("instanceId")) {
instanceId = currentOrNull(); instanceId = currentOrNull();
} else if (qName.equals("name")) { } else if (qName.equals("name")) {
instanceState = InstanceState.fromValue(currentOrNull()); String state = currentOrNull();
if (state != null) {
// Nova
if ("shutdown".equalsIgnoreCase(state))
instanceState = InstanceState.TERMINATED;
else
instanceState = InstanceState.fromValue(state);
}
} else if (qName.equals("instanceType")) { } else if (qName.equals("instanceType")) {
instanceType = currentOrNull(); instanceType = currentOrNull();
} else if (qName.equals("ipAddress")) { } else if (qName.equals("ipAddress")) {
@ -183,6 +191,8 @@ public abstract class BaseReservationHandler<T> extends HandlerForGeneratedReque
reason = currentOrNull(); reason = currentOrNull();
} else if (qName.equals("subnetId")) { } else if (qName.equals("subnetId")) {
subnetId = currentOrNull(); subnetId = currentOrNull();
} else if (qName.equals("spotInstanceRequestId")) {
spotInstanceRequestId = currentOrNull();
} else if (qName.equals("vpcId")) { } else if (qName.equals("vpcId")) {
vpcId = currentOrNull(); vpcId = currentOrNull();
} else if (qName.equals("productCode")) { } else if (qName.equals("productCode")) {
@ -244,7 +254,8 @@ public abstract class BaseReservationHandler<T> extends HandlerForGeneratedReque
instances.add(new RunningInstance(region, groupIds, amiLaunchIndex, dnsName, imageId, instanceId, instances.add(new RunningInstance(region, groupIds, amiLaunchIndex, dnsName, imageId, instanceId,
instanceState, instanceType, ipAddress, kernelId, keyName, launchTime, monitoringState, instanceState, instanceType, ipAddress, kernelId, keyName, launchTime, monitoringState,
availabilityZone, placementGroup, virtualizationType, platform, privateDnsName, privateIpAddress, availabilityZone, placementGroup, virtualizationType, platform, privateDnsName, privateIpAddress,
productCodes, ramdiskId, reason, subnetId, vpcId, rootDeviceType, rootDeviceName, ebsBlockDevices)); productCodes, ramdiskId, reason, subnetId, spotInstanceRequestId, vpcId, rootDeviceType,
rootDeviceName, ebsBlockDevices));
this.amiLaunchIndex = null; this.amiLaunchIndex = null;
this.dnsName = null; this.dnsName = null;
this.imageId = null; this.imageId = null;
@ -266,6 +277,7 @@ public abstract class BaseReservationHandler<T> extends HandlerForGeneratedReque
this.ramdiskId = null; this.ramdiskId = null;
this.reason = null; this.reason = null;
this.subnetId = null; this.subnetId = null;
this.spotInstanceRequestId = null;
this.vpcId = null; this.vpcId = null;
this.rootDeviceType = RootDeviceType.INSTANCE_STORE; this.rootDeviceType = RootDeviceType.INSTANCE_STORE;
this.rootDeviceName = null; this.rootDeviceName = null;

View File

@ -121,7 +121,8 @@ public class DescribeImagesResponseHandler extends ParseSax.HandlerForGeneratedR
imageOwnerId = currentText.toString().trim(); imageOwnerId = currentText.toString().trim();
} else if (qName.equals("imageState")) { } else if (qName.equals("imageState")) {
imageState = ImageState.fromValue(currentText.toString().trim()); imageState = ImageState.fromValue(currentText.toString().trim());
} else if (qName.equals("imageType")) { // eucalyptus
} else if (qName.equals("imageType") || qName.equals("type")) {
imageType = ImageType.fromValue(currentText.toString().trim()); imageType = ImageType.fromValue(currentText.toString().trim());
} else if (qName.equals("isPublic")) { } else if (qName.equals("isPublic")) {
isPublic = Boolean.parseBoolean(currentText.toString().trim()); isPublic = Boolean.parseBoolean(currentText.toString().trim());

View File

@ -33,8 +33,7 @@ import com.google.common.collect.Maps;
* *
* @author Adrian Cole * @author Adrian Cole
*/ */
public class DescribeRegionsResponseHandler extends public class DescribeRegionsResponseHandler extends ParseSax.HandlerWithResult<Map<String, URI>> {
ParseSax.HandlerWithResult<Map<String, URI>> {
private StringBuilder currentText = new StringBuilder(); private StringBuilder currentText = new StringBuilder();
private Map<String, URI> regionEndpoints = Maps.newHashMap(); private Map<String, URI> regionEndpoints = Maps.newHashMap();
@ -52,11 +51,11 @@ public class DescribeRegionsResponseHandler extends
String pending = currentText.toString().trim(); String pending = currentText.toString().trim();
if (pending.indexOf("Walrus") == -1) if (pending.indexOf("Walrus") == -1)
region = pending; region = pending;
} else if (qName.equals("regionEndpoint")) { // Nova uses regionUrl
} else if (qName.equals("regionEndpoint") || qName.equals("regionUrl")) {
String pending = currentText.toString().trim(); String pending = currentText.toString().trim();
if (pending.indexOf("Walrus") == -1) if (pending.indexOf("Walrus") == -1)
regionEndpoint = URI.create(pending.startsWith("http") ? pending regionEndpoint = URI.create(pending.startsWith("http") ? pending : String.format("https://%s", pending));
: String.format("https://%s", pending));
} else if (qName.equals("item") && region != null) { } else if (qName.equals("item") && region != null) {
regionEndpoints.put(region, regionEndpoint); regionEndpoints.put(region, regionEndpoint);
this.region = null; this.region = null;

View File

@ -21,6 +21,8 @@ package org.jclouds.aws.handlers;
import static org.jclouds.http.HttpUtils.releasePayload; import static org.jclouds.http.HttpUtils.releasePayload;
import java.io.IOException;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Singleton; import javax.inject.Singleton;
@ -38,6 +40,7 @@ import org.jclouds.http.HttpResponseException;
import org.jclouds.logging.Logger; import org.jclouds.logging.Logger;
import org.jclouds.rest.AuthorizationException; import org.jclouds.rest.AuthorizationException;
import org.jclouds.rest.ResourceNotFoundException; import org.jclouds.rest.ResourceNotFoundException;
import org.jclouds.util.Utils;
import com.google.common.annotations.VisibleForTesting; import com.google.common.annotations.VisibleForTesting;
@ -65,33 +68,52 @@ public class ParseAWSErrorFromXmlContent implements HttpErrorHandler {
HttpRequest request = command.getRequest(); HttpRequest request = command.getRequest();
Exception exception = new HttpResponseException(command, response); Exception exception = new HttpResponseException(command, response);
try { try {
AWSError error = utils.parseAWSErrorFromContent(request, response); AWSError error = null;
exception = error != null ? new AWSResponseException(command, response, error) : exception; String message = null;
String notFoundMessage = error != null ? error.getMessage() : String.format("%s -> %s", request if (response.getPayload() != null) {
.getRequestLine(), response.getStatusLine()); if (response.getPayload().getContentType() != null
&& (response.getPayload().getContentType().indexOf("xml") != -1 || response.getPayload()
.getContentType().indexOf("unknown") != -1)) {
error = utils.parseAWSErrorFromContent(request, response);
if (error != null) {
message = error.getMessage();
exception = new AWSResponseException(command, response, error);
}
} else {
try {
message = Utils.toStringAndClose(response.getPayload().getInput());
} catch (IOException e) {
}
}
}
message = message != null ? message : String.format("%s -> %s", request.getRequestLine(), response
.getStatusLine());
switch (response.getStatusCode()) { switch (response.getStatusCode()) {
case 400: case 400:
if (error != null && error.getCode().endsWith(".NotFound") || error.getCode().endsWith(".Unknown")) if (error != null && error.getCode() != null
exception = new ResourceNotFoundException(notFoundMessage, exception); && (error.getCode().endsWith(".NotFound") || error.getCode().endsWith(".Unknown")))
else if (error != null && error.getCode().equals("IncorrectState")) exception = new ResourceNotFoundException(message, exception);
exception = new IllegalStateException(error.getMessage(), exception); else if ((error != null && error.getCode() != null && (error.getCode().equals("IncorrectState") || error
else if (error != null && error.getCode().equals("AuthFailure")) .getCode().equals("InvalidGroup.Duplicate")))
exception = new AuthorizationException(command.getRequest(), error != null ? error.getMessage() || (message != null && message.indexOf("already exists") != -1))
: response.getStatusLine()); exception = new IllegalStateException(message, exception);
else if (error != null && error.getCode() != null && error.getCode().equals("AuthFailure"))
exception = new AuthorizationException(command.getRequest(), message);
else if (message != null && message.indexOf("Failed to bind the following fields") != -1)// Nova
exception = new IllegalArgumentException(message, exception);
break; break;
case 401: case 401:
case 403: case 403:
exception = new AuthorizationException(command.getRequest(), error != null ? error.getMessage() exception = new AuthorizationException(command.getRequest(), message);
: response.getStatusLine());
break; break;
case 404: case 404:
if (!command.getRequest().getMethod().equals("DELETE")) { if (!command.getRequest().getMethod().equals("DELETE")) {
String container = request.getEndpoint().getHost(); String container = request.getEndpoint().getHost();
String key = request.getEndpoint().getPath(); String key = request.getEndpoint().getPath();
if (key == null || key.equals("/")) if (key == null || key.equals("/"))
exception = new ContainerNotFoundException(container, notFoundMessage); exception = new ContainerNotFoundException(container, message);
else else
exception = new KeyNotFoundException(container, key, notFoundMessage); exception = new KeyNotFoundException(container, key, message);
} }
break; break;
} }

View File

@ -116,7 +116,7 @@ public interface S3AsyncClient {
* @see S3Client#getObject * @see S3Client#getObject
*/ */
@GET @GET
@Path("{key}") @Path("/{key}")
@ExceptionParser(ReturnNullOnKeyNotFound.class) @ExceptionParser(ReturnNullOnKeyNotFound.class)
@ResponseParser(ParseObjectFromHeadersAndHttpContent.class) @ResponseParser(ParseObjectFromHeadersAndHttpContent.class)
ListenableFuture<S3Object> getObject( ListenableFuture<S3Object> getObject(
@ -127,7 +127,7 @@ public interface S3AsyncClient {
* @see S3Client#headObject * @see S3Client#headObject
*/ */
@HEAD @HEAD
@Path("{key}") @Path("/{key}")
@ExceptionParser(ReturnNullOnKeyNotFound.class) @ExceptionParser(ReturnNullOnKeyNotFound.class)
@ResponseParser(ParseObjectMetadataFromHeaders.class) @ResponseParser(ParseObjectMetadataFromHeaders.class)
ListenableFuture<ObjectMetadata> headObject( ListenableFuture<ObjectMetadata> headObject(
@ -138,7 +138,7 @@ public interface S3AsyncClient {
* @see S3Client#objectExists * @see S3Client#objectExists
*/ */
@HEAD @HEAD
@Path("{key}") @Path("/{key}")
@ExceptionParser(ReturnFalseOnKeyNotFound.class) @ExceptionParser(ReturnFalseOnKeyNotFound.class)
ListenableFuture<Boolean> objectExists( ListenableFuture<Boolean> objectExists(
@Bucket @BinderParam(BindAsHostPrefixIfConfigured.class) @ParamValidators( { BucketNameValidator.class }) String bucketName, @Bucket @BinderParam(BindAsHostPrefixIfConfigured.class) @ParamValidators( { BucketNameValidator.class }) String bucketName,
@ -148,7 +148,7 @@ public interface S3AsyncClient {
* @see S3Client#deleteObject * @see S3Client#deleteObject
*/ */
@DELETE @DELETE
@Path("{key}") @Path("/{key}")
@ExceptionParser(ReturnVoidOnNotFoundOr404.class) @ExceptionParser(ReturnVoidOnNotFoundOr404.class)
ListenableFuture<Void> deleteObject( ListenableFuture<Void> deleteObject(
@Bucket @BinderParam(BindAsHostPrefixIfConfigured.class) @ParamValidators( { BucketNameValidator.class }) String bucketName, @Bucket @BinderParam(BindAsHostPrefixIfConfigured.class) @ParamValidators( { BucketNameValidator.class }) String bucketName,
@ -158,7 +158,7 @@ public interface S3AsyncClient {
* @see S3Client#putObject * @see S3Client#putObject
*/ */
@PUT @PUT
@Path("{key}") @Path("/{key}")
@ResponseParser(ParseETagHeader.class) @ResponseParser(ParseETagHeader.class)
ListenableFuture<String> putObject( ListenableFuture<String> putObject(
@Bucket @BinderParam(BindAsHostPrefixIfConfigured.class) @ParamValidators( { BucketNameValidator.class }) String bucketName, @Bucket @BinderParam(BindAsHostPrefixIfConfigured.class) @ParamValidators( { BucketNameValidator.class }) String bucketName,
@ -249,7 +249,7 @@ public interface S3AsyncClient {
* @see S3Client#copyObject * @see S3Client#copyObject
*/ */
@PUT @PUT
@Path("{destinationObject}") @Path("/{destinationObject}")
@Headers(keys = "x-amz-copy-source", values = "/{sourceBucket}/{sourceObject}") @Headers(keys = "x-amz-copy-source", values = "/{sourceBucket}/{sourceObject}")
@XMLResponseParser(CopyObjectHandler.class) @XMLResponseParser(CopyObjectHandler.class)
ListenableFuture<ObjectMetadata> copyObject( ListenableFuture<ObjectMetadata> copyObject(
@ -284,7 +284,7 @@ public interface S3AsyncClient {
*/ */
@GET @GET
@QueryParams(keys = "acl") @QueryParams(keys = "acl")
@Path("{key}") @Path("/{key}")
@XMLResponseParser(AccessControlListHandler.class) @XMLResponseParser(AccessControlListHandler.class)
@ExceptionParser(ThrowKeyNotFoundOn404.class) @ExceptionParser(ThrowKeyNotFoundOn404.class)
ListenableFuture<AccessControlList> getObjectACL( ListenableFuture<AccessControlList> getObjectACL(
@ -296,7 +296,7 @@ public interface S3AsyncClient {
*/ */
@PUT @PUT
@QueryParams(keys = "acl") @QueryParams(keys = "acl")
@Path("{key}") @Path("/{key}")
ListenableFuture<Boolean> putObjectACL( ListenableFuture<Boolean> putObjectACL(
@Bucket @BinderParam(BindAsHostPrefixIfConfigured.class) @ParamValidators( { BucketNameValidator.class }) String bucketName, @Bucket @BinderParam(BindAsHostPrefixIfConfigured.class) @ParamValidators( { BucketNameValidator.class }) String bucketName,
@PathParam("key") String key, @PathParam("key") String key,

View File

@ -0,0 +1,79 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.aws.s3.blobstore;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.jclouds.blobstore.util.BlobStoreUtils.cleanRequest;
import java.lang.reflect.Method;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.jclouds.aws.s3.S3AsyncClient;
import org.jclouds.aws.s3.blobstore.functions.BlobToObject;
import org.jclouds.aws.s3.domain.S3Object;
import org.jclouds.aws.s3.options.PutObjectOptions;
import org.jclouds.blobstore.BlobRequestSigner;
import org.jclouds.blobstore.domain.Blob;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.options.GetOptions;
import org.jclouds.rest.internal.RestAnnotationProcessor;
/**
*
* @author Adrian Cole
*/
@Singleton
public class S3BlobRequestSigner implements BlobRequestSigner {
private final RestAnnotationProcessor<S3AsyncClient> processor;
private final BlobToObject blobToObject;
private final Method getMethod;
private final Method deleteMethod;
private final Method createMethod;
@Inject
public S3BlobRequestSigner(RestAnnotationProcessor<S3AsyncClient> processor, BlobToObject blobToObject)
throws SecurityException, NoSuchMethodException {
this.processor = checkNotNull(processor, "processor");
this.blobToObject = checkNotNull(blobToObject, "blobToObject");
this.getMethod = S3AsyncClient.class.getMethod("getObject", String.class, String.class, GetOptions[].class);
this.deleteMethod = S3AsyncClient.class.getMethod("deleteObject", String.class, String.class);
this.createMethod = S3AsyncClient.class.getMethod("putObject", String.class, S3Object.class,
PutObjectOptions[].class);
}
@Override
public HttpRequest signGetBlob(String container, String name) {
return cleanRequest(processor.createRequest(getMethod, container, name));
}
@Override
public HttpRequest signPutBlob(String container, Blob blob) {
return cleanRequest(processor.createRequest(createMethod, container, blobToObject.apply(blob)));
}
@Override
public HttpRequest signRemoveBlob(String container, String name) {
return cleanRequest(processor.createRequest(deleteMethod, container, name));
}
}

View File

@ -27,9 +27,11 @@ import org.jclouds.aws.Region;
import org.jclouds.aws.s3.S3AsyncClient; import org.jclouds.aws.s3.S3AsyncClient;
import org.jclouds.aws.s3.S3Client; import org.jclouds.aws.s3.S3Client;
import org.jclouds.aws.s3.blobstore.S3AsyncBlobStore; import org.jclouds.aws.s3.blobstore.S3AsyncBlobStore;
import org.jclouds.aws.s3.blobstore.S3BlobRequestSigner;
import org.jclouds.aws.s3.blobstore.S3BlobStore; import org.jclouds.aws.s3.blobstore.S3BlobStore;
import org.jclouds.aws.suppliers.DefaultLocationSupplier; import org.jclouds.aws.suppliers.DefaultLocationSupplier;
import org.jclouds.blobstore.AsyncBlobStore; import org.jclouds.blobstore.AsyncBlobStore;
import org.jclouds.blobstore.BlobRequestSigner;
import org.jclouds.blobstore.BlobStore; import org.jclouds.blobstore.BlobStore;
import org.jclouds.blobstore.BlobStoreContext; import org.jclouds.blobstore.BlobStoreContext;
import org.jclouds.blobstore.attr.ConsistencyModel; import org.jclouds.blobstore.attr.ConsistencyModel;
@ -66,6 +68,7 @@ public class S3BlobStoreContextModule extends AbstractModule {
bind(BlobStore.class).to(S3BlobStore.class).in(Scopes.SINGLETON); bind(BlobStore.class).to(S3BlobStore.class).in(Scopes.SINGLETON);
bind(BlobStoreContext.class).to(new TypeLiteral<BlobStoreContextImpl<S3Client, S3AsyncClient>>() { bind(BlobStoreContext.class).to(new TypeLiteral<BlobStoreContextImpl<S3Client, S3AsyncClient>>() {
}).in(Scopes.SINGLETON); }).in(Scopes.SINGLETON);
bind(BlobRequestSigner.class).to(S3BlobRequestSigner.class);
} }
@Provides @Provides

View File

@ -0,0 +1,110 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.aws;
import static org.jclouds.compute.BaseComputeServiceLiveTest.buildScript;
import static org.jclouds.compute.options.TemplateOptions.Builder.runScript;
import static org.jclouds.compute.util.ComputeServiceUtils.execHttpResponse;
import static org.jclouds.compute.util.ComputeServiceUtils.extractTargzIntoDirectory;
import static org.jclouds.scriptbuilder.domain.Statements.newStatementList;
import java.net.URI;
import org.jclouds.aws.ec2.compute.BlobStoreAndComputeServiceLiveTest;
import org.jclouds.blobstore.BlobStore;
import org.jclouds.compute.RunNodesException;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.OperatingSystem;
import org.jclouds.http.HttpRequest;
import org.jclouds.scriptbuilder.domain.Statement;
import org.testng.annotations.Test;
/**
* This test helps us understand how we can use the power of blobstores to our favor.
*
* @author Adrian Cole
*/
@Test(groups = "live", testName = "jclouds.ComputeAndBlobStoreTogetherHappilyLiveTest")
public class ComputeAndBlobStoreTogetherHappilyLiveTest extends BlobStoreAndComputeServiceLiveTest {
protected void setupCredentials() {
blobStoreProvider = "s3";
computeServiceProvider = "ec2";
super.setupCredentials();
}
/**
* This test generates a bootstrap script based on the default operating system of the compute
* provider.
* <p/>
* It then uploads this to a blobstore, in a private location. Now, we want the bootstrap of the
* server to be able to load from this location without sending credentials to the starting
* machine. Accordingly, we send a signed url instead.
* <p/>
* Using the {@link BlobStore} api, we get a signed url corresponding to the bootstrap script. We
* next convert this into something that can be invoked via the commandline. Looking around, it
* seems like alestic runurl is pretty close. However, it is limited as it only works on requests
* that can be fully specified without headers (ex. Amazon S3). Instead, we use a variant
* (execHttpResponse).
* <p/>
* execHttpResponse simply assembles an http request, headers and all, and passes it to bash
* <p/>
* With this script ready, any node or nodes will take instructions from the blobstore when it
* boots up. we verify this with an assertion.
*
*/
@Test
public void testWeCanIndirectBootstrapInstructionsToAnArbitraryAndPrivateBlobStore() throws RunNodesException {
OperatingSystem defaultOperatingSystem = computeContext.getComputeService().templateBuilder().build().getImage()
.getOperatingSystem();
// using jclouds ability to detect operating systems before we launch them, we can avoid
// the bad practice of assuming everything is ubuntu.
uploadBlob(tag, "openjdk/install", buildScript(defaultOperatingSystem));
// instead of hard-coding to amazon s3, we can use any blobstore, conceding this test is
// configured for amz. Note we are getting temporary access to a private blob.
HttpRequest signedRequestOfInstallScript = blobContext.getSigner().signGetBlob(tag, "openjdk/install");
// so one of our commands is to execute the contents of the blob above
Statement installOpenJDK = execHttpResponse(signedRequestOfInstallScript);
// if we want to, we can mix and match batched and ad-hoc commands, such as extracting maven
String mavenVersion = "3.0-beta-3";
Statement extractMavenIntoUsrLocal = extractTargzIntoDirectory(URI
.create("http://mirrors.ibiblio.org/pub/mirrors/apache//maven/binaries/apache-maven-" + mavenVersion
+ "-bin.tar.gz"), "/usr/local");
// have both of these commands occur on boot
Statement bootstrapInstructions = newStatementList(installOpenJDK, extractMavenIntoUsrLocal);
// now that we have the correct instructions, kick-off the provisioner
Iterable<? extends NodeMetadata> nodes = computeContext.getComputeService().runNodesWithTag(tag, 2,
runScript(bootstrapInstructions));
// ensure the bootstrap operated by checking for the components we installed at boot time.
// Note this test will ensure both nodes are in sync.
assertSshOutputOfCommandContains(nodes, "java -version", "OpenJDK");
assertSshOutputOfCommandContains(nodes, "/usr/local/apache-maven-" + mavenVersion + "/bin/mvn -version",
"Apache Maven " + mavenVersion + "");
}
}

View File

@ -43,6 +43,7 @@ public class ProvidersInPropertiesTest {
assert !Iterables.contains(providers, "walrus") : providers; assert !Iterables.contains(providers, "walrus") : providers;
assert !Iterables.contains(providers, "googlestorage") : providers; assert !Iterables.contains(providers, "googlestorage") : providers;
assert Iterables.contains(providers, "ec2") : providers; assert Iterables.contains(providers, "ec2") : providers;
assert Iterables.contains(providers, "nova") : providers;
assert Iterables.contains(providers, "eucalyptus") : providers; assert Iterables.contains(providers, "eucalyptus") : providers;
} }
@ -55,6 +56,7 @@ public class ProvidersInPropertiesTest {
assert Iterables.contains(providers, "walrus") : providers; assert Iterables.contains(providers, "walrus") : providers;
assert Iterables.contains(providers, "googlestorage") : providers; assert Iterables.contains(providers, "googlestorage") : providers;
assert Iterables.contains(providers, "ec2") : providers; assert Iterables.contains(providers, "ec2") : providers;
assert Iterables.contains(providers, "nova") : providers;
assert Iterables.contains(providers, "eucalyptus") : providers; assert Iterables.contains(providers, "eucalyptus") : providers;
} }
@ -67,6 +69,7 @@ public class ProvidersInPropertiesTest {
assert Iterables.contains(providers, "walrus") : providers; assert Iterables.contains(providers, "walrus") : providers;
assert Iterables.contains(providers, "googlestorage") : providers; assert Iterables.contains(providers, "googlestorage") : providers;
assert !Iterables.contains(providers, "ec2") : providers; assert !Iterables.contains(providers, "ec2") : providers;
assert !Iterables.contains(providers, "nova") : providers;
assert !Iterables.contains(providers, "eucalyptus") : providers; assert !Iterables.contains(providers, "eucalyptus") : providers;
} }

View File

@ -66,6 +66,8 @@ import org.jclouds.predicates.SocketOpen;
import org.jclouds.rest.RestContextFactory; import org.jclouds.rest.RestContextFactory;
import org.jclouds.scriptbuilder.InitBuilder; import org.jclouds.scriptbuilder.InitBuilder;
import org.jclouds.scriptbuilder.domain.OsFamily; import org.jclouds.scriptbuilder.domain.OsFamily;
import org.jclouds.scriptbuilder.domain.Statement;
import org.jclouds.scriptbuilder.domain.Statements;
import org.jclouds.ssh.ExecResponse; import org.jclouds.ssh.ExecResponse;
import org.jclouds.ssh.SshClient; import org.jclouds.ssh.SshClient;
import org.jclouds.ssh.SshException; import org.jclouds.ssh.SshException;
@ -75,6 +77,7 @@ import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test; import org.testng.annotations.Test;
import com.google.common.base.Predicate; import com.google.common.base.Predicate;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables; import com.google.common.collect.Iterables;
@ -250,25 +253,25 @@ public class EBSBootEC2ClientLiveTest {
"mkebsboot",// name of the script "mkebsboot",// name of the script
"/tmp",// working directory "/tmp",// working directory
"/tmp/logs",// location of stdout.log and stderr.log "/tmp/logs",// location of stdout.log and stderr.log
ImmutableMap.of("imageDir", "/mnt/tmp", "ebsDevice", "/dev/sdh", "ebsMountPoint", "/mnt/ebs"),// variables ImmutableMap.of("imageDir", "/mnt/tmp", "ebsDevice", "/dev/sdh", "ebsMountPoint", "/mnt/ebs"),
// used ImmutableList
// inside .<Statement> of(Statements
// of .interpret(
// the "echo creating a filesystem and mounting the ebs volume",
// script
"echo creating a filesystem and mounting the ebs volume",// what to
// execute
"{md} {varl}IMAGE_DIR{varr} {varl}EBS_MOUNT_POINT{varr}", "{md} {varl}IMAGE_DIR{varr} {varl}EBS_MOUNT_POINT{varr}",
"rm -rf {varl}IMAGE_DIR{varr}/*", "rm -rf {varl}IMAGE_DIR{varr}/*",
"yes| mkfs -t ext3 {varl}EBS_DEVICE{varr} 2>&-", "yes| mkfs -t ext3 {varl}EBS_DEVICE{varr} 2>&-",
"mount {varl}EBS_DEVICE{varr} {varl}EBS_MOUNT_POINT{varr}", "mount {varl}EBS_DEVICE{varr} {varl}EBS_MOUNT_POINT{varr}",
"echo making a local working copy of the boot disk", "echo making a local working copy of the boot disk",
"rsync -ax --exclude /ubuntu/.bash_history --exclude /home/*/.bash_history --exclude /etc/ssh/ssh_host_* --exclude /etc/ssh/moduli --exclude /etc/udev/rules.d/*persistent-net.rules --exclude /var/lib/ec2/* --exclude=/mnt/* --exclude=/proc/* --exclude=/tmp/* --exclude=/dev/log / {varl}IMAGE_DIR{varr}", "rsync -ax --exclude /ubuntu/.bash_history --exclude /home/*/.bash_history --exclude /etc/ssh/ssh_host_* --exclude /etc/ssh/moduli --exclude /etc/udev/rules.d/*persistent-net.rules --exclude /var/lib/ec2/* --exclude=/mnt/* --exclude=/proc/* --exclude=/tmp/* --exclude=/dev/log / {varl}IMAGE_DIR{varr}",
"echo preparing the local working copy", "touch {varl}IMAGE_DIR{varr}/etc/init.d/ec2-init-user-data", "echo preparing the local working copy",
"echo copying the local working copy to the ebs mount", "{cd} {varl}IMAGE_DIR{varr}", "touch {varl}IMAGE_DIR{varr}/etc/init.d/ec2-init-user-data",
"echo copying the local working copy to the ebs mount",
"{cd} {varl}IMAGE_DIR{varr}",
"tar -cSf - * | tar xf - -C {varl}EBS_MOUNT_POINT{varr}", "echo size of ebs", "tar -cSf - * | tar xf - -C {varl}EBS_MOUNT_POINT{varr}", "echo size of ebs",
"du -sk {varl}EBS_MOUNT_POINT{varr}", "echo size of source", "du -sk {varl}IMAGE_DIR{varr}", "du -sk {varl}EBS_MOUNT_POINT{varr}", "echo size of source",
"rm -rf {varl}IMAGE_DIR{varr}/*", "umount {varl}EBS_MOUNT_POINT{varr}", "echo " + SCRIPT_END) "du -sk {varl}IMAGE_DIR{varr}", "rm -rf {varl}IMAGE_DIR{varr}/*",
"umount {varl}EBS_MOUNT_POINT{varr}", "echo " + SCRIPT_END)))
.build(OsFamily.UNIX); .build(OsFamily.UNIX);
} }

View File

@ -0,0 +1,113 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.aws.ec2.compute;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.collect.Iterables.get;
import org.jclouds.blobstore.BlobStoreContext;
import org.jclouds.blobstore.BlobStoreContextFactory;
import org.jclouds.blobstore.domain.Blob;
import org.jclouds.compute.ComputeServiceContext;
import org.jclouds.compute.ComputeServiceContextFactory;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.predicates.NodePredicates;
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
import org.jclouds.net.IPSocket;
import org.jclouds.ssh.ExecResponse;
import org.jclouds.ssh.SshClient;
import org.jclouds.ssh.jsch.config.JschSshClientModule;
import org.testng.annotations.AfterGroups;
import org.testng.annotations.BeforeGroups;
import com.google.common.collect.ImmutableSet;
/**
*
* @author Adrian Cole
*/
public class BlobStoreAndComputeServiceLiveTest {
protected ComputeServiceContext computeContext;
protected BlobStoreContext blobContext;
protected String tag = System.getProperty("user.name") + "happy";
protected String identity;
protected String credential;
protected String blobStoreProvider;
protected String computeServiceProvider;
protected void setupCredentials() {
tag = System.getProperty("user.name") + "happy";
identity = checkNotNull(System.getProperty("jclouds.test.identity"), "jclouds.test.identity");
credential = checkNotNull(System.getProperty("jclouds.test.credential"), "jclouds.test.credential");
}
@BeforeGroups(groups = { "live" })
public void setupClient() {
setupCredentials();
computeContext = new ComputeServiceContextFactory().createContext(computeServiceProvider, identity, credential,
ImmutableSet.of(new Log4JLoggingModule(), new JschSshClientModule()));
blobContext = new BlobStoreContextFactory().createContext(blobStoreProvider, identity, credential, ImmutableSet
.of(new Log4JLoggingModule()));
blobContext.getAsyncBlobStore().createContainerInLocation(null, tag);
computeContext.getComputeService().destroyNodesMatching(NodePredicates.withTag(tag));
}
protected void assertSshOutputOfCommandContains(Iterable<? extends NodeMetadata> nodes, String cmd, String expects) {
for (NodeMetadata node : nodes) {
IPSocket socket = new IPSocket(get(node.getPublicAddresses(), 0), 22);
SshClient ssh = computeContext.utils().sshFactory().create(socket, node.getCredentials().identity,
node.getCredentials().credential.getBytes());
try {
ssh.connect();
ExecResponse exec = ssh.exec(cmd);
assert exec.getOutput().indexOf(expects) != -1 || exec.getError().indexOf(expects) != -1 : exec;
} finally {
if (ssh != null)
ssh.disconnect();
}
}
}
protected void uploadBlob(String container, String name, String script) {
Blob blob = blobContext.getBlobStore().newBlob(name);
blob.setPayload(script);
blob.getPayload().setContentType("text/plain");
blobContext.getBlobStore().putBlob(container, blob);
}
@AfterGroups(groups = { "live" })
public void teardownCompute() {
if (computeContext != null) {
computeContext.getComputeService().destroyNodesMatching(NodePredicates.withTag(tag));
computeContext.close();
}
}
@AfterGroups(groups = { "live" })
public void teardownBlobStore() {
if (blobContext != null) {
blobContext.getAsyncBlobStore().deleteContainer(tag);
blobContext.close();
}
}
}

View File

@ -19,6 +19,7 @@
package org.jclouds.aws.ec2.compute; package org.jclouds.aws.ec2.compute;
import static org.jclouds.compute.util.ComputeServiceUtils.getCores;
import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertEquals;
import java.util.Date; import java.util.Date;
@ -90,9 +91,9 @@ public class EC2ComputeServiceLiveTest extends BaseComputeServiceLiveTest {
protected void assertDefaultWorks() { protected void assertDefaultWorks() {
Template defaultTemplate = client.templateBuilder().build(); Template defaultTemplate = client.templateBuilder().build();
assertEquals(defaultTemplate.getImage().getOperatingSystem().is64Bit(), false); assertEquals(defaultTemplate.getImage().getOperatingSystem().is64Bit(), true);
assertEquals(defaultTemplate.getImage().getOperatingSystem().getFamily(), OsFamily.UBUNTU); assertEquals(defaultTemplate.getImage().getOperatingSystem().getFamily(), OsFamily.AMZN_LINUX);
assertEquals(defaultTemplate.getSize().getCores(), 1.0d); assertEquals(getCores(defaultTemplate.getHardware()), 1.0d);
} }
@Test(enabled = true, dependsOnMethods = "testCompareSizes") @Test(enabled = true, dependsOnMethods = "testCompareSizes")
@ -281,7 +282,6 @@ public class EC2ComputeServiceLiveTest extends BaseComputeServiceLiveTest {
RunningInstance instance = getInstance(instanceClient, startedId); RunningInstance instance = getInstance(instanceClient, startedId);
assertEquals(instance.getSubnetId(), subnetId); assertEquals(instance.getSubnetId(), subnetId);
assertEquals(instance.getSubnetId(), Iterables.getOnlyElement(nodes).getExtra().get("subnetId"));
} finally { } finally {
if (nodeId != null) if (nodeId != null)
@ -303,12 +303,24 @@ public class EC2ComputeServiceLiveTest extends BaseComputeServiceLiveTest {
private void cleanupExtendedStuff(SecurityGroupClient securityGroupClient, KeyPairClient keyPairClient, String tag) private void cleanupExtendedStuff(SecurityGroupClient securityGroupClient, KeyPairClient keyPairClient, String tag)
throws InterruptedException { throws InterruptedException {
try { try {
securityGroupClient.deleteSecurityGroupInRegion(null, tag); for (SecurityGroup group : securityGroupClient.describeSecurityGroupsInRegion(null))
if (group.getName().startsWith("jclouds#" + tag) || group.getName().equals(tag)) {
System.err.printf("deleting group %s%n", group.getName());
securityGroupClient.deleteSecurityGroupInRegion(null, group.getName());
} else {
System.err.printf("group %s didn't match %s%n", group.getName(), tag);
}
} catch (Exception e) { } catch (Exception e) {
} }
try { try {
keyPairClient.deleteKeyPairInRegion(null, tag); for (KeyPair pair : keyPairClient.describeKeyPairsInRegion(null))
if (pair.getKeyName().startsWith("jclouds#" + tag) || pair.getKeyName().equals(tag)) {
System.err.printf("deleting key %s%n", pair.getKeyName());
keyPairClient.deleteKeyPairInRegion(null, pair.getKeyName());
} else {
System.err.printf("key %s didn't match %s%n", pair.getKeyName(), tag);
}
} catch (Exception e) { } catch (Exception e) {
} }

View File

@ -28,17 +28,19 @@ import java.util.Set;
import javax.inject.Provider; import javax.inject.Provider;
import org.jclouds.aws.ec2.compute.domain.EC2Size; import org.jclouds.aws.ec2.compute.domain.EC2Hardware;
import org.jclouds.aws.ec2.domain.InstanceType; import org.jclouds.aws.ec2.domain.InstanceType;
import org.jclouds.compute.domain.ComputeMetadata; import org.jclouds.compute.domain.ComputeMetadata;
import org.jclouds.compute.domain.Image; import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.OperatingSystem; import org.jclouds.compute.domain.OperatingSystem;
import org.jclouds.compute.domain.OsFamily; import org.jclouds.compute.domain.OsFamily;
import org.jclouds.compute.domain.Size; import org.jclouds.compute.domain.Hardware;
import org.jclouds.compute.domain.Processor;
import org.jclouds.compute.domain.Template; import org.jclouds.compute.domain.Template;
import org.jclouds.compute.domain.TemplateBuilder; import org.jclouds.compute.domain.TemplateBuilder;
import org.jclouds.compute.domain.internal.ImageImpl; import org.jclouds.compute.domain.internal.ImageImpl;
import org.jclouds.compute.domain.internal.TemplateBuilderImpl; import org.jclouds.compute.domain.internal.TemplateBuilderImpl;
import org.jclouds.compute.domain.internal.VolumeImpl;
import org.jclouds.compute.options.TemplateOptions; import org.jclouds.compute.options.TemplateOptions;
import org.jclouds.domain.Credentials; import org.jclouds.domain.Credentials;
import org.jclouds.domain.Location; import org.jclouds.domain.Location;
@ -49,6 +51,7 @@ import org.testng.annotations.Test;
import com.google.common.base.Function; import com.google.common.base.Function;
import com.google.common.base.Supplier; import com.google.common.base.Supplier;
import com.google.common.base.Suppliers; import com.google.common.base.Suppliers;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
@ -65,33 +68,35 @@ import com.google.common.collect.Maps;
public class EC2ComputeServiceTest { public class EC2ComputeServiceTest {
private static final Location location = new LocationImpl(LocationScope.REGION, "us-east-1", "us east", null); private static final Location location = new LocationImpl(LocationScope.REGION, "us-east-1", "us east", null);
public static final EC2Size CC1_4XLARGE = new EC2Size(location, InstanceType.CC1_4XLARGE, 33.5, 23 * 1024, 1690, public static final EC2Hardware CC1_4XLARGE = new EC2Hardware(location, InstanceType.CC1_4XLARGE, ImmutableList.of(
new String[] { "us-east-1/cc-image" }); new Processor(4.0, 4.0), new Processor(4.0, 4.0)), 23 * 1024, ImmutableList.of(new VolumeImpl(10.0f,
"/dev/sda1", true, false), new VolumeImpl(840.0f, "/dev/sdb", false, false), new VolumeImpl(840.0f,
"/dev/sdc", false, false)), new String[] { "us-east-1/cc-image" });
/** /**
* Verifies that {@link TemplateBuilderImpl} would choose the correct size of the instance, based * Verifies that {@link TemplateBuilderImpl} would choose the correct size of the instance, based
* on {@link org.jclouds.compute.domain.Size} from {@link EC2Size}. * on {@link org.jclouds.compute.domain.Hardware} from {@link EC2Hardware}.
* *
* Expected size: m2.xlarge * Expected size: m2.xlarge
*/ */
@Test @Test
public void testTemplateChoiceForInstanceBySizeId() throws Exception { public void testTemplateChoiceForInstanceByhardwareId() throws Exception {
Template template = newTemplateBuilder().os64Bit(true).sizeId("m2.xlarge").locationId("us-east-1").build(); Template template = newTemplateBuilder().os64Bit(true).hardwareId("m2.xlarge").locationId("us-east-1").build();
assert template != null : "The returned template was null, but it should have a value."; assert template != null : "The returned template was null, but it should have a value.";
assert EC2Size.M2_XLARGE.equals(template.getSize()) : format( assert EC2Hardware.M2_XLARGE.equals(template.getHardware()) : format(
"Incorrect image determined by the template. Expected: %s. Found: %s.", "m2.xlarge", String "Incorrect image determined by the template. Expected: %s. Found: %s.", "m2.xlarge", String
.valueOf(template.getSize())); .valueOf(template.getHardware()));
} }
@Test @Test
public void testTemplateChoiceForInstanceByCCSizeId() throws Exception { public void testTemplateChoiceForInstanceByCChardwareId() throws Exception {
Template template = newTemplateBuilder().fastest().build(); Template template = newTemplateBuilder().fastest().build();
assert template != null : "The returned template was null, but it should have a value."; assert template != null : "The returned template was null, but it should have a value.";
assert CC1_4XLARGE.equals(template.getSize()) : format( assert CC1_4XLARGE.equals(template.getHardware()) : format(
"Incorrect image determined by the template. Expected: %s. Found: %s.", CC1_4XLARGE.getId(), String "Incorrect image determined by the template. Expected: %s. Found: %s.", CC1_4XLARGE.getId(), String
.valueOf(template.getSize())); .valueOf(template.getHardware()));
} }
/** /**
@ -106,9 +111,9 @@ public class EC2ComputeServiceTest {
"us-east-1").build(); "us-east-1").build();
assert template != null : "The returned template was null, but it should have a value."; assert template != null : "The returned template was null, but it should have a value.";
assert EC2Size.M2_XLARGE.equals(template.getSize()) : format( assert CC1_4XLARGE.equals(template.getHardware()) : format(
"Incorrect image determined by the template. Expected: %s. Found: %s.", "m2.xlarge", String "Incorrect image determined by the template. Expected: %s. Found: %s.", CC1_4XLARGE, String
.valueOf(template.getSize())); .valueOf(template.getHardware()));
} }
/** /**
@ -125,9 +130,9 @@ public class EC2ComputeServiceTest {
"us-east-1").build(); "us-east-1").build();
assert template != null : "The returned template was null, but it should have a value."; assert template != null : "The returned template was null, but it should have a value.";
assert !EC2Size.M2_XLARGE.equals(template.getSize()) : format( assert !EC2Hardware.M2_XLARGE.equals(template.getHardware()) : format(
"Incorrect image determined by the template. Expected: not %s. Found: %s.", "m2.xlarge", String "Incorrect image determined by the template. Expected: not %s. Found: %s.", "m2.xlarge", String
.valueOf(template.getSize())); .valueOf(template.getHardware()));
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@ -148,9 +153,10 @@ public class EC2ComputeServiceTest {
.<Location> of(location)); .<Location> of(location));
Supplier<Set<? extends Image>> images = Suppliers.<Set<? extends Image>> ofInstance(ImmutableSet Supplier<Set<? extends Image>> images = Suppliers.<Set<? extends Image>> ofInstance(ImmutableSet
.<Image> of(image)); .<Image> of(image));
Supplier<Set<? extends Size>> sizes = Suppliers.<Set<? extends Size>> ofInstance(ImmutableSet.<Size> of( Supplier<Set<? extends Hardware>> sizes = Suppliers.<Set<? extends Hardware>> ofInstance(ImmutableSet
EC2Size.C1_MEDIUM, EC2Size.C1_XLARGE, EC2Size.M1_LARGE, EC2Size.M1_SMALL, EC2Size.M1_XLARGE, .<Hardware> of(EC2Hardware.T1_MICRO, EC2Hardware.C1_MEDIUM, EC2Hardware.C1_XLARGE, EC2Hardware.M1_LARGE,
EC2Size.M2_XLARGE, EC2Size.M2_2XLARGE, EC2Size.M2_4XLARGE, CC1_4XLARGE)); EC2Hardware.M1_SMALL, EC2Hardware.M1_XLARGE, EC2Hardware.M2_XLARGE, EC2Hardware.M2_2XLARGE,
EC2Hardware.M2_4XLARGE, CC1_4XLARGE));
return new TemplateBuilderImpl(locations, images, sizes, Suppliers.ofInstance(location), optionsProvider, return new TemplateBuilderImpl(locations, images, sizes, Suppliers.ofInstance(location), optionsProvider,
templateBuilderProvider) { templateBuilderProvider) {

View File

@ -20,6 +20,7 @@
package org.jclouds.aws.ec2.compute; package org.jclouds.aws.ec2.compute;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
import static org.jclouds.compute.util.ComputeServiceUtils.getCores;
import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertEquals;
import java.io.IOException; import java.io.IOException;
@ -27,6 +28,7 @@ import java.util.Properties;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeoutException; import java.util.concurrent.TimeoutException;
import org.jclouds.aws.ec2.domain.InstanceType;
import org.jclouds.aws.ec2.reference.EC2Constants; import org.jclouds.aws.ec2.reference.EC2Constants;
import org.jclouds.compute.ComputeServiceContext; import org.jclouds.compute.ComputeServiceContext;
import org.jclouds.compute.ComputeServiceContextFactory; import org.jclouds.compute.ComputeServiceContextFactory;
@ -37,7 +39,6 @@ import org.testng.annotations.BeforeGroups;
import org.testng.annotations.Test; import org.testng.annotations.Test;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
/** /**
* *
@ -55,30 +56,71 @@ public class EC2TemplateBuilderLiveTest {
} }
@Test @Test
public void testTemplateBuilderCanUseImageId() { public void testTemplateBuilderCanUseImageIdAndhardwareId() {
// TODO ComputeServiceContext newContext = null;
try {
newContext = new ComputeServiceContextFactory().createContext("ec2", user, password,
ImmutableSet.of(new Log4JLoggingModule()));
Template template = newContext.getComputeService().templateBuilder().imageId("us-east-1/ami-ccb35ea5")
.hardwareId(InstanceType.M2_2XLARGE).build();
System.out.println(template.getHardware());
assert (template.getImage().getProviderId().startsWith("ami-")) : template;
assertEquals(template.getImage().getOperatingSystem().getVersion(), "5.4");
assertEquals(template.getImage().getOperatingSystem().is64Bit(), true);
assertEquals(template.getImage().getOperatingSystem().getFamily(), OsFamily.CENTOS);
assertEquals(template.getImage().getVersion(), "4.4.10");
assertEquals(template.getImage().getUserMetadata().get("rootDeviceType"), "instance-store");
assertEquals(template.getLocation().getId(), "us-east-1");
assertEquals(getCores(template.getHardware()), 4.0d);
assertEquals(template.getHardware().getId(), InstanceType.M2_2XLARGE);
} finally {
if (newContext != null)
newContext.close();
}
} }
@Test @Test
public void testTemplateBuilder() throws IOException { public void testDefaultTemplateBuilder() throws IOException {
ComputeServiceContext newContext = null; ComputeServiceContext newContext = null;
try { try {
newContext = new ComputeServiceContextFactory().createContext("ec2", user, password, ImmutableSet newContext = new ComputeServiceContextFactory().createContext("ec2", user, password,
.of(new Log4JLoggingModule())); ImmutableSet.of(new Log4JLoggingModule()));
Template defaultTemplate = newContext.getComputeService().templateBuilder().build(); Template defaultTemplate = newContext.getComputeService().templateBuilder().build();
assert (defaultTemplate.getImage().getProviderId().startsWith("ami-")) : defaultTemplate; assert (defaultTemplate.getImage().getProviderId().startsWith("ami-")) : defaultTemplate;
assertEquals(defaultTemplate.getImage().getOperatingSystem().getVersion(), "10.04"); assertEquals(defaultTemplate.getImage().getOperatingSystem().getVersion(), "0.9.7-beta");
assertEquals(defaultTemplate.getImage().getOperatingSystem().is64Bit(), false); assertEquals(defaultTemplate.getImage().getOperatingSystem().is64Bit(), true);
assertEquals(defaultTemplate.getImage().getOperatingSystem().getFamily(), OsFamily.UBUNTU); assertEquals(defaultTemplate.getImage().getOperatingSystem().getFamily(), OsFamily.AMZN_LINUX);
assertEquals(defaultTemplate.getImage().getUserMetadata().get("rootDeviceType"), "ebs");
assertEquals(defaultTemplate.getLocation().getId(), "us-east-1"); assertEquals(defaultTemplate.getLocation().getId(), "us-east-1");
assertEquals(defaultTemplate.getSize().getCores(), 1.0d); assertEquals(getCores(defaultTemplate.getHardware()), 1.0d);
newContext.getComputeService().templateBuilder().imageId(
Iterables.get(newContext.getComputeService().listImages(), 0).getId()).build(); } finally {
newContext.getComputeService().templateBuilder().osFamily(OsFamily.UBUNTU).smallest().os64Bit(false).imageId( if (newContext != null)
"us-east-1/ami-7e28ca17").build(); newContext.close();
newContext.getComputeService().templateBuilder().osFamily(OsFamily.UBUNTU).smallest().os64Bit(false).imageId( }
"us-east-1/ami-bb709dd2").build(); }
@Test
public void testTemplateBuilderMicro() throws IOException {
ComputeServiceContext newContext = null;
try {
newContext = new ComputeServiceContextFactory().createContext("ec2", user, password,
ImmutableSet.of(new Log4JLoggingModule()));
Template microTemplate = newContext.getComputeService().templateBuilder().hardwareId(InstanceType.T1_MICRO)
.build();
System.out.println(microTemplate.getHardware());
assert (microTemplate.getImage().getProviderId().startsWith("ami-")) : microTemplate;
assertEquals(microTemplate.getImage().getOperatingSystem().getVersion(), "9.10");
assertEquals(microTemplate.getImage().getOperatingSystem().is64Bit(), false);
assertEquals(microTemplate.getImage().getOperatingSystem().getFamily(), OsFamily.UBUNTU);
assertEquals(microTemplate.getImage().getUserMetadata().get("rootDeviceType"), "ebs");
assertEquals(microTemplate.getLocation().getId(), "us-east-1");
assertEquals(getCores(microTemplate.getHardware()), 1.0d);
} finally { } finally {
if (newContext != null) if (newContext != null)
newContext.close(); newContext.close();
@ -93,21 +135,23 @@ public class EC2TemplateBuilderLiveTest {
// set owners to nothing // set owners to nothing
overrides.setProperty(EC2Constants.PROPERTY_EC2_AMI_OWNERS, ""); overrides.setProperty(EC2Constants.PROPERTY_EC2_AMI_OWNERS, "");
newContext = new ComputeServiceContextFactory().createContext("ec2", user, password, ImmutableSet newContext = new ComputeServiceContextFactory().createContext("ec2", user, password,
.of(new Log4JLoggingModule()), overrides); ImmutableSet.of(new Log4JLoggingModule()), overrides);
assertEquals(newContext.getComputeService().listImages().size(), 0); assertEquals(newContext.getComputeService().listImages().size(), 0);
Template template = newContext.getComputeService().templateBuilder().imageId("us-east-1/ami-ccb35ea5").build(); Template template = newContext.getComputeService().templateBuilder().imageId("us-east-1/ami-ccb35ea5").build();
System.out.println(template.getImage()); System.out.println(template.getHardware());
assert (template.getImage().getProviderId().startsWith("ami-")) : template; assert (template.getImage().getProviderId().startsWith("ami-")) : template;
assertEquals(template.getImage().getOperatingSystem().getVersion(), "5.4"); assertEquals(template.getImage().getOperatingSystem().getVersion(), "5.4");
assertEquals(template.getImage().getOperatingSystem().is64Bit(), true); assertEquals(template.getImage().getOperatingSystem().is64Bit(), true);
assertEquals(template.getImage().getOperatingSystem().getFamily(), OsFamily.CENTOS); assertEquals(template.getImage().getOperatingSystem().getFamily(), OsFamily.CENTOS);
assertEquals(template.getImage().getVersion(), "4.4.10"); assertEquals(template.getImage().getVersion(), "4.4.10");
assertEquals(template.getImage().getUserMetadata().get("rootDeviceType"), "instance-store");
assertEquals(template.getLocation().getId(), "us-east-1"); assertEquals(template.getLocation().getId(), "us-east-1");
assertEquals(template.getSize().getCores(), 4.0d); // because it is 64bit assertEquals(getCores(template.getHardware()), 2.0d);
assertEquals(template.getSize().getId(), "m1.large"); // because it is 64bit assertEquals(template.getHardware().getId(), "m1.large"); // because it
// is 64bit
// ensure we cache the new image for next time // ensure we cache the new image for next time
assertEquals(newContext.getComputeService().listImages().size(), 1); assertEquals(newContext.getComputeService().listImages().size(), 1);

View File

@ -19,6 +19,7 @@
package org.jclouds.aws.ec2.compute; package org.jclouds.aws.ec2.compute;
import static org.jclouds.compute.util.ComputeServiceUtils.getCores;
import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertEquals;
import org.jclouds.compute.domain.OsFamily; import org.jclouds.compute.domain.OsFamily;
@ -45,8 +46,7 @@ public class EucalyptusComputeServiceLiveTest extends EC2ComputeServiceLiveTest
Template defaultTemplate = client.templateBuilder().build(); Template defaultTemplate = client.templateBuilder().build();
assertEquals(defaultTemplate.getImage().getOperatingSystem().is64Bit(), true); assertEquals(defaultTemplate.getImage().getOperatingSystem().is64Bit(), true);
assertEquals(defaultTemplate.getImage().getOperatingSystem().getFamily(), OsFamily.CENTOS); assertEquals(defaultTemplate.getImage().getOperatingSystem().getFamily(), OsFamily.CENTOS);
// 64 bit implied 4 ecus assertEquals(getCores(defaultTemplate.getHardware()), 1.0d);
assertEquals(defaultTemplate.getSize().getCores(), 4.0d);
} }
} }

View File

@ -0,0 +1,54 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.aws.ec2.compute;
import static org.jclouds.compute.util.ComputeServiceUtils.getCores;
import static org.testng.Assert.assertEquals;
import org.jclouds.compute.domain.OsFamily;
import org.jclouds.compute.domain.Template;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
/**
*
* @author Adrian Cole
*/
@Test(groups = "live", sequential = true, testName = "ec2.NebulaComputeServiceLiveTest")
public class NovaComputeServiceLiveTest extends EC2ComputeServiceLiveTest {
@BeforeClass
@Override
public void setServiceDefaults() {
provider = "nova";
}
@Override
protected void assertDefaultWorks() {
Template defaultTemplate = client.templateBuilder().build();
assert (defaultTemplate.getImage().getProviderId().startsWith("ami-")) : defaultTemplate;
assertEquals(defaultTemplate.getImage().getOperatingSystem().getVersion(), "10.04");
assertEquals(defaultTemplate.getImage().getOperatingSystem().is64Bit(), true);
assertEquals(defaultTemplate.getImage().getOperatingSystem().getFamily(), OsFamily.UBUNTU);
assertEquals(defaultTemplate.getImage().getUserMetadata().get("rootDeviceType"), "instance-store");
assertEquals(defaultTemplate.getLocation().getId(), "nova");
assertEquals(getCores(defaultTemplate.getHardware()), 1.0d);
}
}

View File

@ -0,0 +1,110 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.aws.ec2.compute;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.jclouds.compute.util.ComputeServiceUtils.getCores;
import static org.testng.Assert.assertEquals;
import java.io.IOException;
import java.util.Properties;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeoutException;
import org.jclouds.aws.ec2.reference.EC2Constants;
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.logging.log4j.config.Log4JLoggingModule;
import org.testng.annotations.BeforeGroups;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableSet;
/**
*
* @author Adrian Cole
*/
@Test(groups = "live", testName = "ec2.NebulaTemplateBuilderLiveTest")
public class NovaTemplateBuilderLiveTest {
private String password;
private String user;
@BeforeGroups(groups = { "live" })
public void setupClient() throws InterruptedException, ExecutionException, TimeoutException, IOException {
user = checkNotNull(System.getProperty("jclouds.test.identity"), "jclouds.test.identity");
password = checkNotNull(System.getProperty("jclouds.test.credential"), "jclouds.test.credential");
}
@Test
public void testDefaultTemplateBuilder() throws IOException {
ComputeServiceContext newContext = null;
try {
newContext = new ComputeServiceContextFactory().createContext("nova", user, password, ImmutableSet
.of(new Log4JLoggingModule()));
Template defaultTemplate = newContext.getComputeService().templateBuilder().build();
assert (defaultTemplate.getImage().getProviderId().startsWith("ami-")) : defaultTemplate;
assertEquals(defaultTemplate.getImage().getOperatingSystem().getVersion(), "9.10");
assertEquals(defaultTemplate.getImage().getOperatingSystem().is64Bit(), true);
assertEquals(defaultTemplate.getImage().getOperatingSystem().getFamily(), OsFamily.UBUNTU);
assertEquals(defaultTemplate.getImage().getUserMetadata().get("rootDeviceType"), "instance-store");
assertEquals(defaultTemplate.getLocation().getId(), "nova");
assertEquals(getCores(defaultTemplate.getHardware()), 1.0d);
} finally {
if (newContext != null)
newContext.close();
}
}
@Test
public void testTemplateBuilderWithNoOwnersParsesImageOnDemand() throws IOException {
ComputeServiceContext newContext = null;
try {
Properties overrides = new Properties();
// set owners to nothing
overrides.setProperty(EC2Constants.PROPERTY_EC2_AMI_OWNERS, "");
newContext = new ComputeServiceContextFactory().createContext("nova", user, password, ImmutableSet
.of(new Log4JLoggingModule()), overrides);
assertEquals(newContext.getComputeService().listImages().size(), 0);
Template template = newContext.getComputeService().templateBuilder().imageId("nova/ami-6CD61336").build();
assert (template.getImage().getProviderId().startsWith("ami-")) : template;
assertEquals(template.getImage().getOperatingSystem().getVersion(), "");
assertEquals(template.getImage().getOperatingSystem().is64Bit(), true);
assertEquals(template.getImage().getOperatingSystem().getFamily(), null);
assertEquals(template.getImage().getUserMetadata().get("rootDeviceType"), "instance-store");
assertEquals(template.getLocation().getId(), "nova");
assertEquals(getCores(template.getHardware()), 1.0d);
// ensure we cache the new image for next time
assertEquals(newContext.getComputeService().listImages().size(), 1);
} finally {
if (newContext != null)
newContext.close();
}
}
}

View File

@ -54,11 +54,11 @@ public class ImageParserTest extends BaseEC2HandlerTest {
InputStream is = getClass().getResourceAsStream("/ec2/alestic_canonical.xml"); InputStream is = getClass().getResourceAsStream("/ec2/alestic_canonical.xml");
Set<Image> result = parseImages(is); Set<Image> result = parseImages(is);
assertEquals(result.size(), 7); assertEquals(result.size(), 8);
ImageParser parser = new ImageParser(new EC2PopulateDefaultLoginCredentialsForImageStrategy(), Suppliers ImageParser parser = new ImageParser(new EC2PopulateDefaultLoginCredentialsForImageStrategy(), Suppliers
.<Set<? extends Location>> ofInstance(ImmutableSet.<Location> of(defaultLocation)), Suppliers .<Set<? extends Location>> ofInstance(ImmutableSet.<Location> of(defaultLocation)), Suppliers
.ofInstance(defaultLocation)); .ofInstance(defaultLocation), "ec2");
org.jclouds.compute.domain.Image ubuntuHardy = parser.apply(Iterables.get(result, 0)); org.jclouds.compute.domain.Image ubuntuHardy = parser.apply(Iterables.get(result, 0));
assertEquals(ubuntuHardy.getDescription(), "ubuntu-images-us/ubuntu-hardy-8.04-i386-server-20091130.manifest.xml"); assertEquals(ubuntuHardy.getDescription(), "ubuntu-images-us/ubuntu-hardy-8.04-i386-server-20091130.manifest.xml");
@ -73,7 +73,8 @@ public class ImageParserTest extends BaseEC2HandlerTest {
assertEquals(ubuntuHardy.getOperatingSystem().getDescription(), assertEquals(ubuntuHardy.getOperatingSystem().getDescription(),
"ubuntu-images-us/ubuntu-hardy-8.04-i386-server-20091130.manifest.xml"); "ubuntu-images-us/ubuntu-hardy-8.04-i386-server-20091130.manifest.xml");
assertEquals(ubuntuHardy.getOperatingSystem().is64Bit(), false); assertEquals(ubuntuHardy.getOperatingSystem().is64Bit(), false);
assertEquals(ubuntuHardy.getUserMetadata(), ImmutableMap.<String, String> of("owner", "099720109477")); assertEquals(ubuntuHardy.getUserMetadata(), ImmutableMap.<String, String> of("owner", "099720109477",
"rootDeviceType", "instance-store"));
assertEquals(ubuntuHardy.getVersion(), "20091130"); assertEquals(ubuntuHardy.getVersion(), "20091130");
org.jclouds.compute.domain.Image alesticKarmic = parser.apply(Iterables.get(result, 1)); org.jclouds.compute.domain.Image alesticKarmic = parser.apply(Iterables.get(result, 1));
@ -90,7 +91,8 @@ public class ImageParserTest extends BaseEC2HandlerTest {
assertEquals(alesticKarmic.getOperatingSystem().getDescription(), assertEquals(alesticKarmic.getOperatingSystem().getDescription(),
"alestic/ubuntu-9.10-karmic-base-20090623.manifest.xml"); "alestic/ubuntu-9.10-karmic-base-20090623.manifest.xml");
assertEquals(alesticKarmic.getOperatingSystem().getFamily(), OsFamily.UBUNTU); assertEquals(alesticKarmic.getOperatingSystem().getFamily(), OsFamily.UBUNTU);
assertEquals(alesticKarmic.getUserMetadata(), ImmutableMap.<String, String> of("owner", "063491364108")); assertEquals(alesticKarmic.getUserMetadata(), ImmutableMap.<String, String> of("owner", "063491364108",
"rootDeviceType", "instance-store"));
assertEquals(alesticKarmic.getVersion(), "20090623"); assertEquals(alesticKarmic.getVersion(), "20090623");
org.jclouds.compute.domain.Image ubuntuKarmic = parser.apply(Iterables.get(result, 2)); org.jclouds.compute.domain.Image ubuntuKarmic = parser.apply(Iterables.get(result, 2));
@ -108,11 +110,28 @@ public class ImageParserTest extends BaseEC2HandlerTest {
assertEquals(ubuntuKarmic.getOperatingSystem().getDescription(), assertEquals(ubuntuKarmic.getOperatingSystem().getDescription(),
"ubuntu-images-us/ubuntu-karmic-9.10-i386-server-20100121.manifest.xml"); "ubuntu-images-us/ubuntu-karmic-9.10-i386-server-20100121.manifest.xml");
assertEquals(ubuntuKarmic.getOperatingSystem().getFamily(), OsFamily.UBUNTU); assertEquals(ubuntuKarmic.getOperatingSystem().getFamily(), OsFamily.UBUNTU);
assertEquals(ubuntuKarmic.getUserMetadata(), ImmutableMap.<String, String> of("owner", "099720109477")); assertEquals(ubuntuKarmic.getUserMetadata(), ImmutableMap.<String, String> of("owner", "099720109477",
"rootDeviceType", "instance-store"));
assertEquals(ubuntuKarmic.getVersion(), "20100121"); assertEquals(ubuntuKarmic.getVersion(), "20100121");
// should skip testing image org.jclouds.compute.domain.Image testing = parser.apply(Iterables.get(result, 3));
assert parser.apply(Iterables.get(result, 3)) == null;
assertEquals(testing.getOperatingSystem().is64Bit(), true);
assertEquals(testing.getDescription(),
"ubuntu-images-testing-us/ubuntu-lucid-daily-amd64-desktop-20100317.manifest.xml");
assertEquals(testing.getId(), "us-east-1/ami-190fe070");
assertEquals(testing.getProviderId(), "ami-190fe070");
assertEquals(testing.getLocation(), defaultLocation);
assertEquals(testing.getName(), null);
assertEquals(testing.getOperatingSystem().getName(), null);
assertEquals(testing.getOperatingSystem().getVersion(), "10.04");
assertEquals(testing.getOperatingSystem().getArch(), "paravirtual");
assertEquals(testing.getOperatingSystem().getDescription(),
"ubuntu-images-testing-us/ubuntu-lucid-daily-amd64-desktop-20100317.manifest.xml");
assertEquals(testing.getOperatingSystem().getFamily(), OsFamily.UBUNTU);
assertEquals(testing.getUserMetadata(), ImmutableMap.<String, String> of("owner", "099720109477",
"rootDeviceType", "instance-store"));
assertEquals(testing.getVersion(), "20100317");
org.jclouds.compute.domain.Image alesticHardy = parser.apply(Iterables.get(result, 4)); org.jclouds.compute.domain.Image alesticHardy = parser.apply(Iterables.get(result, 4));
@ -128,7 +147,8 @@ public class ImageParserTest extends BaseEC2HandlerTest {
assertEquals(alesticHardy.getOperatingSystem().getDescription(), assertEquals(alesticHardy.getOperatingSystem().getDescription(),
"alestic/ubuntu-8.04-hardy-base-20080905.manifest.xml"); "alestic/ubuntu-8.04-hardy-base-20080905.manifest.xml");
assertEquals(alesticHardy.getOperatingSystem().getFamily(), OsFamily.UBUNTU); assertEquals(alesticHardy.getOperatingSystem().getFamily(), OsFamily.UBUNTU);
assertEquals(alesticHardy.getUserMetadata(), ImmutableMap.<String, String> of("owner", "063491364108")); assertEquals(alesticHardy.getUserMetadata(), ImmutableMap.<String, String> of("owner", "063491364108",
"rootDeviceType", "instance-store"));
assertEquals(alesticHardy.getVersion(), "20080905"); assertEquals(alesticHardy.getVersion(), "20080905");
org.jclouds.compute.domain.Image ubuntuLucid = parser.apply(Iterables.get(result, 5)); org.jclouds.compute.domain.Image ubuntuLucid = parser.apply(Iterables.get(result, 5));
@ -146,11 +166,31 @@ public class ImageParserTest extends BaseEC2HandlerTest {
assertEquals(ubuntuLucid.getOperatingSystem().getDescription(), assertEquals(ubuntuLucid.getOperatingSystem().getDescription(),
"ubuntu-images-us-west-1/ubuntu-lucid-10.04-i386-server-20100427.1.manifest.xml"); "ubuntu-images-us-west-1/ubuntu-lucid-10.04-i386-server-20100427.1.manifest.xml");
assertEquals(ubuntuLucid.getOperatingSystem().getFamily(), OsFamily.UBUNTU); assertEquals(ubuntuLucid.getOperatingSystem().getFamily(), OsFamily.UBUNTU);
assertEquals(ubuntuLucid.getUserMetadata(), ImmutableMap.<String, String> of("owner", "099720109477")); assertEquals(ubuntuLucid.getUserMetadata(), ImmutableMap.<String, String> of("owner", "099720109477",
"rootDeviceType", "instance-store"));
assertEquals(ubuntuLucid.getVersion(), "20100427.1"); assertEquals(ubuntuLucid.getVersion(), "20100427.1");
// should skip kernel // should skip kernel
assert parser.apply(Iterables.get(result, 6)) == null; assert parser.apply(Iterables.get(result, 6)) == null;
org.jclouds.compute.domain.Image ubuntuEbs = parser.apply(Iterables.get(result, 7));
assertEquals(ubuntuEbs.getOperatingSystem().is64Bit(), false);
assertEquals(ubuntuEbs.getDescription(), "099720109477/ebs/ubuntu-images/ubuntu-lucid-10.04-i386-server-20100827");
assertEquals(ubuntuEbs.getId(), "us-east-1/ami-10f3a255");
assertEquals(ubuntuEbs.getProviderId(), "ami-10f3a255");
assertEquals(ubuntuEbs.getLocation(), defaultLocation);
assertEquals(ubuntuEbs.getName(), null);
assertEquals(ubuntuEbs.getOperatingSystem().getName(), null);
assertEquals(ubuntuEbs.getOperatingSystem().getVersion(), "10.04");
assertEquals(ubuntuEbs.getOperatingSystem().getArch(), "paravirtual");
assertEquals(ubuntuEbs.getOperatingSystem().getDescription(),
"099720109477/ebs/ubuntu-images/ubuntu-lucid-10.04-i386-server-20100827");
assertEquals(ubuntuEbs.getOperatingSystem().getFamily(), OsFamily.UBUNTU);
assertEquals(ubuntuEbs.getUserMetadata(), ImmutableMap.<String, String> of("owner", "099720109477",
"rootDeviceType", "ebs"));
assertEquals(ubuntuEbs.getVersion(), "20100827");
} }
private Location defaultLocation = new LocationImpl(LocationScope.REGION, "us-east-1", "us-east-1", null); private Location defaultLocation = new LocationImpl(LocationScope.REGION, "us-east-1", "us-east-1", null);
@ -162,7 +202,7 @@ public class ImageParserTest extends BaseEC2HandlerTest {
ImageParser parser = new ImageParser(new EC2PopulateDefaultLoginCredentialsForImageStrategy(), Suppliers ImageParser parser = new ImageParser(new EC2PopulateDefaultLoginCredentialsForImageStrategy(), Suppliers
.<Set<? extends Location>> ofInstance(ImmutableSet.<Location> of(defaultLocation)), Suppliers .<Set<? extends Location>> ofInstance(ImmutableSet.<Location> of(defaultLocation)), Suppliers
.ofInstance(defaultLocation)); .ofInstance(defaultLocation), "ec2");
org.jclouds.compute.domain.Image image = parser.apply(Iterables.get(result, 0)); org.jclouds.compute.domain.Image image = parser.apply(Iterables.get(result, 0));
@ -178,7 +218,8 @@ public class ImageParserTest extends BaseEC2HandlerTest {
assertEquals(image.getOperatingSystem().getDescription(), assertEquals(image.getOperatingSystem().getDescription(),
"vostok-builds/vostok-0.95-5622/vostok-0.95-5622.manifest.xml"); "vostok-builds/vostok-0.95-5622/vostok-0.95-5622.manifest.xml");
assertEquals(image.getOperatingSystem().getFamily(), OsFamily.UNKNOWN); assertEquals(image.getOperatingSystem().getFamily(), OsFamily.UNKNOWN);
assertEquals(image.getUserMetadata(), ImmutableMap.<String, String> of("owner", "133804938231")); assertEquals(image.getUserMetadata(), ImmutableMap.<String, String> of("owner", "133804938231", "rootDeviceType",
"instance-store"));
assertEquals(image.getVersion(), "5622"); assertEquals(image.getVersion(), "5622");
} }
@ -190,7 +231,7 @@ public class ImageParserTest extends BaseEC2HandlerTest {
ImageParser parser = new ImageParser(new EC2PopulateDefaultLoginCredentialsForImageStrategy(), Suppliers ImageParser parser = new ImageParser(new EC2PopulateDefaultLoginCredentialsForImageStrategy(), Suppliers
.<Set<? extends Location>> ofInstance(ImmutableSet.<Location> of(defaultLocation)), Suppliers .<Set<? extends Location>> ofInstance(ImmutableSet.<Location> of(defaultLocation)), Suppliers
.ofInstance(defaultLocation)); .ofInstance(defaultLocation), "ec2");
org.jclouds.compute.domain.Image image = parser.apply(Iterables.get(result, 0)); org.jclouds.compute.domain.Image image = parser.apply(Iterables.get(result, 0));
@ -205,7 +246,8 @@ public class ImageParserTest extends BaseEC2HandlerTest {
assertEquals(image.getOperatingSystem().getArch(), "hvm"); assertEquals(image.getOperatingSystem().getArch(), "hvm");
assertEquals(image.getOperatingSystem().getDescription(), "amazon/EC2 CentOS 5.4 HVM AMI"); assertEquals(image.getOperatingSystem().getDescription(), "amazon/EC2 CentOS 5.4 HVM AMI");
assertEquals(image.getOperatingSystem().getFamily(), OsFamily.CENTOS); assertEquals(image.getOperatingSystem().getFamily(), OsFamily.CENTOS);
assertEquals(image.getUserMetadata(), ImmutableMap.<String, String> of("owner", "206029621532")); assertEquals(image.getUserMetadata(), ImmutableMap.<String, String> of("owner", "206029621532", "rootDeviceType",
"ebs"));
assertEquals(image.getVersion(), null); assertEquals(image.getVersion(), null);
} }
@ -217,7 +259,7 @@ public class ImageParserTest extends BaseEC2HandlerTest {
ImageParser parser = new ImageParser(new EC2PopulateDefaultLoginCredentialsForImageStrategy(), Suppliers ImageParser parser = new ImageParser(new EC2PopulateDefaultLoginCredentialsForImageStrategy(), Suppliers
.<Set<? extends Location>> ofInstance(ImmutableSet.<Location> of(defaultLocation)), Suppliers .<Set<? extends Location>> ofInstance(ImmutableSet.<Location> of(defaultLocation)), Suppliers
.ofInstance(defaultLocation)); .ofInstance(defaultLocation), "ec2");
org.jclouds.compute.domain.Image image = parser.apply(Iterables.get(result, 0)); org.jclouds.compute.domain.Image image = parser.apply(Iterables.get(result, 0));
@ -233,7 +275,8 @@ public class ImageParserTest extends BaseEC2HandlerTest {
assertEquals(image.getOperatingSystem().getDescription(), assertEquals(image.getOperatingSystem().getDescription(),
"rightscale-us-east/CentOS_5.4_x64_v4.4.10.manifest.xml"); "rightscale-us-east/CentOS_5.4_x64_v4.4.10.manifest.xml");
assertEquals(image.getOperatingSystem().getFamily(), OsFamily.CENTOS); assertEquals(image.getOperatingSystem().getFamily(), OsFamily.CENTOS);
assertEquals(image.getUserMetadata(), ImmutableMap.<String, String> of("owner", "411009282317")); assertEquals(image.getUserMetadata(), ImmutableMap.<String, String> of("owner", "411009282317", "rootDeviceType",
"instance-store"));
assertEquals(image.getVersion(), "4.4.10"); assertEquals(image.getVersion(), "4.4.10");
image = parser.apply(Iterables.get(result, 1)); image = parser.apply(Iterables.get(result, 1));
@ -249,7 +292,8 @@ public class ImageParserTest extends BaseEC2HandlerTest {
assertEquals(image.getOperatingSystem().getDescription(), assertEquals(image.getOperatingSystem().getDescription(),
"411009282317/RightImage_Ubuntu_9.10_x64_v4.5.3_EBS_Alpha"); "411009282317/RightImage_Ubuntu_9.10_x64_v4.5.3_EBS_Alpha");
assertEquals(image.getOperatingSystem().getFamily(), OsFamily.UBUNTU); assertEquals(image.getOperatingSystem().getFamily(), OsFamily.UBUNTU);
assertEquals(image.getUserMetadata(), ImmutableMap.<String, String> of("owner", "411009282317")); assertEquals(image.getUserMetadata(), ImmutableMap.<String, String> of("owner", "411009282317", "rootDeviceType",
"ebs"));
assertEquals(image.getVersion(), "4.5.3_EBS_Alpha"); assertEquals(image.getVersion(), "4.5.3_EBS_Alpha");
} }
@ -261,7 +305,7 @@ public class ImageParserTest extends BaseEC2HandlerTest {
assertEquals(result.size(), 4); assertEquals(result.size(), 4);
ImageParser parser = new ImageParser(new EC2PopulateDefaultLoginCredentialsForImageStrategy(), Suppliers ImageParser parser = new ImageParser(new EC2PopulateDefaultLoginCredentialsForImageStrategy(), Suppliers
.<Set<? extends Location>> ofInstance(ImmutableSet.<Location> of(defaultLocation)), Suppliers .<Set<? extends Location>> ofInstance(ImmutableSet.<Location> of(defaultLocation)), Suppliers
.ofInstance(defaultLocation)); .ofInstance(defaultLocation), "ec2");
org.jclouds.compute.domain.Image image = parser.apply(Iterables.get(result, 0)); org.jclouds.compute.domain.Image image = parser.apply(Iterables.get(result, 0));
@ -276,12 +320,333 @@ public class ImageParserTest extends BaseEC2HandlerTest {
assertEquals(image.getOperatingSystem().getArch(), "paravirtual"); assertEquals(image.getOperatingSystem().getArch(), "paravirtual");
assertEquals(image.getOperatingSystem().getDescription(), "centos-5.3-x86_64/centos.5-3.x86-64.img.manifest.xml"); assertEquals(image.getOperatingSystem().getDescription(), "centos-5.3-x86_64/centos.5-3.x86-64.img.manifest.xml");
assertEquals(image.getOperatingSystem().getFamily(), OsFamily.CENTOS); assertEquals(image.getOperatingSystem().getFamily(), OsFamily.CENTOS);
assertEquals(image.getUserMetadata(), ImmutableMap.<String, String> of("owner", "admin")); assertEquals(image.getUserMetadata(), ImmutableMap.<String, String> of("owner", "admin", "rootDeviceType",
"instance-store"));
assertEquals(image.getVersion(), null); assertEquals(image.getVersion(), null);
// should skip test images }
public void testParseAmznmage() {
InputStream is = getClass().getResourceAsStream("/ec2/amzn_images.xml");
Set<Image> result = parseImages(is);
assertEquals(result.size(), 4);
ImageParser parser = new ImageParser(new EC2PopulateDefaultLoginCredentialsForImageStrategy(), Suppliers
.<Set<? extends Location>> ofInstance(ImmutableSet.<Location> of(defaultLocation)), Suppliers
.ofInstance(defaultLocation), "ec2");
org.jclouds.compute.domain.Image image = parser.apply(Iterables.get(result, 0));
assertEquals(image.getOperatingSystem().is64Bit(), false);
assertEquals(image.getDescription(), "Amazon");
assertEquals(image.getId(), "us-east-1/ami-82e4b5c7");
assertEquals(image.getProviderId(), "ami-82e4b5c7");
assertEquals(image.getLocation(), defaultLocation);
assertEquals(image.getName(), null);
assertEquals(image.getOperatingSystem().getName(), null);
assertEquals(image.getOperatingSystem().getVersion(), "0.9.7-beta");
assertEquals(image.getOperatingSystem().getArch(), "paravirtual");
assertEquals(image.getOperatingSystem().getDescription(), "137112412989/amzn-ami-0.9.7-beta.i386-ebs");
assertEquals(image.getOperatingSystem().getFamily(), OsFamily.AMZN_LINUX);
assertEquals(image.getUserMetadata(), ImmutableMap.<String, String> of("owner", "137112412989", "rootDeviceType",
"ebs"));
assertEquals(image.getVersion(), "0.9.7-beta");
image = parser.apply(Iterables.get(result, 1));
assertEquals(image.getOperatingSystem().is64Bit(), true);
assertEquals(image.getDescription(), "Amazon");
assertEquals(image.getId(), "us-east-1/ami-8ce4b5c9");
assertEquals(image.getProviderId(), "ami-8ce4b5c9");
assertEquals(image.getLocation(), defaultLocation);
assertEquals(image.getName(), null);
assertEquals(image.getOperatingSystem().getName(), null);
assertEquals(image.getOperatingSystem().getVersion(), "0.9.7-beta");
assertEquals(image.getOperatingSystem().getArch(), "paravirtual");
assertEquals(image.getOperatingSystem().getDescription(), "137112412989/amzn-ami-0.9.7-beta.x86_64-ebs");
assertEquals(image.getOperatingSystem().getFamily(), OsFamily.AMZN_LINUX);
assertEquals(image.getUserMetadata(), ImmutableMap.<String, String> of("owner", "137112412989", "rootDeviceType",
"ebs"));
assertEquals(image.getVersion(), "0.9.7-beta");
image = parser.apply(Iterables.get(result, 2));
assertEquals(image.getOperatingSystem().is64Bit(), false);
assertEquals(image.getDescription(), "Amazon Linux AMI i386 S3");
assertEquals(image.getId(), "us-east-1/ami-f0e4b5b5");
assertEquals(image.getProviderId(), "ami-f0e4b5b5");
assertEquals(image.getLocation(), defaultLocation);
assertEquals(image.getName(), null);
assertEquals(image.getOperatingSystem().getName(), null);
assertEquals(image.getOperatingSystem().getVersion(), "0.9.7-beta");
assertEquals(image.getOperatingSystem().getArch(), "paravirtual");
assertEquals(image.getOperatingSystem().getDescription(),
"amzn-ami-us-west-1/amzn-ami-0.9.7-beta.i386.manifest.xml");
assertEquals(image.getOperatingSystem().getFamily(), OsFamily.AMZN_LINUX);
assertEquals(image.getUserMetadata(), ImmutableMap.<String, String> of("owner", "137112412989", "rootDeviceType",
"instance-store"));
assertEquals(image.getVersion(), "0.9.7-beta");
image = parser.apply(Iterables.get(result, 3)); image = parser.apply(Iterables.get(result, 3));
assertEquals(image, null);
assertEquals(image.getOperatingSystem().is64Bit(), true);
assertEquals(image.getDescription(), "Amazon Linux AMI x86_64 S3");
assertEquals(image.getId(), "us-east-1/ami-f2e4b5b7");
assertEquals(image.getProviderId(), "ami-f2e4b5b7");
assertEquals(image.getLocation(), defaultLocation);
assertEquals(image.getName(), null);
assertEquals(image.getOperatingSystem().getName(), null);
assertEquals(image.getOperatingSystem().getVersion(), "0.9.7-beta");
assertEquals(image.getOperatingSystem().getArch(), "paravirtual");
assertEquals(image.getOperatingSystem().getDescription(),
"amzn-ami-us-west-1/amzn-ami-0.9.7-beta.x86_64.manifest.xml");
assertEquals(image.getOperatingSystem().getFamily(), OsFamily.AMZN_LINUX);
assertEquals(image.getUserMetadata(), ImmutableMap.<String, String> of("owner", "137112412989", "rootDeviceType",
"instance-store"));
assertEquals(image.getVersion(), "0.9.7-beta");
}
public void testParseNovaImage() {
InputStream is = getClass().getResourceAsStream("/ec2/nova_images.xml");
Set<Image> result = parseImages(is);
assertEquals(result.size(), 19);
ImageParser parser = new ImageParser(new EC2PopulateDefaultLoginCredentialsForImageStrategy(), Suppliers
.<Set<? extends Location>> ofInstance(ImmutableSet.<Location> of(defaultLocation)), Suppliers
.ofInstance(defaultLocation), "nebula");
org.jclouds.compute.domain.Image image = parser.apply(Iterables.get(result, 0));
assertEquals(image.getOperatingSystem().is64Bit(), true);
assertEquals(image.getDescription(), "nasacms/image.manifest.xml");
assertEquals(image.getId(), "us-east-1/ami-h30p5im0");
assertEquals(image.getProviderId(), "ami-h30p5im0");
assertEquals(image.getLocation(), defaultLocation);
assertEquals(image.getName(), null);
assertEquals(image.getOperatingSystem().getName(), null);
assertEquals(image.getOperatingSystem().getVersion(), "");
assertEquals(image.getOperatingSystem().getArch(), "paravirtual");
assertEquals(image.getOperatingSystem().getDescription(), "nasacms/image.manifest.xml");
assertEquals(image.getOperatingSystem().getFamily(), OsFamily.UBUNTU);
assertEquals(image.getUserMetadata(), ImmutableMap.<String, String> of("owner", "foo", "rootDeviceType",
"instance-store"));
assertEquals(image.getVersion(), null);
assertEquals(parser.apply(Iterables.get(result, 1)), null);
image = parser.apply(Iterables.get(result, 2));
assertEquals(image.getOperatingSystem().is64Bit(), true);
assertEquals(image.getDescription(), "nebula/tiny");
assertEquals(image.getId(), "us-east-1/ami-tiny");
assertEquals(image.getProviderId(), "ami-tiny");
assertEquals(image.getLocation(), defaultLocation);
assertEquals(image.getName(), null);
assertEquals(image.getOperatingSystem().getName(), null);
assertEquals(image.getOperatingSystem().getVersion(), "");
assertEquals(image.getOperatingSystem().getArch(), "paravirtual");
assertEquals(image.getOperatingSystem().getDescription(), "nebula/tiny");
assertEquals(image.getOperatingSystem().getFamily(), OsFamily.UBUNTU);
assertEquals(image.getUserMetadata(), ImmutableMap.<String, String> of("owner", "vishvananda", "rootDeviceType",
"instance-store"));
assertEquals(image.getVersion(), null);
image = parser.apply(Iterables.get(result, 3));
assertEquals(image.getOperatingSystem().is64Bit(), true);
assertEquals(image.getDescription(), "demos/mediawiki");
assertEquals(image.getId(), "us-east-1/ami-630A130F");
assertEquals(image.getProviderId(), "ami-630A130F");
assertEquals(image.getLocation(), defaultLocation);
assertEquals(image.getName(), null);
assertEquals(image.getOperatingSystem().getName(), null);
assertEquals(image.getOperatingSystem().getVersion(), "");
assertEquals(image.getOperatingSystem().getArch(), "paravirtual");
assertEquals(image.getOperatingSystem().getDescription(), "demos/mediawiki");
assertEquals(image.getOperatingSystem().getFamily(), OsFamily.UBUNTU);
assertEquals(image.getUserMetadata(), ImmutableMap.<String, String> of("owner", "admin", "rootDeviceType",
"instance-store"));
assertEquals(image.getVersion(), null);
assertEquals(parser.apply(Iterables.get(result, 4)), null);
assertEquals(parser.apply(Iterables.get(result, 5)), null);
assertEquals(parser.apply(Iterables.get(result, 6)), null);
image = parser.apply(Iterables.get(result, 7));
assertEquals(image.getOperatingSystem().is64Bit(), true);
assertEquals(image.getDescription(), "pinglet/instances");
assertEquals(image.getId(), "us-east-1/ami-pinginst");
assertEquals(image.getProviderId(), "ami-pinginst");
assertEquals(image.getLocation(), defaultLocation);
assertEquals(image.getName(), null);
assertEquals(image.getOperatingSystem().getName(), null);
assertEquals(image.getOperatingSystem().getVersion(), "");
assertEquals(image.getOperatingSystem().getArch(), "paravirtual");
assertEquals(image.getOperatingSystem().getDescription(), "pinglet/instances");
assertEquals(image.getOperatingSystem().getFamily(), OsFamily.UBUNTU);
assertEquals(image.getUserMetadata(), ImmutableMap.<String, String> of("owner", "admin", "rootDeviceType",
"instance-store"));
assertEquals(image.getVersion(), null);
image = parser.apply(Iterables.get(result, 8));
assertEquals(image.getOperatingSystem().is64Bit(), true);
assertEquals(image.getDescription(), "bucket/testbuntu.manifest.xml");
assertEquals(image.getId(), "us-east-1/ami-alqbihe2");
assertEquals(image.getProviderId(), "ami-alqbihe2");
assertEquals(image.getLocation(), defaultLocation);
assertEquals(image.getName(), null);
assertEquals(image.getOperatingSystem().getName(), null);
assertEquals(image.getOperatingSystem().getVersion(), "");
assertEquals(image.getOperatingSystem().getArch(), "paravirtual");
assertEquals(image.getOperatingSystem().getDescription(), "bucket/testbuntu.manifest.xml");
assertEquals(image.getOperatingSystem().getFamily(), OsFamily.UBUNTU);
assertEquals(image.getUserMetadata(), ImmutableMap.<String, String> of("owner", "rkumar2", "rootDeviceType",
"instance-store"));
assertEquals(image.getVersion(), null);
image = parser.apply(Iterables.get(result, 9));
assertEquals(image.getOperatingSystem().is64Bit(), true);
assertEquals(image.getDescription(), "gfortran-bucket/gfortran.manifest.xml");
assertEquals(image.getId(), "us-east-1/ami-i0aemtfp");
assertEquals(image.getProviderId(), "ami-i0aemtfp");
assertEquals(image.getLocation(), defaultLocation);
assertEquals(image.getName(), null);
assertEquals(image.getOperatingSystem().getName(), null);
assertEquals(image.getOperatingSystem().getVersion(), "");
assertEquals(image.getOperatingSystem().getArch(), "paravirtual");
assertEquals(image.getOperatingSystem().getDescription(), "gfortran-bucket/gfortran.manifest.xml");
assertEquals(image.getOperatingSystem().getFamily(), OsFamily.UBUNTU);
assertEquals(image.getUserMetadata(), ImmutableMap.<String, String> of("owner", "ykliu", "rootDeviceType",
"instance-store"));
assertEquals(image.getVersion(), null);
assertEquals(parser.apply(Iterables.get(result, 10)), null);
image = parser.apply(Iterables.get(result, 11));
assertEquals(image.getOperatingSystem().is64Bit(), true);
assertEquals(image.getDescription(), "grinder/grinder-analyzer.manifest.xml");
assertEquals(image.getId(), "us-east-1/ami-2ig7w1bh");
assertEquals(image.getProviderId(), "ami-2ig7w1bh");
assertEquals(image.getLocation(), defaultLocation);
assertEquals(image.getName(), null);
assertEquals(image.getOperatingSystem().getName(), null);
assertEquals(image.getOperatingSystem().getVersion(), "");
assertEquals(image.getOperatingSystem().getArch(), "paravirtual");
assertEquals(image.getOperatingSystem().getDescription(), "grinder/grinder-analyzer.manifest.xml");
assertEquals(image.getOperatingSystem().getFamily(), OsFamily.UBUNTU);
assertEquals(image.getUserMetadata(), ImmutableMap.<String, String> of("owner", "foo", "rootDeviceType",
"instance-store"));
assertEquals(image.getVersion(), null);
assertEquals(parser.apply(Iterables.get(result, 12)), null);
image = parser.apply(Iterables.get(result, 13));
assertEquals(image.getOperatingSystem().is64Bit(), true);
assertEquals(image.getDescription(), "nebula/lucid");
assertEquals(image.getId(), "us-east-1/ami-lucid");
assertEquals(image.getProviderId(), "ami-lucid");
assertEquals(image.getLocation(), defaultLocation);
assertEquals(image.getName(), null);
assertEquals(image.getOperatingSystem().getName(), null);
assertEquals(image.getOperatingSystem().getVersion(), "10.04");
assertEquals(image.getOperatingSystem().getArch(), "paravirtual");
assertEquals(image.getOperatingSystem().getDescription(), "nebula/lucid");
assertEquals(image.getOperatingSystem().getFamily(), OsFamily.UBUNTU);
assertEquals(image.getUserMetadata(), ImmutableMap.<String, String> of("owner", "vishvananda", "rootDeviceType",
"instance-store"));
assertEquals(image.getVersion(), null);
image = parser.apply(Iterables.get(result, 14));
assertEquals(image.getOperatingSystem().is64Bit(), true);
assertEquals(image.getDescription(), "nebula/karmic-large");
assertEquals(image.getId(), "us-east-1/ami-karmiclg");
assertEquals(image.getProviderId(), "ami-karmiclg");
assertEquals(image.getLocation(), defaultLocation);
assertEquals(image.getName(), null);
assertEquals(image.getOperatingSystem().getName(), null);
assertEquals(image.getOperatingSystem().getVersion(), "9.10");
assertEquals(image.getOperatingSystem().getArch(), "paravirtual");
assertEquals(image.getOperatingSystem().getDescription(), "nebula/karmic-large");
assertEquals(image.getOperatingSystem().getFamily(), OsFamily.UBUNTU);
assertEquals(image.getUserMetadata(), ImmutableMap.<String, String> of("owner", "admin", "rootDeviceType",
"instance-store"));
assertEquals(image.getVersion(), null);
image = parser.apply(Iterables.get(result, 15));
assertEquals(image.getOperatingSystem().is64Bit(), true);
assertEquals(image.getDescription(), "jo/qa-grinder.manifest.xml");
assertEquals(image.getId(), "us-east-1/ami-8jen8kdn");
assertEquals(image.getProviderId(), "ami-8jen8kdn");
assertEquals(image.getLocation(), defaultLocation);
assertEquals(image.getName(), null);
assertEquals(image.getOperatingSystem().getName(), null);
assertEquals(image.getOperatingSystem().getVersion(), "");
assertEquals(image.getOperatingSystem().getArch(), "paravirtual");
assertEquals(image.getOperatingSystem().getDescription(), "jo/qa-grinder.manifest.xml");
assertEquals(image.getOperatingSystem().getFamily(), OsFamily.UBUNTU);
assertEquals(image.getUserMetadata(), ImmutableMap.<String, String> of("owner", "jyothi", "rootDeviceType",
"instance-store"));
assertEquals(image.getVersion(), null);
image = parser.apply(Iterables.get(result, 16));
assertEquals(image.getOperatingSystem().is64Bit(), true);
assertEquals(image.getDescription(), "nebula/lucid-large");
assertEquals(image.getId(), "us-east-1/ami-lucidlg");
assertEquals(image.getProviderId(), "ami-lucidlg");
assertEquals(image.getLocation(), defaultLocation);
assertEquals(image.getName(), null);
assertEquals(image.getOperatingSystem().getName(), null);
assertEquals(image.getOperatingSystem().getVersion(), "10.04");
assertEquals(image.getOperatingSystem().getArch(), "paravirtual");
assertEquals(image.getOperatingSystem().getDescription(), "nebula/lucid-large");
assertEquals(image.getOperatingSystem().getFamily(), OsFamily.UBUNTU);
assertEquals(image.getUserMetadata(), ImmutableMap.<String, String> of("owner", "vishvananda", "rootDeviceType",
"instance-store"));
assertEquals(image.getVersion(), null);
image = parser.apply(Iterables.get(result, 17));
assertEquals(image.getOperatingSystem().is64Bit(), true);
assertEquals(image.getDescription(), "demos/wordpress");
assertEquals(image.getId(), "us-east-1/ami-6CD61336");
assertEquals(image.getProviderId(), "ami-6CD61336");
assertEquals(image.getLocation(), defaultLocation);
assertEquals(image.getName(), null);
assertEquals(image.getOperatingSystem().getName(), null);
assertEquals(image.getOperatingSystem().getVersion(), "");
assertEquals(image.getOperatingSystem().getArch(), "paravirtual");
assertEquals(image.getOperatingSystem().getDescription(), "demos/wordpress");
assertEquals(image.getOperatingSystem().getFamily(), OsFamily.UBUNTU);
assertEquals(image.getUserMetadata(), ImmutableMap.<String, String> of("owner", "admin", "rootDeviceType",
"instance-store"));
assertEquals(image.getVersion(), null);
image = parser.apply(Iterables.get(result, 18));
assertEquals(image.getOperatingSystem().is64Bit(), true);
assertEquals(image.getDescription(), "nebula/ubuntu-karmic");
assertEquals(image.getId(), "us-east-1/ami-25CB1213");
assertEquals(image.getProviderId(), "ami-25CB1213");
assertEquals(image.getLocation(), defaultLocation);
assertEquals(image.getName(), null);
assertEquals(image.getOperatingSystem().getName(), null);
assertEquals(image.getOperatingSystem().getVersion(), "9.10");
assertEquals(image.getOperatingSystem().getArch(), "paravirtual");
assertEquals(image.getOperatingSystem().getDescription(), "nebula/ubuntu-karmic");
assertEquals(image.getOperatingSystem().getFamily(), OsFamily.UBUNTU);
assertEquals(image.getUserMetadata(), ImmutableMap.<String, String> of("owner", "admin", "rootDeviceType",
"instance-store"));
assertEquals(image.getVersion(), null);
} }

View File

@ -44,7 +44,7 @@ import com.google.common.collect.ImmutableSet;
@Test(groups = "unit", testName = "ec2.RegionAndIdToImageTest") @Test(groups = "unit", testName = "ec2.RegionAndIdToImageTest")
public class RegionAndIdToImageTest { public class RegionAndIdToImageTest {
@SuppressWarnings("unchecked") @SuppressWarnings({ "unchecked", "rawtypes" })
@Test @Test
public void testApply() { public void testApply() {
@ -76,7 +76,7 @@ public class RegionAndIdToImageTest {
} }
@SuppressWarnings("unchecked") @SuppressWarnings({ "unchecked", "rawtypes" })
@Test @Test
public void testApplyNotFound() { public void testApplyNotFound() {

View File

@ -33,18 +33,27 @@ import java.util.concurrent.ConcurrentMap;
import org.jclouds.aws.domain.Region; import org.jclouds.aws.domain.Region;
import org.jclouds.aws.ec2.EC2Client; import org.jclouds.aws.ec2.EC2Client;
import org.jclouds.aws.ec2.compute.domain.EC2Hardware;
import org.jclouds.aws.ec2.compute.domain.RegionAndName; import org.jclouds.aws.ec2.compute.domain.RegionAndName;
import org.jclouds.aws.ec2.domain.Attachment;
import org.jclouds.aws.ec2.domain.AvailabilityZone; import org.jclouds.aws.ec2.domain.AvailabilityZone;
import org.jclouds.aws.ec2.domain.Image; import org.jclouds.aws.ec2.domain.Image;
import org.jclouds.aws.ec2.domain.InstanceState; import org.jclouds.aws.ec2.domain.InstanceState;
import org.jclouds.aws.ec2.domain.InstanceType; import org.jclouds.aws.ec2.domain.InstanceType;
import org.jclouds.aws.ec2.domain.KeyPair; import org.jclouds.aws.ec2.domain.KeyPair;
import org.jclouds.aws.ec2.domain.RootDeviceType;
import org.jclouds.aws.ec2.domain.RunningInstance; import org.jclouds.aws.ec2.domain.RunningInstance;
import org.jclouds.aws.ec2.functions.RunningInstanceToStorageMappingUnix; import org.jclouds.aws.ec2.domain.RunningInstance.EbsBlockDevice;
import org.jclouds.aws.ec2.services.AMIClient; import org.jclouds.aws.ec2.services.AMIClient;
import org.jclouds.compute.domain.Hardware;
import org.jclouds.compute.domain.NodeMetadata; import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.OperatingSystem; import org.jclouds.compute.domain.OperatingSystem;
import org.jclouds.compute.domain.Processor;
import org.jclouds.compute.domain.Volume;
import org.jclouds.compute.domain.internal.VolumeImpl;
import org.jclouds.compute.strategy.PopulateDefaultLoginCredentialsForImageStrategy; import org.jclouds.compute.strategy.PopulateDefaultLoginCredentialsForImageStrategy;
import org.jclouds.date.DateService;
import org.jclouds.date.internal.SimpleDateFormatDateService;
import org.jclouds.domain.Credentials; import org.jclouds.domain.Credentials;
import org.jclouds.domain.Location; import org.jclouds.domain.Location;
import org.jclouds.domain.LocationScope; import org.jclouds.domain.LocationScope;
@ -53,7 +62,10 @@ import org.testng.annotations.Test;
import com.google.common.base.Supplier; import com.google.common.base.Supplier;
import com.google.common.base.Suppliers; import com.google.common.base.Suppliers;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Maps;
/** /**
* @author Adrian Cole * @author Adrian Cole
@ -69,6 +81,269 @@ public class RunningInstanceToNodeMetadataTest {
} }
DateService dateService = new SimpleDateFormatDateService();
@SuppressWarnings( { "unchecked", "rawtypes" })
@Test
public void testApplyWithEBSWhenBootIsInstanceStoreAndAvailabilityZoneNotFound() throws UnknownHostException {
EC2Client client = createMock(EC2Client.class);
AMIClient amiClient = createMock(AMIClient.class);
expect(client.getAMIServices()).andReturn(amiClient).atLeastOnce();
Map<RegionAndName, KeyPair> credentialsMap = createMock(Map.class);
ConcurrentMap<RegionAndName, org.jclouds.compute.domain.Image> imageMap = createMock(ConcurrentMap.class);
Supplier<Set<? extends Hardware>> hardwares = Suppliers.<Set<? extends Hardware>> ofInstance(ImmutableSet
.<Hardware> of(EC2Hardware.M1_SMALL));
PopulateDefaultLoginCredentialsForImageStrategy credentialProvider = createMock(PopulateDefaultLoginCredentialsForImageStrategy.class);
RunningInstance instance = createMock(RunningInstance.class);
Image image = createMock(Image.class);
expect(instance.getId()).andReturn("i-3d640055").atLeastOnce();
expect(instance.getGroupIds()).andReturn(ImmutableSet.of("default")).atLeastOnce();
expect(instance.getKeyName()).andReturn("jclouds#tag#us-east-1#50").atLeastOnce();
expect(instance.getInstanceState()).andReturn(InstanceState.RUNNING);
Location location = new LocationImpl(LocationScope.ZONE, "us-east-1d", "description", null);
Supplier<Set<? extends Location>> locations = Suppliers.<Set<? extends Location>> ofInstance(ImmutableSet
.<Location> of(location));
org.jclouds.compute.domain.Image jcImage = createMock(org.jclouds.compute.domain.Image.class);
expect(instance.getIpAddress()).andReturn("174.129.1.50");
expect(instance.getPrivateIpAddress()).andReturn("10.202.117.241");
expect(instance.getRegion()).andReturn(Region.US_EAST_1).atLeastOnce();
expect(jcImage.getOperatingSystem()).andReturn(createMock(OperatingSystem.class)).atLeastOnce();
expect(instance.getImageId()).andReturn("ami-1515f07c").atLeastOnce();
expect(imageMap.get(new RegionAndName(Region.US_EAST_1, "ami-1515f07c"))).andReturn(jcImage);
expect(amiClient.describeImagesInRegion(Region.US_EAST_1, imageIds("ami-1515f07c"))).andReturn(
(Set) ImmutableSet.<Image> of(image));
expect(credentialProvider.execute(image)).andReturn(new Credentials("user", "pass"));
expect(credentialsMap.get(new RegionAndName(Region.US_EAST_1, "jclouds#tag#us-east-1#50"))).andReturn(
new KeyPair(Region.US_EAST_1, "jclouds#tag#us-east-1#50", "keyFingerprint", "pass"));
expect(instance.getAvailabilityZone()).andReturn(AvailabilityZone.US_EAST_1A).atLeastOnce();
expect(instance.getInstanceType()).andReturn(InstanceType.M1_SMALL).atLeastOnce();
expect(instance.getEbsBlockDevices()).andReturn(
ImmutableMap.<String, EbsBlockDevice> of("/dev/sdg", new EbsBlockDevice("vol-1f20d376",
Attachment.Status.ATTACHED, dateService.iso8601DateParse("2009-12-11T16:32:46.000Z"), false),
"/dev/sdj", new EbsBlockDevice("vol-c0eb78aa", Attachment.Status.ATTACHED, dateService
.iso8601DateParse("2010-06-17T10:43:28.000Z"), false)));
expect(instance.getRootDeviceType()).andReturn(RootDeviceType.INSTANCE_STORE);
expect(instance.getRootDeviceName()).andReturn(null).atLeastOnce();
replay(imageMap);
replay(client);
replay(amiClient);
replay(credentialsMap);
replay(credentialProvider);
replay(instance);
replay(jcImage);
RunningInstanceToNodeMetadata parser = new RunningInstanceToNodeMetadata(client, credentialsMap,
credentialProvider, imageMap, locations, hardwares);
NodeMetadata metadata = parser.apply(instance);
assertEquals(metadata.getTag(), "NOTAG-i-3d640055");
assertEquals(metadata.getLocation(), null);
assertEquals(metadata.getImageId(), "us-east-1/ami-1515f07c");
assertEquals(metadata.getHardware().getId(), "m1.small");
assertEquals(metadata.getHardware().getName(), "m1.small");
assertEquals(metadata.getHardware().getProviderId(), "m1.small");
assertEquals(metadata.getHardware().getProcessors(), ImmutableList.<Processor> of(new Processor(1.0, 1.0)));
assertEquals(metadata.getHardware().getRam(), 1740);
assertEquals(metadata.getHardware().getVolumes(), ImmutableList.<Volume> of(new VolumeImpl(null,
Volume.Type.LOCAL, 10.0f, "/dev/sda1", true, false),//
new VolumeImpl(null, Volume.Type.LOCAL, 150.0f, "/dev/sda2", false, false),//
new VolumeImpl("vol-1f20d376", Volume.Type.SAN, null, "/dev/sdg", false, true),//
new VolumeImpl("vol-c0eb78aa", Volume.Type.SAN, null, "/dev/sdj", false, true)));
assertEquals(metadata.getCredentials(), new Credentials("user", "pass"));
verify(imageMap);
verify(jcImage);
verify(client);
verify(amiClient);
verify(credentialsMap);
verify(credentialProvider);
verify(instance);
}
@SuppressWarnings( { "unchecked", "rawtypes" })
@Test
public void testApplyForEucalyptusWhereNullAvailabilityZoneIpAddressNoGroups() throws UnknownHostException {
EC2Client client = createMock(EC2Client.class);
AMIClient amiClient = createMock(AMIClient.class);
expect(client.getAMIServices()).andReturn(amiClient).atLeastOnce();
Map<RegionAndName, KeyPair> credentialsMap = createMock(Map.class);
ConcurrentMap<RegionAndName, org.jclouds.compute.domain.Image> imageMap = createMock(ConcurrentMap.class);
Supplier<Set<? extends Hardware>> hardwares = Suppliers.<Set<? extends Hardware>> ofInstance(ImmutableSet
.<Hardware> of(EC2Hardware.M1_SMALL));
PopulateDefaultLoginCredentialsForImageStrategy credentialProvider = createMock(PopulateDefaultLoginCredentialsForImageStrategy.class);
RunningInstance instance = createMock(RunningInstance.class);
Image image = createMock(Image.class);
expect(instance.getId()).andReturn("i-3d640055").atLeastOnce();
expect(instance.getGroupIds()).andReturn(ImmutableSet.<String> of()).atLeastOnce();
expect(instance.getKeyName()).andReturn("nebulatanimislam").atLeastOnce();
expect(instance.getInstanceState()).andReturn(InstanceState.RUNNING);
Location region = new LocationImpl(LocationScope.REGION, "us-east-1", "description", null);
Supplier<Set<? extends Location>> locations = Suppliers.<Set<? extends Location>> ofInstance(ImmutableSet
.<Location> of(region));
org.jclouds.compute.domain.Image jcImage = createMock(org.jclouds.compute.domain.Image.class);
expect(instance.getIpAddress()).andReturn(null);
expect(instance.getPrivateIpAddress()).andReturn("10.202.117.241");
expect(instance.getRegion()).andReturn(Region.US_EAST_1).atLeastOnce();
expect(jcImage.getOperatingSystem()).andReturn(createMock(OperatingSystem.class)).atLeastOnce();
expect(instance.getImageId()).andReturn("ami-1515f07c").atLeastOnce();
expect(imageMap.get(new RegionAndName(Region.US_EAST_1, "ami-1515f07c"))).andReturn(jcImage);
expect(amiClient.describeImagesInRegion(Region.US_EAST_1, imageIds("ami-1515f07c"))).andReturn(
(Set) ImmutableSet.<Image> of(image));
expect(credentialProvider.execute(image)).andReturn(new Credentials("user", "pass"));
expect(credentialsMap.get(new RegionAndName(Region.US_EAST_1, "nebulatanimislam"))).andReturn(null);
expect(instance.getAvailabilityZone()).andReturn(null).atLeastOnce();
expect(instance.getInstanceType()).andReturn(InstanceType.M1_SMALL).atLeastOnce();
expect(instance.getEbsBlockDevices()).andReturn(Maps.<String, EbsBlockDevice> newHashMap());
expect(instance.getRootDeviceType()).andReturn(RootDeviceType.INSTANCE_STORE);
replay(imageMap);
replay(client);
replay(amiClient);
replay(credentialsMap);
replay(credentialProvider);
replay(instance);
replay(jcImage);
RunningInstanceToNodeMetadata parser = new RunningInstanceToNodeMetadata(client, credentialsMap,
credentialProvider, imageMap, locations, hardwares);
NodeMetadata metadata = parser.apply(instance);
assertEquals(metadata.getTag(), "NOTAG-i-3d640055");
assertEquals(metadata.getLocation(), region);
assertEquals(metadata.getImageId(), "us-east-1/ami-1515f07c");
assertEquals(metadata.getHardware().getId(), "m1.small");
assertEquals(metadata.getHardware().getName(), "m1.small");
assertEquals(metadata.getHardware().getProviderId(), "m1.small");
assertEquals(metadata.getHardware().getProcessors(), ImmutableList.<Processor> of(new Processor(1.0, 1.0)));
assertEquals(metadata.getHardware().getRam(), 1740);
assertEquals(metadata.getHardware().getVolumes(), ImmutableList.<Volume> of(new VolumeImpl(null,
Volume.Type.LOCAL, 10.0f, "/dev/sda1", true, false),//
new VolumeImpl(null, Volume.Type.LOCAL, 150.0f, "/dev/sda2", false, false)));
assertEquals(metadata.getCredentials(), new Credentials("user", null));
verify(imageMap);
verify(jcImage);
verify(client);
verify(amiClient);
verify(credentialsMap);
verify(credentialProvider);
verify(instance);
}
@SuppressWarnings( { "unchecked", "rawtypes" })
@Test
public void testApplyForEucalyptusWhereImageNotFound() throws UnknownHostException {
EC2Client client = createMock(EC2Client.class);
AMIClient amiClient = createMock(AMIClient.class);
expect(client.getAMIServices()).andReturn(amiClient).atLeastOnce();
Map<RegionAndName, KeyPair> credentialsMap = createMock(Map.class);
ConcurrentMap<RegionAndName, org.jclouds.compute.domain.Image> imageMap = createMock(ConcurrentMap.class);
Supplier<Set<? extends Hardware>> hardwares = Suppliers.<Set<? extends Hardware>> ofInstance(ImmutableSet
.<Hardware> of(EC2Hardware.M1_SMALL));
PopulateDefaultLoginCredentialsForImageStrategy credentialProvider = createMock(PopulateDefaultLoginCredentialsForImageStrategy.class);
RunningInstance instance = createMock(RunningInstance.class);
expect(instance.getId()).andReturn("i-3d640055").atLeastOnce();
expect(instance.getGroupIds()).andReturn(ImmutableSet.<String> of()).atLeastOnce();
expect(instance.getKeyName()).andReturn("nebulatanimislam").atLeastOnce();
expect(instance.getInstanceState()).andReturn(InstanceState.RUNNING);
Location region = new LocationImpl(LocationScope.REGION, "us-east-1", "description", null);
Supplier<Set<? extends Location>> locations = Suppliers.<Set<? extends Location>> ofInstance(ImmutableSet
.<Location> of(region));
org.jclouds.compute.domain.Image jcImage = createMock(org.jclouds.compute.domain.Image.class);
expect(instance.getIpAddress()).andReturn(null);
expect(instance.getPrivateIpAddress()).andReturn("10.202.117.241");
expect(instance.getRegion()).andReturn(Region.US_EAST_1).atLeastOnce();
expect(jcImage.getOperatingSystem()).andReturn(createMock(OperatingSystem.class)).atLeastOnce();
expect(instance.getImageId()).andReturn("ami-1515f07c").atLeastOnce();
expect(imageMap.get(new RegionAndName(Region.US_EAST_1, "ami-1515f07c"))).andReturn(jcImage);
expect(amiClient.describeImagesInRegion(Region.US_EAST_1, imageIds("ami-1515f07c"))).andReturn(
(Set) ImmutableSet.<Image> of());
expect(credentialProvider.execute(null)).andReturn(new Credentials("root", null));
expect(credentialsMap.get(new RegionAndName(Region.US_EAST_1, "nebulatanimislam"))).andReturn(null);
expect(instance.getAvailabilityZone()).andReturn(null).atLeastOnce();
expect(instance.getInstanceType()).andReturn(InstanceType.M1_SMALL).atLeastOnce();
expect(instance.getEbsBlockDevices()).andReturn(Maps.<String, EbsBlockDevice> newHashMap());
expect(instance.getRootDeviceType()).andReturn(RootDeviceType.INSTANCE_STORE);
replay(imageMap);
replay(client);
replay(amiClient);
replay(credentialsMap);
replay(credentialProvider);
replay(instance);
replay(jcImage);
RunningInstanceToNodeMetadata parser = new RunningInstanceToNodeMetadata(client, credentialsMap,
credentialProvider, imageMap, locations, hardwares);
NodeMetadata metadata = parser.apply(instance);
assertEquals(metadata.getTag(), "NOTAG-i-3d640055");
assertEquals(metadata.getLocation(), region);
assertEquals(metadata.getImageId(), "us-east-1/ami-1515f07c");
assertEquals(metadata.getHardware().getId(), "m1.small");
assertEquals(metadata.getHardware().getName(), "m1.small");
assertEquals(metadata.getHardware().getProviderId(), "m1.small");
assertEquals(metadata.getHardware().getProcessors(), ImmutableList.<Processor> of(new Processor(1.0, 1.0)));
assertEquals(metadata.getHardware().getRam(), 1740);
assertEquals(metadata.getHardware().getVolumes(), ImmutableList.<Volume> of(new VolumeImpl(null,
Volume.Type.LOCAL, 10.0f, "/dev/sda1", true, false),//
new VolumeImpl(null, Volume.Type.LOCAL, 150.0f, "/dev/sda2", false, false)));
assertEquals(metadata.getCredentials(), new Credentials("root", null));
verify(imageMap);
verify(jcImage);
verify(client);
verify(amiClient);
verify(credentialsMap);
verify(credentialProvider);
verify(instance);
}
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@Test @Test
public void testImageNotFoundAndLazyReturnsNull() throws UnknownHostException { public void testImageNotFoundAndLazyReturnsNull() throws UnknownHostException {
@ -83,6 +358,8 @@ public class RunningInstanceToNodeMetadataTest {
Location location = new LocationImpl(LocationScope.ZONE, "us-east-1a", "description", null); Location location = new LocationImpl(LocationScope.ZONE, "us-east-1a", "description", null);
Supplier<Set<? extends Location>> locations = Suppliers.<Set<? extends Location>> ofInstance(ImmutableSet Supplier<Set<? extends Location>> locations = Suppliers.<Set<? extends Location>> ofInstance(ImmutableSet
.<Location> of(location)); .<Location> of(location));
Supplier<Set<? extends Hardware>> hardwares = Suppliers.<Set<? extends Hardware>> ofInstance(ImmutableSet
.<Hardware> of(EC2Hardware.M2_4XLARGE));
PopulateDefaultLoginCredentialsForImageStrategy credentialProvider = createMock(PopulateDefaultLoginCredentialsForImageStrategy.class); PopulateDefaultLoginCredentialsForImageStrategy credentialProvider = createMock(PopulateDefaultLoginCredentialsForImageStrategy.class);
RunningInstance instance = createMock(RunningInstance.class); RunningInstance instance = createMock(RunningInstance.class);
@ -90,9 +367,6 @@ public class RunningInstanceToNodeMetadataTest {
expect(instance.getGroupIds()).andReturn(ImmutableSet.<String> of()).atLeastOnce(); expect(instance.getGroupIds()).andReturn(ImmutableSet.<String> of()).atLeastOnce();
expect(instance.getKeyName()).andReturn(null).atLeastOnce(); expect(instance.getKeyName()).andReturn(null).atLeastOnce();
expect(instance.getInstanceState()).andReturn(InstanceState.RUNNING); expect(instance.getInstanceState()).andReturn(InstanceState.RUNNING);
expect(instance.getVirtualizationType()).andReturn("paravirtual");
expect(instance.getPlacementGroup()).andReturn(null);
expect(instance.getSubnetId()).andReturn(null);
expect(instance.getIpAddress()).andReturn("127.0.0.1"); expect(instance.getIpAddress()).andReturn("127.0.0.1");
expect(instance.getPrivateIpAddress()).andReturn("127.0.0.1"); expect(instance.getPrivateIpAddress()).andReturn("127.0.0.1");
@ -115,7 +389,7 @@ public class RunningInstanceToNodeMetadataTest {
replay(instance); replay(instance);
RunningInstanceToNodeMetadata parser = new RunningInstanceToNodeMetadata(client, credentialsMap, RunningInstanceToNodeMetadata parser = new RunningInstanceToNodeMetadata(client, credentialsMap,
credentialProvider, imageMap, locations, new RunningInstanceToStorageMappingUnix()); credentialProvider, imageMap, locations, hardwares);
NodeMetadata metadata = parser.apply(instance); NodeMetadata metadata = parser.apply(instance);
assertEquals(metadata.getLocation(), locations.get().iterator().next()); assertEquals(metadata.getLocation(), locations.get().iterator().next());
@ -145,6 +419,8 @@ public class RunningInstanceToNodeMetadataTest {
Location location = new LocationImpl(LocationScope.ZONE, "us-east-1a", "description", null); Location location = new LocationImpl(LocationScope.ZONE, "us-east-1a", "description", null);
Supplier<Set<? extends Location>> locations = Suppliers.<Set<? extends Location>> ofInstance(ImmutableSet Supplier<Set<? extends Location>> locations = Suppliers.<Set<? extends Location>> ofInstance(ImmutableSet
.<Location> of(location)); .<Location> of(location));
Supplier<Set<? extends Hardware>> hardwares = Suppliers.<Set<? extends Hardware>> ofInstance(ImmutableSet
.<Hardware> of(EC2Hardware.M2_4XLARGE));
PopulateDefaultLoginCredentialsForImageStrategy credentialProvider = createMock(PopulateDefaultLoginCredentialsForImageStrategy.class); PopulateDefaultLoginCredentialsForImageStrategy credentialProvider = createMock(PopulateDefaultLoginCredentialsForImageStrategy.class);
RunningInstance instance = createMock(RunningInstance.class); RunningInstance instance = createMock(RunningInstance.class);
@ -152,9 +428,6 @@ public class RunningInstanceToNodeMetadataTest {
expect(instance.getGroupIds()).andReturn(ImmutableSet.<String> of()).atLeastOnce(); expect(instance.getGroupIds()).andReturn(ImmutableSet.<String> of()).atLeastOnce();
expect(instance.getKeyName()).andReturn(null).atLeastOnce(); expect(instance.getKeyName()).andReturn(null).atLeastOnce();
expect(instance.getInstanceState()).andReturn(InstanceState.RUNNING); expect(instance.getInstanceState()).andReturn(InstanceState.RUNNING);
expect(instance.getVirtualizationType()).andReturn("paravirtual");
expect(instance.getPlacementGroup()).andReturn(null);
expect(instance.getSubnetId()).andReturn(null);
expect(instance.getIpAddress()).andReturn("127.0.0.1"); expect(instance.getIpAddress()).andReturn("127.0.0.1");
expect(instance.getPrivateIpAddress()).andReturn("127.0.0.1"); expect(instance.getPrivateIpAddress()).andReturn("127.0.0.1");
@ -178,7 +451,7 @@ public class RunningInstanceToNodeMetadataTest {
replay(instance); replay(instance);
RunningInstanceToNodeMetadata parser = new RunningInstanceToNodeMetadata(client, credentialsMap, RunningInstanceToNodeMetadata parser = new RunningInstanceToNodeMetadata(client, credentialsMap,
credentialProvider, imageMap, locations, new RunningInstanceToStorageMappingUnix()); credentialProvider, imageMap, locations, hardwares);
NodeMetadata metadata = parser.apply(instance); NodeMetadata metadata = parser.apply(instance);
assertEquals(metadata.getLocation(), locations.get().iterator().next()); assertEquals(metadata.getLocation(), locations.get().iterator().next());
@ -208,6 +481,8 @@ public class RunningInstanceToNodeMetadataTest {
Location location = new LocationImpl(LocationScope.ZONE, "us-east-1a", "description", null); Location location = new LocationImpl(LocationScope.ZONE, "us-east-1a", "description", null);
Supplier<Set<? extends Location>> locations = Suppliers.<Set<? extends Location>> ofInstance(ImmutableSet Supplier<Set<? extends Location>> locations = Suppliers.<Set<? extends Location>> ofInstance(ImmutableSet
.<Location> of(location)); .<Location> of(location));
Supplier<Set<? extends Hardware>> hardwares = Suppliers.<Set<? extends Hardware>> ofInstance(ImmutableSet
.<Hardware> of(EC2Hardware.M2_4XLARGE));
PopulateDefaultLoginCredentialsForImageStrategy credentialProvider = createMock(PopulateDefaultLoginCredentialsForImageStrategy.class); PopulateDefaultLoginCredentialsForImageStrategy credentialProvider = createMock(PopulateDefaultLoginCredentialsForImageStrategy.class);
RunningInstance instance = createMock(RunningInstance.class); RunningInstance instance = createMock(RunningInstance.class);
@ -215,9 +490,6 @@ public class RunningInstanceToNodeMetadataTest {
expect(instance.getGroupIds()).andReturn(ImmutableSet.<String> of()).atLeastOnce(); expect(instance.getGroupIds()).andReturn(ImmutableSet.<String> of()).atLeastOnce();
expect(instance.getKeyName()).andReturn(null).atLeastOnce(); expect(instance.getKeyName()).andReturn(null).atLeastOnce();
expect(instance.getInstanceState()).andReturn(InstanceState.RUNNING); expect(instance.getInstanceState()).andReturn(InstanceState.RUNNING);
expect(instance.getVirtualizationType()).andReturn("paravirtual");
expect(instance.getPlacementGroup()).andReturn(null);
expect(instance.getSubnetId()).andReturn(null);
expect(instance.getIpAddress()).andReturn("127.0.0.1"); expect(instance.getIpAddress()).andReturn("127.0.0.1");
expect(instance.getPrivateIpAddress()).andReturn("127.0.0.1"); expect(instance.getPrivateIpAddress()).andReturn("127.0.0.1");
@ -245,7 +517,7 @@ public class RunningInstanceToNodeMetadataTest {
replay(instance); replay(instance);
RunningInstanceToNodeMetadata parser = new RunningInstanceToNodeMetadata(client, credentialsMap, RunningInstanceToNodeMetadata parser = new RunningInstanceToNodeMetadata(client, credentialsMap,
credentialProvider, imageMap, locations, new RunningInstanceToStorageMappingUnix()); credentialProvider, imageMap, locations, hardwares);
NodeMetadata metadata = parser.apply(instance); NodeMetadata metadata = parser.apply(instance);
assertEquals(metadata.getLocation(), locations.get().iterator().next()); assertEquals(metadata.getLocation(), locations.get().iterator().next());
@ -276,6 +548,8 @@ public class RunningInstanceToNodeMetadataTest {
Location location = new LocationImpl(LocationScope.ZONE, "us-east-1a", "description", null); Location location = new LocationImpl(LocationScope.ZONE, "us-east-1a", "description", null);
Supplier<Set<? extends Location>> locations = Suppliers.<Set<? extends Location>> ofInstance(ImmutableSet Supplier<Set<? extends Location>> locations = Suppliers.<Set<? extends Location>> ofInstance(ImmutableSet
.<Location> of(location)); .<Location> of(location));
Supplier<Set<? extends Hardware>> hardwares = Suppliers.<Set<? extends Hardware>> ofInstance(ImmutableSet
.<Hardware> of(EC2Hardware.M2_4XLARGE));
PopulateDefaultLoginCredentialsForImageStrategy credentialProvider = createMock(PopulateDefaultLoginCredentialsForImageStrategy.class); PopulateDefaultLoginCredentialsForImageStrategy credentialProvider = createMock(PopulateDefaultLoginCredentialsForImageStrategy.class);
RunningInstance instance = createMock(RunningInstance.class); RunningInstance instance = createMock(RunningInstance.class);
@ -284,9 +558,6 @@ public class RunningInstanceToNodeMetadataTest {
expect(instance.getGroupIds()).andReturn(ImmutableSet.<String> of()).atLeastOnce(); expect(instance.getGroupIds()).andReturn(ImmutableSet.<String> of()).atLeastOnce();
expect(instance.getKeyName()).andReturn(null).atLeastOnce(); expect(instance.getKeyName()).andReturn(null).atLeastOnce();
expect(instance.getInstanceState()).andReturn(InstanceState.RUNNING); expect(instance.getInstanceState()).andReturn(InstanceState.RUNNING);
expect(instance.getVirtualizationType()).andReturn("paravirtual");
expect(instance.getPlacementGroup()).andReturn(null);
expect(instance.getSubnetId()).andReturn(null);
expect(instance.getIpAddress()).andReturn("127.0.0.1"); expect(instance.getIpAddress()).andReturn("127.0.0.1");
expect(instance.getPrivateIpAddress()).andReturn("127.0.0.1"); expect(instance.getPrivateIpAddress()).andReturn("127.0.0.1");
@ -309,7 +580,7 @@ public class RunningInstanceToNodeMetadataTest {
replay(instance); replay(instance);
RunningInstanceToNodeMetadata parser = new RunningInstanceToNodeMetadata(client, credentialsMap, RunningInstanceToNodeMetadata parser = new RunningInstanceToNodeMetadata(client, credentialsMap,
credentialProvider, imageMap, locations, new RunningInstanceToStorageMappingUnix()); credentialProvider, imageMap, locations, hardwares);
NodeMetadata metadata = parser.apply(instance); NodeMetadata metadata = parser.apply(instance);
assertEquals(metadata.getLocation(), locations.get().iterator().next()); assertEquals(metadata.getLocation(), locations.get().iterator().next());
@ -338,6 +609,8 @@ public class RunningInstanceToNodeMetadataTest {
Location location = new LocationImpl(LocationScope.ZONE, "us-east-1a", "description", null); Location location = new LocationImpl(LocationScope.ZONE, "us-east-1a", "description", null);
Supplier<Set<? extends Location>> locations = Suppliers.<Set<? extends Location>> ofInstance(ImmutableSet Supplier<Set<? extends Location>> locations = Suppliers.<Set<? extends Location>> ofInstance(ImmutableSet
.<Location> of(location)); .<Location> of(location));
Supplier<Set<? extends Hardware>> hardwares = Suppliers.<Set<? extends Hardware>> ofInstance(ImmutableSet
.<Hardware> of(EC2Hardware.M2_4XLARGE));
PopulateDefaultLoginCredentialsForImageStrategy credentialProvider = createMock(PopulateDefaultLoginCredentialsForImageStrategy.class); PopulateDefaultLoginCredentialsForImageStrategy credentialProvider = createMock(PopulateDefaultLoginCredentialsForImageStrategy.class);
RunningInstance instance = createMock(RunningInstance.class); RunningInstance instance = createMock(RunningInstance.class);
@ -346,9 +619,6 @@ public class RunningInstanceToNodeMetadataTest {
expect(instance.getGroupIds()).andReturn(ImmutableSet.of("jclouds#tag#us-east-1")).atLeastOnce(); expect(instance.getGroupIds()).andReturn(ImmutableSet.of("jclouds#tag#us-east-1")).atLeastOnce();
expect(instance.getKeyName()).andReturn(null).atLeastOnce(); expect(instance.getKeyName()).andReturn(null).atLeastOnce();
expect(instance.getInstanceState()).andReturn(InstanceState.RUNNING); expect(instance.getInstanceState()).andReturn(InstanceState.RUNNING);
expect(instance.getVirtualizationType()).andReturn("paravirtual");
expect(instance.getPlacementGroup()).andReturn(null);
expect(instance.getSubnetId()).andReturn(null);
expect(instance.getIpAddress()).andReturn("127.0.0.1"); expect(instance.getIpAddress()).andReturn("127.0.0.1");
expect(instance.getPrivateIpAddress()).andReturn("127.0.0.1"); expect(instance.getPrivateIpAddress()).andReturn("127.0.0.1");
@ -371,7 +641,7 @@ public class RunningInstanceToNodeMetadataTest {
replay(instance); replay(instance);
RunningInstanceToNodeMetadata parser = new RunningInstanceToNodeMetadata(client, credentialsMap, RunningInstanceToNodeMetadata parser = new RunningInstanceToNodeMetadata(client, credentialsMap,
credentialProvider, imageMap, locations, new RunningInstanceToStorageMappingUnix()); credentialProvider, imageMap, locations, hardwares);
NodeMetadata metadata = parser.apply(instance); NodeMetadata metadata = parser.apply(instance);
assertEquals(metadata.getLocation(), locations.get().iterator().next()); assertEquals(metadata.getLocation(), locations.get().iterator().next());
@ -388,7 +658,7 @@ public class RunningInstanceToNodeMetadataTest {
verify(instance); verify(instance);
} }
@SuppressWarnings("unchecked") @SuppressWarnings( { "unchecked", "rawtypes" })
@Test @Test
public void testApplyWithKeyPairCreatesTagOfParsedSecurityGroupAndCredentialsBasedOnIt() throws UnknownHostException { public void testApplyWithKeyPairCreatesTagOfParsedSecurityGroupAndCredentialsBasedOnIt() throws UnknownHostException {
EC2Client client = createMock(EC2Client.class); EC2Client client = createMock(EC2Client.class);
@ -396,7 +666,8 @@ public class RunningInstanceToNodeMetadataTest {
expect(client.getAMIServices()).andReturn(amiClient).atLeastOnce(); expect(client.getAMIServices()).andReturn(amiClient).atLeastOnce();
Map<RegionAndName, KeyPair> credentialsMap = createMock(Map.class); Map<RegionAndName, KeyPair> credentialsMap = createMock(Map.class);
ConcurrentMap<RegionAndName, org.jclouds.compute.domain.Image> imageMap = createMock(ConcurrentMap.class); ConcurrentMap<RegionAndName, org.jclouds.compute.domain.Image> imageMap = createMock(ConcurrentMap.class);
Supplier<Set<? extends Hardware>> hardwares = Suppliers.<Set<? extends Hardware>> ofInstance(ImmutableSet
.<Hardware> of(EC2Hardware.M2_4XLARGE));
PopulateDefaultLoginCredentialsForImageStrategy credentialProvider = createMock(PopulateDefaultLoginCredentialsForImageStrategy.class); PopulateDefaultLoginCredentialsForImageStrategy credentialProvider = createMock(PopulateDefaultLoginCredentialsForImageStrategy.class);
RunningInstance instance = createMock(RunningInstance.class); RunningInstance instance = createMock(RunningInstance.class);
Image image = createMock(Image.class); Image image = createMock(Image.class);
@ -405,9 +676,6 @@ public class RunningInstanceToNodeMetadataTest {
expect(instance.getGroupIds()).andReturn(ImmutableSet.of("jclouds#tag#us-east-1")).atLeastOnce(); expect(instance.getGroupIds()).andReturn(ImmutableSet.of("jclouds#tag#us-east-1")).atLeastOnce();
expect(instance.getKeyName()).andReturn("jclouds#tag#us-east-1#50").atLeastOnce(); expect(instance.getKeyName()).andReturn("jclouds#tag#us-east-1#50").atLeastOnce();
expect(instance.getInstanceState()).andReturn(InstanceState.RUNNING); expect(instance.getInstanceState()).andReturn(InstanceState.RUNNING);
expect(instance.getVirtualizationType()).andReturn("paravirtual");
expect(instance.getPlacementGroup()).andReturn(null);
expect(instance.getSubnetId()).andReturn(null);
Location location = new LocationImpl(LocationScope.ZONE, "us-east-1a", "description", null); Location location = new LocationImpl(LocationScope.ZONE, "us-east-1a", "description", null);
Supplier<Set<? extends Location>> locations = Suppliers.<Set<? extends Location>> ofInstance(ImmutableSet Supplier<Set<? extends Location>> locations = Suppliers.<Set<? extends Location>> ofInstance(ImmutableSet
@ -445,7 +713,7 @@ public class RunningInstanceToNodeMetadataTest {
replay(jcImage); replay(jcImage);
RunningInstanceToNodeMetadata parser = new RunningInstanceToNodeMetadata(client, credentialsMap, RunningInstanceToNodeMetadata parser = new RunningInstanceToNodeMetadata(client, credentialsMap,
credentialProvider, imageMap, locations, new RunningInstanceToStorageMappingUnix()); credentialProvider, imageMap, locations, hardwares);
NodeMetadata metadata = parser.apply(instance); NodeMetadata metadata = parser.apply(instance);
assertEquals(metadata.getTag(), "tag"); assertEquals(metadata.getTag(), "tag");
@ -464,7 +732,7 @@ public class RunningInstanceToNodeMetadataTest {
} }
@SuppressWarnings("unchecked") @SuppressWarnings( { "unchecked", "rawtypes" })
@Test @Test
public void testApplyWithTwoSecurityGroups() throws UnknownHostException { public void testApplyWithTwoSecurityGroups() throws UnknownHostException {
EC2Client client = createMock(EC2Client.class); EC2Client client = createMock(EC2Client.class);
@ -472,7 +740,8 @@ public class RunningInstanceToNodeMetadataTest {
expect(client.getAMIServices()).andReturn(amiClient).atLeastOnce(); expect(client.getAMIServices()).andReturn(amiClient).atLeastOnce();
Map<RegionAndName, KeyPair> credentialsMap = createMock(Map.class); Map<RegionAndName, KeyPair> credentialsMap = createMock(Map.class);
ConcurrentMap<RegionAndName, org.jclouds.compute.domain.Image> imageMap = createMock(ConcurrentMap.class); ConcurrentMap<RegionAndName, org.jclouds.compute.domain.Image> imageMap = createMock(ConcurrentMap.class);
Supplier<Set<? extends Hardware>> hardwares = Suppliers.<Set<? extends Hardware>> ofInstance(ImmutableSet
.<Hardware> of(EC2Hardware.M2_4XLARGE));
PopulateDefaultLoginCredentialsForImageStrategy credentialProvider = createMock(PopulateDefaultLoginCredentialsForImageStrategy.class); PopulateDefaultLoginCredentialsForImageStrategy credentialProvider = createMock(PopulateDefaultLoginCredentialsForImageStrategy.class);
RunningInstance instance = createMock(RunningInstance.class); RunningInstance instance = createMock(RunningInstance.class);
Image image = createMock(Image.class); Image image = createMock(Image.class);
@ -481,9 +750,6 @@ public class RunningInstanceToNodeMetadataTest {
expect(instance.getGroupIds()).andReturn(ImmutableSet.of("jclouds1", "jclouds2")).atLeastOnce(); expect(instance.getGroupIds()).andReturn(ImmutableSet.of("jclouds1", "jclouds2")).atLeastOnce();
expect(instance.getKeyName()).andReturn("jclouds#tag#us-east-1#50").atLeastOnce(); expect(instance.getKeyName()).andReturn("jclouds#tag#us-east-1#50").atLeastOnce();
expect(instance.getInstanceState()).andReturn(InstanceState.RUNNING); expect(instance.getInstanceState()).andReturn(InstanceState.RUNNING);
expect(instance.getVirtualizationType()).andReturn("paravirtual");
expect(instance.getPlacementGroup()).andReturn(null);
expect(instance.getSubnetId()).andReturn(null);
Location location = new LocationImpl(LocationScope.ZONE, "us-east-1a", "description", null); Location location = new LocationImpl(LocationScope.ZONE, "us-east-1a", "description", null);
Supplier<Set<? extends Location>> locations = Suppliers.<Set<? extends Location>> ofInstance(ImmutableSet Supplier<Set<? extends Location>> locations = Suppliers.<Set<? extends Location>> ofInstance(ImmutableSet
@ -521,7 +787,7 @@ public class RunningInstanceToNodeMetadataTest {
replay(jcImage); replay(jcImage);
RunningInstanceToNodeMetadata parser = new RunningInstanceToNodeMetadata(client, credentialsMap, RunningInstanceToNodeMetadata parser = new RunningInstanceToNodeMetadata(client, credentialsMap,
credentialProvider, imageMap, locations, new RunningInstanceToStorageMappingUnix()); credentialProvider, imageMap, locations, hardwares);
NodeMetadata metadata = parser.apply(instance); NodeMetadata metadata = parser.apply(instance);

View File

@ -33,11 +33,13 @@ import javax.inject.Provider;
import org.jclouds.aws.ec2.compute.domain.RegionAndName; import org.jclouds.aws.ec2.compute.domain.RegionAndName;
import org.jclouds.aws.ec2.compute.options.EC2TemplateOptions; import org.jclouds.aws.ec2.compute.options.EC2TemplateOptions;
import org.jclouds.compute.domain.Hardware;
import org.jclouds.compute.domain.Image; import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.OperatingSystem; import org.jclouds.compute.domain.OperatingSystem;
import org.jclouds.compute.domain.Size; import org.jclouds.compute.domain.Processor;
import org.jclouds.compute.domain.TemplateBuilder; import org.jclouds.compute.domain.TemplateBuilder;
import org.jclouds.compute.domain.internal.SizeImpl; import org.jclouds.compute.domain.Volume;
import org.jclouds.compute.domain.internal.HardwareImpl;
import org.jclouds.compute.domain.internal.TemplateBuilderImpl; import org.jclouds.compute.domain.internal.TemplateBuilderImpl;
import org.jclouds.compute.domain.internal.TemplateBuilderImplTest; import org.jclouds.compute.domain.internal.TemplateBuilderImplTest;
import org.jclouds.compute.options.TemplateOptions; import org.jclouds.compute.options.TemplateOptions;
@ -50,6 +52,7 @@ import org.testng.annotations.Test;
import com.google.common.base.Function; import com.google.common.base.Function;
import com.google.common.base.Supplier; import com.google.common.base.Supplier;
import com.google.common.base.Suppliers; import com.google.common.base.Suppliers;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import com.google.common.collect.MapMaker; import com.google.common.collect.MapMaker;
@ -70,8 +73,8 @@ public class EC2TemplateBuilderImplTest extends TemplateBuilderImplTest {
@Override @Override
protected EC2TemplateBuilderImpl createTemplateBuilder(final Image knownImage, protected EC2TemplateBuilderImpl createTemplateBuilder(final Image knownImage,
Supplier<Set<? extends Location>> locations, Supplier<Set<? extends Image>> images, Supplier<Set<? extends Location>> locations, Supplier<Set<? extends Image>> images,
Supplier<Set<? extends Size>> sizes, Location defaultLocation, Provider<TemplateOptions> optionsProvider, Supplier<Set<? extends Hardware>> sizes, Location defaultLocation,
Provider<TemplateBuilder> templateBuilderProvider) { Provider<TemplateOptions> optionsProvider, Provider<TemplateBuilder> templateBuilderProvider) {
final RegionAndName knownRegionAndName = new RegionAndName("region", "ami"); final RegionAndName knownRegionAndName = new RegionAndName("region", "ami");
ConcurrentMap<RegionAndName, Image> imageMap = new MapMaker() ConcurrentMap<RegionAndName, Image> imageMap = new MapMaker()
@ -94,10 +97,12 @@ public class EC2TemplateBuilderImplTest extends TemplateBuilderImplTest {
Supplier<Set<? extends Location>> locations = Suppliers.<Set<? extends Location>> ofInstance(ImmutableSet Supplier<Set<? extends Location>> locations = Suppliers.<Set<? extends Location>> ofInstance(ImmutableSet
.<Location> of(location)); .<Location> of(location));
Supplier<Set<? extends Image>> images = Suppliers.<Set<? extends Image>> ofInstance(Sets.<Image> newLinkedHashSet()); Supplier<Set<? extends Image>> images = Suppliers.<Set<? extends Image>> ofInstance(Sets
Supplier<Set<? extends Size>> sizes = Suppliers.<Set<? extends Size>> ofInstance(ImmutableSet .<Image> newLinkedHashSet());
.<Size> of(new SizeImpl("1", "1", "region/1", location, null, ImmutableMap.<String, String> of(), 1, 1, Supplier<Set<? extends Hardware>> sizes = Suppliers.<Set<? extends Hardware>> ofInstance(ImmutableSet
1, ImagePredicates.any()))); .<Hardware> of(new HardwareImpl("1", "1", "region/1", location, null,
ImmutableMap.<String, String> of(), ImmutableList.of(new Processor(1, 1.0)), 1, ImmutableList
.<Volume> of(), ImagePredicates.any())));
Provider<TemplateOptions> optionsProvider = createMock(Provider.class); Provider<TemplateOptions> optionsProvider = createMock(Provider.class);
Provider<TemplateBuilder> templateBuilderProvider = createMock(Provider.class); Provider<TemplateBuilder> templateBuilderProvider = createMock(Provider.class);
@ -148,9 +153,10 @@ public class EC2TemplateBuilderImplTest extends TemplateBuilderImplTest {
Supplier<Set<? extends Location>> locations = Suppliers.<Set<? extends Location>> ofInstance(ImmutableSet Supplier<Set<? extends Location>> locations = Suppliers.<Set<? extends Location>> ofInstance(ImmutableSet
.<Location> of(location)); .<Location> of(location));
Supplier<Set<? extends Image>> images = Suppliers.<Set<? extends Image>> ofInstance(ImmutableSet.<Image> of()); Supplier<Set<? extends Image>> images = Suppliers.<Set<? extends Image>> ofInstance(ImmutableSet.<Image> of());
Supplier<Set<? extends Size>> sizes = Suppliers.<Set<? extends Size>> ofInstance(ImmutableSet Supplier<Set<? extends Hardware>> sizes = Suppliers.<Set<? extends Hardware>> ofInstance(ImmutableSet
.<Size> of(new SizeImpl("1", "1", "region/1", location, null, ImmutableMap.<String, String> of(), 1, 1, .<Hardware> of(new HardwareImpl("1", "1", "region/1", location, null,
1, ImagePredicates.any()))); ImmutableMap.<String, String> of(), ImmutableList.of(new Processor(1, 1.0)), 1, ImmutableList
.<Volume> of(), ImagePredicates.any())));
Provider<TemplateOptions> optionsProvider = createMock(Provider.class); Provider<TemplateOptions> optionsProvider = createMock(Provider.class);
Provider<TemplateBuilder> templateBuilderProvider = createMock(Provider.class); Provider<TemplateBuilder> templateBuilderProvider = createMock(Provider.class);
@ -186,9 +192,10 @@ public class EC2TemplateBuilderImplTest extends TemplateBuilderImplTest {
Supplier<Set<? extends Location>> locations = Suppliers.<Set<? extends Location>> ofInstance(ImmutableSet Supplier<Set<? extends Location>> locations = Suppliers.<Set<? extends Location>> ofInstance(ImmutableSet
.<Location> of(location)); .<Location> of(location));
Supplier<Set<? extends Image>> images = Suppliers.<Set<? extends Image>> ofInstance(ImmutableSet.<Image> of()); Supplier<Set<? extends Image>> images = Suppliers.<Set<? extends Image>> ofInstance(ImmutableSet.<Image> of());
Supplier<Set<? extends Size>> sizes = Suppliers.<Set<? extends Size>> ofInstance(ImmutableSet Supplier<Set<? extends Hardware>> sizes = Suppliers.<Set<? extends Hardware>> ofInstance(ImmutableSet
.<Size> of(new SizeImpl("1", "1", "region/1", location, null, ImmutableMap.<String, String> of(), 1, 1, .<Hardware> of(new HardwareImpl("1", "1", "region/1", location, null,
1, ImagePredicates.any()))); ImmutableMap.<String, String> of(), ImmutableList.of(new Processor(1, 1.0)), 1, ImmutableList
.<Volume> of(), ImagePredicates.any())));
Location defaultLocation = createMock(Location.class); Location defaultLocation = createMock(Location.class);
Provider<TemplateOptions> optionsProvider = createMock(Provider.class); Provider<TemplateOptions> optionsProvider = createMock(Provider.class);

View File

@ -31,7 +31,7 @@ import java.util.Set;
import org.jclouds.aws.domain.Region; import org.jclouds.aws.domain.Region;
import org.jclouds.aws.ec2.compute.EC2ComputeServiceTest; import org.jclouds.aws.ec2.compute.EC2ComputeServiceTest;
import org.jclouds.aws.ec2.compute.domain.EC2Size; import org.jclouds.aws.ec2.compute.domain.EC2Hardware;
import org.jclouds.aws.ec2.compute.domain.RegionAndName; import org.jclouds.aws.ec2.compute.domain.RegionAndName;
import org.jclouds.aws.ec2.compute.domain.RegionNameAndIngressRules; import org.jclouds.aws.ec2.compute.domain.RegionNameAndIngressRules;
import org.jclouds.aws.ec2.compute.functions.CreatePlacementGroupIfNeeded; import org.jclouds.aws.ec2.compute.functions.CreatePlacementGroupIfNeeded;
@ -58,7 +58,7 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT
// setup constants // setup constants
String region = Region.AP_SOUTHEAST_1; String region = Region.AP_SOUTHEAST_1;
String tag = "tag"; String tag = "tag";
EC2Size size = EC2Size.M1_SMALL; EC2Hardware size = EC2Hardware.M1_SMALL;
String systemGeneratedKeyPairName = "systemGeneratedKeyPair"; String systemGeneratedKeyPairName = "systemGeneratedKeyPair";
String generatedGroup = "group"; String generatedGroup = "group";
Set<String> generatedGroups = ImmutableSet.of(generatedGroup); Set<String> generatedGroups = ImmutableSet.of(generatedGroup);
@ -80,7 +80,7 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT
Template template = createMock(Template.class); Template template = createMock(Template.class);
// setup expectations // setup expectations
expect(template.getSize()).andReturn(size).atLeastOnce(); expect(template.getHardware()).andReturn(size).atLeastOnce();
expect(template.getOptions()).andReturn(options).atLeastOnce(); expect(template.getOptions()).andReturn(options).atLeastOnce();
expect(strategy.createNewKeyPairUnlessUserSpecifiedOtherwise(region, tag, options)).andReturn( expect(strategy.createNewKeyPairUnlessUserSpecifiedOtherwise(region, tag, options)).andReturn(
systemGeneratedKeyPairName); systemGeneratedKeyPairName);
@ -112,7 +112,7 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT
// setup constants // setup constants
String region = Region.US_EAST_1; String region = Region.US_EAST_1;
String tag = "tag"; String tag = "tag";
EC2Size size = EC2ComputeServiceTest.CC1_4XLARGE; EC2Hardware size = EC2ComputeServiceTest.CC1_4XLARGE;
String systemGeneratedKeyPairName = "systemGeneratedKeyPair"; String systemGeneratedKeyPairName = "systemGeneratedKeyPair";
String generatedGroup = "group"; String generatedGroup = "group";
Set<String> generatedGroups = ImmutableSet.of(generatedGroup); Set<String> generatedGroups = ImmutableSet.of(generatedGroup);
@ -134,7 +134,7 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT
Template template = createMock(Template.class); Template template = createMock(Template.class);
// setup expectations // setup expectations
expect(template.getSize()).andReturn(size).atLeastOnce(); expect(template.getHardware()).andReturn(size).atLeastOnce();
expect(template.getOptions()).andReturn(options).atLeastOnce(); expect(template.getOptions()).andReturn(options).atLeastOnce();
expect(strategy.createNewKeyPairUnlessUserSpecifiedOtherwise(region, tag, options)).andReturn( expect(strategy.createNewKeyPairUnlessUserSpecifiedOtherwise(region, tag, options)).andReturn(
systemGeneratedKeyPairName); systemGeneratedKeyPairName);
@ -168,7 +168,7 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT
// setup constants // setup constants
String region = Region.US_EAST_1; String region = Region.US_EAST_1;
String tag = "tag"; String tag = "tag";
EC2Size size = EC2ComputeServiceTest.CC1_4XLARGE; EC2Hardware size = EC2ComputeServiceTest.CC1_4XLARGE;
String systemGeneratedKeyPairName = "systemGeneratedKeyPair"; String systemGeneratedKeyPairName = "systemGeneratedKeyPair";
String generatedGroup = "group"; String generatedGroup = "group";
Set<String> generatedGroups = ImmutableSet.of(generatedGroup); Set<String> generatedGroups = ImmutableSet.of(generatedGroup);
@ -190,7 +190,7 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT
Template template = createMock(Template.class); Template template = createMock(Template.class);
// setup expectations // setup expectations
expect(template.getSize()).andReturn(size).atLeastOnce(); expect(template.getHardware()).andReturn(size).atLeastOnce();
expect(template.getOptions()).andReturn(options).atLeastOnce(); expect(template.getOptions()).andReturn(options).atLeastOnce();
expect(strategy.createNewKeyPairUnlessUserSpecifiedOtherwise(region, tag, options)).andReturn( expect(strategy.createNewKeyPairUnlessUserSpecifiedOtherwise(region, tag, options)).andReturn(
systemGeneratedKeyPairName); systemGeneratedKeyPairName);
@ -224,7 +224,7 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT
// setup constants // setup constants
String region = Region.AP_SOUTHEAST_1; String region = Region.AP_SOUTHEAST_1;
String tag = "tag"; String tag = "tag";
EC2Size size = EC2Size.M1_SMALL; EC2Hardware size = EC2Hardware.M1_SMALL;
String systemGeneratedKeyPairName = "systemGeneratedKeyPair"; String systemGeneratedKeyPairName = "systemGeneratedKeyPair";
// create mocks // create mocks
@ -244,7 +244,7 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT
Template template = createMock(Template.class); Template template = createMock(Template.class);
// setup expectations // setup expectations
expect(template.getSize()).andReturn(size).atLeastOnce(); expect(template.getHardware()).andReturn(size).atLeastOnce();
expect(template.getOptions()).andReturn(options).atLeastOnce(); expect(template.getOptions()).andReturn(options).atLeastOnce();
expect(strategy.createNewKeyPairUnlessUserSpecifiedOtherwise(region, tag, options)).andReturn( expect(strategy.createNewKeyPairUnlessUserSpecifiedOtherwise(region, tag, options)).andReturn(
systemGeneratedKeyPairName); systemGeneratedKeyPairName);

View File

@ -32,7 +32,7 @@ import java.util.Set;
import org.easymock.IArgumentMatcher; import org.easymock.IArgumentMatcher;
import org.jclouds.aws.domain.Region; import org.jclouds.aws.domain.Region;
import org.jclouds.aws.ec2.EC2Client; import org.jclouds.aws.ec2.EC2Client;
import org.jclouds.aws.ec2.compute.domain.EC2Size; import org.jclouds.aws.ec2.compute.domain.EC2Hardware;
import org.jclouds.aws.ec2.compute.functions.RunningInstanceToNodeMetadata; import org.jclouds.aws.ec2.compute.functions.RunningInstanceToNodeMetadata;
import org.jclouds.aws.ec2.compute.options.EC2TemplateOptions; import org.jclouds.aws.ec2.compute.options.EC2TemplateOptions;
import org.jclouds.aws.ec2.domain.AvailabilityZone; import org.jclouds.aws.ec2.domain.AvailabilityZone;
@ -90,7 +90,7 @@ public class EC2RunNodesAndAddToSetStrategyTest {
return null; return null;
} }
@SuppressWarnings("unchecked") @SuppressWarnings({ "unchecked", "rawtypes" })
private void assertRegionAndZoneForLocation(Location location, String region, String zone) { private void assertRegionAndZoneForLocation(Location location, String region, String zone) {
String imageId = "ami1"; String imageId = "ami1";
String instanceCreatedId = "instance1"; String instanceCreatedId = "instance1";
@ -157,7 +157,7 @@ public class EC2RunNodesAndAddToSetStrategyTest {
Template template = createMock(Template.class); Template template = createMock(Template.class);
Set<NodeMetadata> nodes = createMock(Set.class); Set<NodeMetadata> nodes = createMock(Set.class);
Map<NodeMetadata, Exception> badNodes = createMock(Map.class); Map<NodeMetadata, Exception> badNodes = createMock(Map.class);
EC2Size size = createMock(EC2Size.class); EC2Hardware size = createMock(EC2Hardware.class);
Image image = createMock(Image.class); Image image = createMock(Image.class);
final Location location; final Location location;
EC2TemplateOptions options = createMock(EC2TemplateOptions.class); EC2TemplateOptions options = createMock(EC2TemplateOptions.class);

View File

@ -1,71 +0,0 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.aws.ec2.functions;
import org.jclouds.aws.ec2.domain.InstanceType;
import org.jclouds.aws.ec2.domain.RunningInstance;
import org.testng.annotations.Test;
import java.util.Map;
import static org.easymock.EasyMock.expect;
import static org.easymock.classextension.EasyMock.createMock;
import static org.easymock.classextension.EasyMock.replay;
/**
* @author Oleksiy Yarmula
*/
public class RunningInstanceToStorageMappingUnixTest {
@Test
public void testMappingForM1LargeInstance() {
RunningInstanceToStorageMappingUnix volumeMapping = new RunningInstanceToStorageMappingUnix();
RunningInstance instance = createMock(RunningInstance.class);
expect(instance.getInstanceType()).andStubReturn(InstanceType.M1_LARGE);
replay(instance);
Map<String, String> mappingReturned = volumeMapping.apply(instance);
assert mappingReturned.size() == 3 : String.format(
"Expected size of mapping devices: %d. Found: %d", 3, mappingReturned.size());
assert mappingReturned.containsKey("disk_drive//dev/sda1/gb");
assert mappingReturned.containsKey("disk_drive//dev/sdb/gb");
assert mappingReturned.containsKey("disk_drive//dev/sdc/gb");
}
@Test
public void testMappingForM1XLargeInstance() {
RunningInstanceToStorageMappingUnix volumeMapping = new RunningInstanceToStorageMappingUnix();
RunningInstance instance = createMock(RunningInstance.class);
expect(instance.getInstanceType()).andStubReturn(InstanceType.M1_XLARGE);
replay(instance);
Map<String, String> mappingReturned = volumeMapping.apply(instance);
assert mappingReturned.size() == 5 : String.format(
"Expected size of mapping devices: %d. Found: %d", 5, mappingReturned.size());
assert mappingReturned.containsKey("disk_drive//dev/sda1/gb");
assert mappingReturned.containsKey("disk_drive//dev/sdb/gb");
assert mappingReturned.containsKey("disk_drive//dev/sdc/gb");
assert mappingReturned.containsKey("disk_drive//dev/sdd/gb");
assert mappingReturned.containsKey("disk_drive//dev/sde/gb");
}
}

View File

@ -35,7 +35,6 @@ import org.jclouds.aws.domain.Region;
import org.jclouds.aws.ec2.EC2Client; import org.jclouds.aws.ec2.EC2Client;
import org.jclouds.aws.ec2.domain.InstanceType; import org.jclouds.aws.ec2.domain.InstanceType;
import org.jclouds.aws.ec2.domain.PlacementGroup; import org.jclouds.aws.ec2.domain.PlacementGroup;
import org.jclouds.aws.ec2.domain.RunningInstance;
import org.jclouds.aws.ec2.domain.PlacementGroup.State; import org.jclouds.aws.ec2.domain.PlacementGroup.State;
import org.jclouds.aws.ec2.predicates.PlacementGroupAvailable; import org.jclouds.aws.ec2.predicates.PlacementGroupAvailable;
import org.jclouds.aws.ec2.predicates.PlacementGroupDeleted; import org.jclouds.aws.ec2.predicates.PlacementGroupDeleted;
@ -43,9 +42,9 @@ import org.jclouds.compute.BaseComputeServiceLiveTest;
import org.jclouds.compute.ComputeServiceContext; import org.jclouds.compute.ComputeServiceContext;
import org.jclouds.compute.ComputeServiceContextFactory; import org.jclouds.compute.ComputeServiceContextFactory;
import org.jclouds.compute.RunNodesException; import org.jclouds.compute.RunNodesException;
import org.jclouds.compute.domain.Hardware;
import org.jclouds.compute.domain.Image; import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.NodeMetadata; import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.Size;
import org.jclouds.compute.domain.Template; import org.jclouds.compute.domain.Template;
import org.jclouds.compute.predicates.NodePredicates; import org.jclouds.compute.predicates.NodePredicates;
import org.jclouds.logging.log4j.config.Log4JLoggingModule; import org.jclouds.logging.log4j.config.Log4JLoggingModule;
@ -141,11 +140,11 @@ public class PlacementGroupClientLiveTest {
} }
public void testStartCCInstance() throws Exception { public void testStartCCInstance() throws Exception {
Set<? extends Size> sizes = context.getComputeService().listSizes(); Set<? extends Hardware> sizes = context.getComputeService().listHardwareProfiles();
assert Iterables.any(sizes, new Predicate<Size>() { assert Iterables.any(sizes, new Predicate<Hardware>() {
@Override @Override
public boolean apply(Size arg0) { public boolean apply(Hardware arg0) {
return arg0.getProviderId().equals(InstanceType.CC1_4XLARGE); return arg0.getProviderId().equals(InstanceType.CC1_4XLARGE);
} }
@ -162,7 +161,7 @@ public class PlacementGroupClientLiveTest {
Template template = context.getComputeService().templateBuilder().fastest().build(); Template template = context.getComputeService().templateBuilder().fastest().build();
assert template != null : "The returned template was null, but it should have a value."; assert template != null : "The returned template was null, but it should have a value.";
assertEquals(template.getSize().getProviderId(), InstanceType.CC1_4XLARGE); assertEquals(template.getHardware().getProviderId(), InstanceType.CC1_4XLARGE);
assertEquals(template.getImage().getId(), "us-east-1/ami-7ea24a17"); assertEquals(template.getImage().getId(), "us-east-1/ami-7ea24a17");
template.getOptions().installPrivateKey(newStringPayload(keyPair.get("private"))).authorizePublicKey( template.getOptions().installPrivateKey(newStringPayload(keyPair.get("private"))).authorizePublicKey(
@ -176,10 +175,8 @@ public class PlacementGroupClientLiveTest {
Set<? extends NodeMetadata> nodes = context.getComputeService().runNodesWithTag(tag, 1, template); Set<? extends NodeMetadata> nodes = context.getComputeService().runNodesWithTag(tag, 1, template);
NodeMetadata node = Iterables.getOnlyElement(nodes); NodeMetadata node = Iterables.getOnlyElement(nodes);
RunningInstance instance = Iterables.getOnlyElement(Iterables.getOnlyElement(client.getInstanceServices() Iterables.getOnlyElement(Iterables.getOnlyElement(client.getInstanceServices().describeInstancesInRegion(null,
.describeInstancesInRegion(null, node.getProviderId()))); node.getProviderId())));
assertEquals(instance.getVirtualizationType(), node.getExtra().get("virtualizationType"));
assertEquals(instance.getPlacementGroup(), node.getExtra().get("placementGroup"));
} catch (RunNodesException e) { } catch (RunNodesException e) {
System.err.println(e.getNodeErrors().keySet()); System.err.println(e.getNodeErrors().keySet());

View File

@ -77,7 +77,7 @@ public class DescribeInstancesResponseHandlerTest extends BaseEC2HandlerTest {
"adriancole.ec21", dateService.iso8601DateParse("2009-11-09T03:00:34.000Z"), "adriancole.ec21", dateService.iso8601DateParse("2009-11-09T03:00:34.000Z"),
MonitoringState.DISABLED, AvailabilityZone.US_EAST_1C, null, "paravirtual", null, MonitoringState.DISABLED, AvailabilityZone.US_EAST_1C, null, "paravirtual", null,
"ip-10-243-42-70.ec2.internal", "10.243.42.70", ImmutableSet.<String> of(), "ari-a51cf9cc", "ip-10-243-42-70.ec2.internal", "10.243.42.70", ImmutableSet.<String> of(), "ari-a51cf9cc",
null, null, null, RootDeviceType.INSTANCE_STORE, null, ImmutableMap null, null, null, null, RootDeviceType.INSTANCE_STORE, null, ImmutableMap
.<String, EbsBlockDevice> of())), "993194456877", null, "r-a3c508cb")); .<String, EbsBlockDevice> of())), "993194456877", null, "r-a3c508cb"));
Set<Reservation<? extends RunningInstance>> result = getReservations(is); Set<Reservation<? extends RunningInstance>> result = getReservations(is);
@ -96,14 +96,15 @@ public class DescribeInstancesResponseHandlerTest extends BaseEC2HandlerTest {
InstanceType.M1_LARGE, (String) null, "aki-ba3adfd3", "example-key-name", dateService InstanceType.M1_LARGE, (String) null, "aki-ba3adfd3", "example-key-name", dateService
.iso8601DateParse("2007-08-07T11:54:42.000Z"), MonitoringState.DISABLED, .iso8601DateParse("2007-08-07T11:54:42.000Z"), MonitoringState.DISABLED,
AvailabilityZone.US_EAST_1B, null, "paravirtual", null, "10-251-50-132.ec2.internal", null, AvailabilityZone.US_EAST_1B, null, "paravirtual", null, "10-251-50-132.ec2.internal", null,
ImmutableSet.of("774F4FF8"), "ari-badbad00", null, null, null, RootDeviceType.INSTANCE_STORE, ImmutableSet.of("774F4FF8"), "ari-badbad00", null, null, null, null,
null, ImmutableMap.<String, EbsBlockDevice> of()), new RunningInstance(defaultRegion, RootDeviceType.INSTANCE_STORE, null, ImmutableMap.<String, EbsBlockDevice> of()),
ImmutableSet.of("default"), "23", "ec2-72-44-33-6.compute-1.amazonaws.com", "ami-6ea54007", new RunningInstance(defaultRegion, ImmutableSet.of("default"), "23",
"i-28a64435", InstanceState.RUNNING, InstanceType.M1_LARGE, (String) null, "aki-ba3adfd3", "ec2-72-44-33-6.compute-1.amazonaws.com", "ami-6ea54007", "i-28a64435", InstanceState.RUNNING,
"example-key-name", dateService.iso8601DateParse("2007-08-07T11:54:42.000Z"), InstanceType.M1_LARGE, (String) null, "aki-ba3adfd3", "example-key-name", dateService
MonitoringState.DISABLED, AvailabilityZone.US_EAST_1B, null, "paravirtual", null, .iso8601DateParse("2007-08-07T11:54:42.000Z"), MonitoringState.DISABLED,
"10-251-50-134.ec2.internal", null, ImmutableSet.of("774F4FF8"), "ari-badbad00", null, null, AvailabilityZone.US_EAST_1B, null, "paravirtual", null, "10-251-50-134.ec2.internal", null,
null, RootDeviceType.INSTANCE_STORE, null, ImmutableMap.<String, EbsBlockDevice> of())), ImmutableSet.of("774F4FF8"), "ari-badbad00", null, null, null, null,
RootDeviceType.INSTANCE_STORE, null, ImmutableMap.<String, EbsBlockDevice> of())),
"UYY3TLBUXIEON5NQVUUX6OMPWBZIQNFM", null, "r-44a5402d")); "UYY3TLBUXIEON5NQVUUX6OMPWBZIQNFM", null, "r-44a5402d"));
Set<Reservation<? extends RunningInstance>> result = getReservations(is); Set<Reservation<? extends RunningInstance>> result = getReservations(is);
@ -123,8 +124,25 @@ public class DescribeInstancesResponseHandlerTest extends BaseEC2HandlerTest {
"i-3FFA0762", InstanceState.SHUTTING_DOWN, InstanceType.M1_LARGE, null, "eki-6CBD12F2", "i-3FFA0762", InstanceState.SHUTTING_DOWN, InstanceType.M1_LARGE, null, "eki-6CBD12F2",
"jclouds#euc-17", dateService.iso8601DateParse("2010-06-16T03:06:19.000Z"), "jclouds#euc-17", dateService.iso8601DateParse("2010-06-16T03:06:19.000Z"),
MonitoringState.DISABLED, "open", null, "paravirtual", null, "10.7.0.179", null, ImmutableSet MonitoringState.DISABLED, "open", null, "paravirtual", null, "10.7.0.179", null, ImmutableSet
.<String> of(), "eri-A97113E4", null, null, null, RootDeviceType.INSTANCE_STORE, null, .<String> of(), "eri-A97113E4", null, null, null, null, RootDeviceType.INSTANCE_STORE,
ImmutableMap.<String, EbsBlockDevice> of())), "jclouds", null, "r-4D2A08AD")); null, ImmutableMap.<String, EbsBlockDevice> of())), "jclouds", null, "r-4D2A08AD"));
Set<Reservation<? extends RunningInstance>> result = getReservations(is);
assertEquals(result, contents);
}
public void testApplyInputStreamNovaNoAvailabilityZone() {
InputStream is = getClass().getResourceAsStream("/ec2/describe_instances_nova.xml");
Set<Reservation<? extends RunningInstance>> contents = Sets.newLinkedHashSet();
contents.add(new Reservation<RunningInstance>(defaultRegion, ImmutableSet.of("default"), ImmutableSet
.of(new RunningInstance(defaultRegion, ImmutableSet.<String> of(), "0", null, "ami-h30p5im0",
"i-9slweygo", InstanceState.TERMINATED, InstanceType.M1_SMALL, null, null, "nebulatanimislam",
dateService.iso8601SecondsDateParse("2010-09-09T18:09:42Z"), null, null, null, "paravirtual",
null, null, "10.128.207.5", ImmutableSet.<String> of("None"), null, null, null, null, null,
RootDeviceType.INSTANCE_STORE, null, ImmutableMap.<String, EbsBlockDevice> of())), "tislam1",
null, "r-opqeylmj"));
Set<Reservation<? extends RunningInstance>> result = getReservations(is); Set<Reservation<? extends RunningInstance>> result = getReservations(is);
@ -143,7 +161,7 @@ public class DescribeInstancesResponseHandlerTest extends BaseEC2HandlerTest {
"adriancole.ec2ebs1", dateService.iso8601DateParse("2009-12-30T04:06:23.000Z"), "adriancole.ec2ebs1", dateService.iso8601DateParse("2009-12-30T04:06:23.000Z"),
MonitoringState.DISABLED, AvailabilityZone.US_EAST_1B, "placement", "hvm", null, MonitoringState.DISABLED, AvailabilityZone.US_EAST_1B, "placement", "hvm", null,
"domU-12-31-39-09-CE-53.compute-1.internal", "10.210.209.157", ImmutableSet.<String> of(), "domU-12-31-39-09-CE-53.compute-1.internal", "10.210.209.157", ImmutableSet.<String> of(),
"ari-a51cf9cc", null, null, null, RootDeviceType.EBS, "/dev/sda1", ImmutableMap "ari-a51cf9cc", null, null, null, null, RootDeviceType.EBS, "/dev/sda1", ImmutableMap
.<String, EbsBlockDevice> of("/dev/sda1", new EbsBlockDevice("vol-dc6ca8b5", .<String, EbsBlockDevice> of("/dev/sda1", new EbsBlockDevice("vol-dc6ca8b5",
Attachment.Status.ATTACHED, dateService Attachment.Status.ATTACHED, dateService
.iso8601DateParse("2009-12-30T04:06:29.000Z"), true)))), .iso8601DateParse("2009-12-30T04:06:29.000Z"), true)))),

View File

@ -96,6 +96,21 @@ public class DescribeRegionsResponseHandlerTest extends BaseHandlerTest {
assertEquals(result, expected); assertEquals(result, expected);
} }
public void testEuc2() {
InputStream is = Utils
.toInputStream("<?xml version=\"1.0\" ?><DescribeRegionsResponse xmlns=\"http://ec2.amazonaws.com/doc/2009-11-30/\"><requestId>1LAQRTCLTLPS6CEIC627</requestId><regionInfo><item><regionUrl>http://10.255.255.1:8773/services/Cloud</regionUrl><regionName>nova</regionName></item></regionInfo></DescribeRegionsResponse>");
Map<String, URI> expected = ImmutableMap.<String, URI> of("nova",
URI.create("http://10.255.255.1:8773/services/Cloud"));
Map<String, URI> result = factory.create(
injector.getInstance(DescribeRegionsResponseHandler.class)).parse(
is);
assertEquals(result, expected);
}
public void testUnsupportedAdditionalRegionDoesntBreak() { public void testUnsupportedAdditionalRegionDoesntBreak() {
InputStream is = getClass().getResourceAsStream( InputStream is = getClass().getResourceAsStream(

View File

@ -71,17 +71,17 @@ public class RunInstancesResponseHandlerTest extends BaseEC2HandlerTest {
null, "ami-60a54009", "i-2ba64342", InstanceState.PENDING, InstanceType.M1_SMALL, (String) null, null, null, "ami-60a54009", "i-2ba64342", InstanceState.PENDING, InstanceType.M1_SMALL, (String) null, null,
"example-key-name", dateService.iso8601DateParse("2007-08-07T11:51:50.000Z"), MonitoringState.ENABLED, "example-key-name", dateService.iso8601DateParse("2007-08-07T11:51:50.000Z"), MonitoringState.ENABLED,
AvailabilityZone.US_EAST_1B, null, "paravirtual", null, (String) null, null, Sets AvailabilityZone.US_EAST_1B, null, "paravirtual", null, (String) null, null, Sets
.<String> newLinkedHashSet(), null, null, null, null, RootDeviceType.INSTANCE_STORE, null, .<String> newLinkedHashSet(), null, null, null, null, null, RootDeviceType.INSTANCE_STORE,
ImmutableMap.<String, EbsBlockDevice> of()), new RunningInstance(defaultRegion, ImmutableSet null, ImmutableMap.<String, EbsBlockDevice> of()), new RunningInstance(defaultRegion, ImmutableSet
.of("default"), "1", null, "ami-60a54009", "i-2bc64242", InstanceState.PENDING, InstanceType.M1_SMALL, .of("default"), "1", null, "ami-60a54009", "i-2bc64242", InstanceState.PENDING, InstanceType.M1_SMALL,
(String) null, null, "example-key-name", dateService.iso8601DateParse("2007-08-07T11:51:50.000Z"), (String) null, null, "example-key-name", dateService.iso8601DateParse("2007-08-07T11:51:50.000Z"),
MonitoringState.ENABLED, AvailabilityZone.US_EAST_1B, null, "paravirtual", null, (String) null, null, MonitoringState.ENABLED, AvailabilityZone.US_EAST_1B, null, "paravirtual", null, (String) null, null,
Sets.<String> newLinkedHashSet(), null, null, null, null, RootDeviceType.INSTANCE_STORE, null, Sets.<String> newLinkedHashSet(), null, null, null, null, null, RootDeviceType.INSTANCE_STORE, null,
ImmutableMap.<String, EbsBlockDevice> of()), new RunningInstance(defaultRegion, ImmutableSet ImmutableMap.<String, EbsBlockDevice> of()), new RunningInstance(defaultRegion, ImmutableSet
.of("default"), "2", null, "ami-60a54009", "i-2be64332", InstanceState.PENDING, InstanceType.M1_SMALL, .of("default"), "2", null, "ami-60a54009", "i-2be64332", InstanceState.PENDING, InstanceType.M1_SMALL,
(String) null, null, "example-key-name", dateService.iso8601DateParse("2007-08-07T11:51:50.000Z"), (String) null, null, "example-key-name", dateService.iso8601DateParse("2007-08-07T11:51:50.000Z"),
MonitoringState.ENABLED, AvailabilityZone.US_EAST_1B, null, "paravirtual", null, (String) null, null, MonitoringState.ENABLED, AvailabilityZone.US_EAST_1B, null, "paravirtual", null, (String) null, null,
Sets.<String> newLinkedHashSet(), null, null, null, null, RootDeviceType.INSTANCE_STORE, null, Sets.<String> newLinkedHashSet(), null, null, null, null, null, RootDeviceType.INSTANCE_STORE, null,
ImmutableMap.<String, EbsBlockDevice> of()) ImmutableMap.<String, EbsBlockDevice> of())
), "AIDADH4IGTRXXKCD", null, "r-47a5402e"); ), "AIDADH4IGTRXXKCD", null, "r-47a5402e");

View File

@ -69,6 +69,30 @@ public class ParseAWSErrorFromXmlContentTest {
"<Error><Code>IncorrectState</Code></Error>", IllegalStateException.class); "<Error><Code>IncorrectState</Code></Error>", IllegalStateException.class);
} }
@Test
public void test400WithInvalidGroupDuplicateIllegalStateException() {
assertCodeMakes("GET", URI.create("https://amazonaws.com/foo"), 400,"Bad Request", "application/unknown",
"<Error><Code>InvalidGroup.Duplicate</Code></Error>", IllegalStateException.class);
}
@Test
public void test400WithTextPlainIllegalArgumentException() {
assertCodeMakes("GET", URI.create("https://amazonaws.com/foo"), 400, "Bad Request", "text/plain",
"Failure: 400 Bad Request\nFailed to bind the following fields\nMonitoring.Enabled = true\n\n\n",
IllegalArgumentException.class);
}
@Test
public void test400WithGroupAlreadyExistsEucalyptusIllegalStateException() {
assertCodeMakes(
"GET",
URI.create("https://amazonaws.com/foo"),
400,
"",
"<?xml version=\"1.0\"?><Response><Errors><Error><Code>Groups</Code><Message>\nError adding network group: group named jclouds#eucrun#Eucalyptus already exists\nError adding network group: group named jclouds#eucrun#Eucalyptus already exists</Message></Error></Errors><RequestID>e0133975-3bc5-456d-9753-1d61b27e07e9</RequestID></Response>",
IllegalStateException.class);
}
@Test @Test
public void test400WithAuthFailureSetsAuthorizationException() { public void test400WithAuthFailureSetsAuthorizationException() {
assertCodeMakes("GET", URI.create("https://amazonaws.com/foo"), 400, "", assertCodeMakes("GET", URI.create("https://amazonaws.com/foo"), 400, "",
@ -77,6 +101,11 @@ public class ParseAWSErrorFromXmlContentTest {
private void assertCodeMakes(String method, URI uri, int statusCode, String message, String content, private void assertCodeMakes(String method, URI uri, int statusCode, String message, String content,
Class<? extends Exception> expected) { Class<? extends Exception> expected) {
assertCodeMakes(method, uri, statusCode, message, "text/xml", content, expected);
}
private void assertCodeMakes(String method, URI uri, int statusCode, String message, String contentType,
String content, Class<? extends Exception> expected) {
ParseAWSErrorFromXmlContent function = Guice.createInjector(new SaxParserModule(), new AbstractModule() { ParseAWSErrorFromXmlContent function = Guice.createInjector(new SaxParserModule(), new AbstractModule() {
@ -92,8 +121,7 @@ public class ParseAWSErrorFromXmlContentTest {
HttpRequest request = new HttpRequest(method, uri); HttpRequest request = new HttpRequest(method, uri);
HttpResponse response = new HttpResponse(statusCode, message, Payloads.newInputStreamPayload(Utils HttpResponse response = new HttpResponse(statusCode, message, Payloads.newInputStreamPayload(Utils
.toInputStream(content))); .toInputStream(content)));
response.getPayload().setContentType("text/xml"); response.getPayload().setContentType(contentType);
//TODO also check application/unknown
expect(command.getRequest()).andReturn(request).atLeastOnce(); expect(command.getRequest()).andReturn(request).atLeastOnce();
command.setException(classEq(expected)); command.setException(classEq(expected));

View File

@ -270,8 +270,7 @@ public class S3AsyncClientTest extends BaseS3AsyncClientTest {
public void testGetObject() throws ArrayIndexOutOfBoundsException, SecurityException, IllegalArgumentException, public void testGetObject() throws ArrayIndexOutOfBoundsException, SecurityException, IllegalArgumentException,
NoSuchMethodException, IOException { NoSuchMethodException, IOException {
Method method = S3AsyncClient.class.getMethod("getObject", String.class, String.class, Array.newInstance( Method method = S3AsyncClient.class.getMethod("getObject", String.class, String.class, GetOptions[].class);
GetOptions.class, 0).getClass());
HttpRequest request = processor.createRequest(method, "bucket", "object"); HttpRequest request = processor.createRequest(method, "bucket", "object");
assertRequestLineEquals(request, "GET https://bucket.s3.amazonaws.com/object HTTP/1.1"); assertRequestLineEquals(request, "GET https://bucket.s3.amazonaws.com/object HTTP/1.1");

View File

@ -0,0 +1,140 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.aws.s3.blobstore;
import static org.testng.Assert.assertEquals;
import java.io.IOException;
import java.util.Properties;
import org.jclouds.aws.s3.S3AsyncClient;
import org.jclouds.aws.s3.config.S3RestClientModule;
import org.jclouds.blobstore.BlobRequestSigner;
import org.jclouds.blobstore.domain.Blob;
import org.jclouds.blobstore.domain.Blob.Factory;
import org.jclouds.date.TimeStamp;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.RequiresHttp;
import org.jclouds.io.payloads.PhantomPayload;
import org.jclouds.rest.ConfiguresRestClient;
import org.jclouds.rest.RestClientTest;
import org.jclouds.rest.RestContextFactory;
import org.jclouds.rest.RestContextFactory.ContextSpec;
import org.jclouds.rest.internal.RestAnnotationProcessor;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import com.google.common.base.Supplier;
import com.google.inject.Module;
import com.google.inject.TypeLiteral;
@Test(groups = "unit", testName = "s3.S3BlobRequestSignerTest")
public class S3BlobRequestSignerTest extends RestClientTest<S3AsyncClient> {
private BlobRequestSigner signer;
private Factory blobFactory;
public void testSignGetBlob() throws ArrayIndexOutOfBoundsException, SecurityException, IllegalArgumentException,
NoSuchMethodException, IOException {
HttpRequest request = signer.signGetBlob("container", "name");
assertRequestLineEquals(request, "GET https://container.s3.amazonaws.com/name HTTP/1.1");
assertNonPayloadHeadersEqual(
request,
"Authorization: AWS identity:0uvBv1wEskuhFHYJF/L6kEV9A7o=\nDate: Thu, 05 Jun 2008 16:38:19 GMT\nHost: container.s3.amazonaws.com\n");
assertPayloadEquals(request, null, null, false);
assertEquals(request.getFilters().size(), 0);
}
public void testSignRemoveBlob() throws ArrayIndexOutOfBoundsException, SecurityException, IllegalArgumentException,
NoSuchMethodException, IOException {
HttpRequest request = signer.signRemoveBlob("container", "name");
assertRequestLineEquals(request, "DELETE https://container.s3.amazonaws.com/name HTTP/1.1");
assertNonPayloadHeadersEqual(
request,
"Authorization: AWS identity:4FnyjdX/ULdDMRbVlLNjZfEo9RQ=\nDate: Thu, 05 Jun 2008 16:38:19 GMT\nHost: container.s3.amazonaws.com\n");
assertPayloadEquals(request, null, null, false);
assertEquals(request.getFilters().size(), 0);
}
public void testSignPutBlob() throws ArrayIndexOutOfBoundsException, SecurityException, IllegalArgumentException,
NoSuchMethodException, IOException {
Blob blob = blobFactory.create(null);
blob.getMetadata().setName("name");
blob.setPayload(new PhantomPayload(2l, new byte[] { 0, 2, 4, 8 }));
blob.getPayload().setContentType("text/plain");
HttpRequest request = signer.signPutBlob("container", blob);
assertRequestLineEquals(request, "PUT https://container.s3.amazonaws.com/name HTTP/1.1");
assertNonPayloadHeadersEqual(
request,
"Authorization: AWS identity:j9Dy/lmmvlCKjA4lkqZenLxMkR4=\nDate: Thu, 05 Jun 2008 16:38:19 GMT\nHost: container.s3.amazonaws.com\n");
assertContentHeadersEqual(request, "text/plain", (long) 2l, new byte[] { 0, 2, 4, 8 });
assertEquals(request.getFilters().size(), 0);
}
@BeforeClass
protected void setupFactory() throws IOException {
super.setupFactory();
this.blobFactory = injector.getInstance(Blob.Factory.class);
this.signer = injector.getInstance(BlobRequestSigner.class);
}
@Override
protected void checkFilters(HttpRequest request) {
}
@Override
protected TypeLiteral<RestAnnotationProcessor<S3AsyncClient>> createTypeLiteral() {
return new TypeLiteral<RestAnnotationProcessor<S3AsyncClient>>() {
};
}
@Override
protected Module createModule() {
return new TestS3RestClientModule();
}
@RequiresHttp
@ConfiguresRestClient
private static final class TestS3RestClientModule extends S3RestClientModule {
@Override
protected void configure() {
super.configure();
}
@Override
protected String provideTimeStamp(@TimeStamp Supplier<String> cache) {
return "Thu, 05 Jun 2008 16:38:19 GMT";
}
}
@Override
public ContextSpec<?, ?> createContextSpec() {
return new RestContextFactory().createContextSpec("s3", "identity", "credential", new Properties());
}
}

View File

@ -0,0 +1,32 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.aws.s3.blobstore.integration;
import org.jclouds.blobstore.integration.internal.BaseBlobSignerLiveTest;
import org.testng.annotations.Test;
/**
*
* @author Adrian Cole
*/
@Test(groups = { "live" }, testName = "s3.S3BlobSignerLiveTest")
public class S3BlobSignerLiveTest extends BaseBlobSignerLiveTest {
}

View File

@ -33,7 +33,6 @@ import java.util.Set;
import javax.inject.Singleton; import javax.inject.Singleton;
import javax.ws.rs.core.UriBuilder; import javax.ws.rs.core.UriBuilder;
import org.jboss.resteasy.specimpl.UriBuilderImpl;
import org.jclouds.PerformanceTest; import org.jclouds.PerformanceTest;
import org.jclouds.aws.domain.Region; import org.jclouds.aws.domain.Region;
import org.jclouds.aws.sqs.domain.Queue; import org.jclouds.aws.sqs.domain.Queue;
@ -55,6 +54,7 @@ import com.google.inject.AbstractModule;
import com.google.inject.Guice; import com.google.inject.Guice;
import com.google.inject.Injector; import com.google.inject.Injector;
import com.google.inject.Provides; import com.google.inject.Provides;
import com.sun.jersey.api.uri.UriBuilderImpl;
/** /**
* Tests behavior of {@code ListQueuesResponseHandlerr} * Tests behavior of {@code ListQueuesResponseHandlerr}

View File

@ -33,23 +33,30 @@ public class ErrorHandlerTest extends BaseHandlerTest {
public static final String errorFromAmazonIfYouDontRemoveTransferEncodingHeader = "<Error><Code>NotImplemented</Code><Message>A header you provided implies functionality that is not implemented</Message><Header>Transfer-Encoding</Header><RequestId>7C59925D75D15561</RequestId><HostId>fbskVU51OZJg2yZS/wNIxoE2PmCf0ZqFd0iH6Vrzw0uKG3KmokswBytL/Bfp/GWb</HostId></Error>"; public static final String errorFromAmazonIfYouDontRemoveTransferEncodingHeader = "<Error><Code>NotImplemented</Code><Message>A header you provided implies functionality that is not implemented</Message><Header>Transfer-Encoding</Header><RequestId>7C59925D75D15561</RequestId><HostId>fbskVU51OZJg2yZS/wNIxoE2PmCf0ZqFd0iH6Vrzw0uKG3KmokswBytL/Bfp/GWb</HostId></Error>";
ParseSax<AWSError> createParser() { ParseSax<AWSError> createParser() {
ParseSax<AWSError> parser = (ParseSax<AWSError>) factory.create(injector ParseSax<AWSError> parser = (ParseSax<AWSError>) factory.create(injector.getInstance(ErrorHandler.class));
.getInstance(ErrorHandler.class));
return parser; return parser;
} }
@Test @Test
public void testErrorFromAmazonIfYouDontRemoveTransferEncodingHeader() throws HttpException { public void testErrorFromAmazonIfYouDontRemoveTransferEncodingHeader() throws HttpException {
ParseSax<AWSError> parser = createParser(); ParseSax<AWSError> parser = createParser();
AWSError error = parser.parse(Utils AWSError error = parser.parse(Utils.toInputStream(errorFromAmazonIfYouDontRemoveTransferEncodingHeader));
.toInputStream(errorFromAmazonIfYouDontRemoveTransferEncodingHeader));
assertEquals(error.getCode(), "NotImplemented"); assertEquals(error.getCode(), "NotImplemented");
assertEquals(error.getMessage(), assertEquals(error.getMessage(), "A header you provided implies functionality that is not implemented");
"A header you provided implies functionality that is not implemented");
assertEquals(error.getDetails().get("Header"), "Transfer-Encoding"); assertEquals(error.getDetails().get("Header"), "Transfer-Encoding");
assertEquals(error.getRequestId(), "7C59925D75D15561"); assertEquals(error.getDetails().get("HostId"), "fbskVU51OZJg2yZS/wNIxoE2PmCf0ZqFd0iH6Vrzw0uKG3KmokswBytL/Bfp/GWb");
assertEquals(error.getDetails().get("HostId"), }
"fbskVU51OZJg2yZS/wNIxoE2PmCf0ZqFd0iH6Vrzw0uKG3KmokswBytL/Bfp/GWb");
@Test
public void testErrorFromEucalyptusWhenGroupAlreadyExists() throws HttpException {
ParseSax<AWSError> parser = createParser();
AWSError error = parser
.parse(Utils
.toInputStream("<?xml version=\"1.0\"?><Response><Errors><Error><Code>Groups</Code><Message>\nError adding network group: group named jclouds#eucrun#Eucalyptus already exists\nError adding network group: group named jclouds#eucrun#Eucalyptus already exists</Message></Error></Errors><RequestID>e0133975-3bc5-456d-9753-1d61b27e07e9</RequestID></Response>"));
assertEquals(error.getCode(), "Groups");
assertEquals(
error.getMessage(),
"Error adding network group: group named jclouds#eucrun#Eucalyptus already exists\nError adding network group: group named jclouds#eucrun#Eucalyptus already exists");
} }
public static final String badRequestWhenSourceIsDestBucketOnCopy400 = "<Error><Code>InvalidRequest</Code><Message>The Source and Destination may not be the same when the MetadataDirective is Copy.</Message><RequestId>54C77CAF4D42474B</RequestId><HostId>SJecknEUUUx88/65VAKbCdKSOCkpuVTeu7ZG9in9x9NTNglGnoxdbALCfS4k/DUZ</HostId></Error>"; public static final String badRequestWhenSourceIsDestBucketOnCopy400 = "<Error><Code>InvalidRequest</Code><Message>The Source and Destination may not be the same when the MetadataDirective is Copy.</Message><RequestId>54C77CAF4D42474B</RequestId><HostId>SJecknEUUUx88/65VAKbCdKSOCkpuVTeu7ZG9in9x9NTNglGnoxdbALCfS4k/DUZ</HostId></Error>";

View File

@ -91,5 +91,29 @@
<rootDeviceType>instance-store</rootDeviceType> <rootDeviceType>instance-store</rootDeviceType>
<blockDeviceMapping /> <blockDeviceMapping />
</item> </item>
<item>
<imageId>ami-10f3a255</imageId>
<imageLocation>099720109477/ebs/ubuntu-images/ubuntu-lucid-10.04-i386-server-20100827</imageLocation>
<imageState>available</imageState>
<imageOwnerId>099720109477</imageOwnerId>
<isPublic>true</isPublic>
<architecture>i386</architecture>
<imageType>machine</imageType>
<kernelId>aki-a8f0a1ed</kernelId>
<name>ebs/ubuntu-images/ubuntu-lucid-10.04-i386-server-20100827</name>
<rootDeviceType>ebs</rootDeviceType>
<rootDeviceName>/dev/sda1</rootDeviceName>
<blockDeviceMapping>
<item>
<deviceName>/dev/sda1</deviceName>
<ebs>
<snapshotId>snap-76eff01e</snapshotId>
<volumeSize>15</volumeSize>
<deleteOnTermination>true</deleteOnTermination>
</ebs>
</item>
</blockDeviceMapping>
<virtualizationType>paravirtual</virtualizationType>
</item>
</imagesSet> </imagesSet>
</DescribeImagesResponse> </DescribeImagesResponse>

View File

@ -0,0 +1,86 @@
<?xml version="1.0"?>
<DescribeImagesResponse xmlns="http://ec2.amazonaws.com/doc/2009-11-30/">
<requestId>6104eee1-affd-49d7-92a0-516cab8a8ba6</requestId>
<imagesSet>
<item>
<imageId>ami-82e4b5c7</imageId>
<imageLocation>137112412989/amzn-ami-0.9.7-beta.i386-ebs</imageLocation>
<imageState>available</imageState>
<imageOwnerId>137112412989</imageOwnerId>
<isPublic>true</isPublic>
<architecture>i386</architecture>
<imageType>machine</imageType>
<kernelId>aki-99a0f1dc</kernelId>
<name>amzn-ami-0.9.7-beta.i386-ebs</name>
<description>Amazon</description>
<rootDeviceType>ebs</rootDeviceType>
<rootDeviceName>/dev/sda1</rootDeviceName>
<blockDeviceMapping>
<item>
<deviceName>/dev/sda1</deviceName>
<ebs>
<snapshotId>snap-e98b7b82</snapshotId>
<volumeSize>10</volumeSize>
<deleteOnTermination>true</deleteOnTermination>
</ebs>
</item>
</blockDeviceMapping>
<virtualizationType>paravirtual</virtualizationType>
</item>
<item>
<imageId>ami-8ce4b5c9</imageId>
<imageLocation>137112412989/amzn-ami-0.9.7-beta.x86_64-ebs</imageLocation>
<imageState>available</imageState>
<imageOwnerId>137112412989</imageOwnerId>
<isPublic>true</isPublic>
<architecture>x86_64</architecture>
<imageType>machine</imageType>
<kernelId>aki-9ba0f1de</kernelId>
<name>amzn-ami-0.9.7-beta.x86_64-ebs</name>
<description>Amazon</description>
<rootDeviceType>ebs</rootDeviceType>
<rootDeviceName>/dev/sda1</rootDeviceName>
<blockDeviceMapping>
<item>
<deviceName>/dev/sda1</deviceName>
<ebs>
<snapshotId>snap-8d8b7be6</snapshotId>
<volumeSize>10</volumeSize>
<deleteOnTermination>true</deleteOnTermination>
</ebs>
</item>
</blockDeviceMapping>
<virtualizationType>paravirtual</virtualizationType>
</item>
<item>
<imageId>ami-f0e4b5b5</imageId>
<imageLocation>amzn-ami-us-west-1/amzn-ami-0.9.7-beta.i386.manifest.xml</imageLocation>
<imageState>available</imageState>
<imageOwnerId>137112412989</imageOwnerId>
<isPublic>true</isPublic>
<architecture>i386</architecture>
<imageType>machine</imageType>
<kernelId>aki-99a0f1dc</kernelId>
<name>amzn-ami-0.9.7-beta.i386-S3</name>
<description>Amazon Linux AMI i386 S3</description>
<rootDeviceType>instance-store</rootDeviceType>
<blockDeviceMapping/>
<virtualizationType>paravirtual</virtualizationType>
</item>
<item>
<imageId>ami-f2e4b5b7</imageId>
<imageLocation>amzn-ami-us-west-1/amzn-ami-0.9.7-beta.x86_64.manifest.xml</imageLocation>
<imageState>available</imageState>
<imageOwnerId>137112412989</imageOwnerId>
<isPublic>true</isPublic>
<architecture>x86_64</architecture>
<imageType>machine</imageType>
<kernelId>aki-9ba0f1de</kernelId>
<name>amzn-ami-0.9.7-beta.x86_64-S3</name>
<description>Amazon Linux AMI x86_64 S3</description>
<rootDeviceType>instance-store</rootDeviceType>
<blockDeviceMapping/>
<virtualizationType>paravirtual</virtualizationType>
</item>
</imagesSet>
</DescribeImagesResponse>

View File

@ -0,0 +1,37 @@
<?xml version="1.0" ?>
<DescribeInstancesResponse xmlns="http://ec2.amazonaws.com/doc/2009-11-30/">
<requestId>G7PDD1DNVLO7DZS6AFZH</requestId>
<reservationSet>
<item>
<instancesSet>
<item>
<privateDnsName>10.128.207.5</privateDnsName>
<amiLaunchIndex>0</amiLaunchIndex>
<instanceType>m1.small</instanceType>
<dnsName />
<launchTime>2010-09-09T18:09:42Z</launchTime>
<instanceId>i-9slweygo</instanceId>
<imageId>ami-h30p5im0</imageId>
<instanceState>
<code>1</code>
<name>shutdown</name>
</instanceState>
<keyName>nebulatanimislam</keyName>
<publicDnsName>10.128.207.5</publicDnsName>
<productCodesSet>
<item>
<productCode>None</productCode>
</item>
</productCodesSet>
</item>
</instancesSet>
<reservationId>r-opqeylmj</reservationId>
<groupSet>
<item>
<groupId>default</groupId>
</item>
</groupSet>
<ownerId>tislam1</ownerId>
</item>
</reservationSet>
</DescribeInstancesResponse>

View File

@ -0,0 +1,179 @@
<?xml version="1.0" ?>
<DescribeImagesResponse xmlns="http://ec2.amazonaws.com/doc/2009-11-30/">
<requestId>RX9NL9IWKIR11XL8ZLFR</requestId>
<imagesSet>
<item>
<imageOwnerId>foo</imageOwnerId>
<isPublic>true</isPublic>
<imageId>ami-h30p5im0</imageId>
<imageState>available</imageState>
<architecture>x86_64</architecture>
<imageLocation>nasacms/image.manifest.xml</imageLocation>
<type>machine</type>
</item>
<item>
<imageOwnerId>admin</imageOwnerId>
<isPublic>true</isPublic>
<imageId>ari-lucid</imageId>
<imageState>available</imageState>
<architecture>x86_64</architecture>
<imageLocation>nebula/lucid-ramdisk</imageLocation>
<type>ramdisk</type>
</item>
<item>
<imageOwnerId>vishvananda</imageOwnerId>
<isPublic>true</isPublic>
<imageId>ami-tiny</imageId>
<imageState>available</imageState>
<architecture>x86_64</architecture>
<imageLocation>nebula/tiny</imageLocation>
<type>machine</type>
</item>
<item>
<imageOwnerId>admin</imageOwnerId>
<isPublic>true</isPublic>
<imageId>ami-630A130F</imageId>
<imageState>available</imageState>
<architecture>x86_64</architecture>
<imageLocation>demos/mediawiki</imageLocation>
<type>machine</type>
</item>
<item>
<imageOwnerId>admin</imageOwnerId>
<isPublic>true</isPublic>
<imageId>aki-edge</imageId>
<imageState>available</imageState>
<architecture>x86_64</architecture>
<imageLocation>nebula/bleeding-edge-kernel</imageLocation>
<type>kernel</type>
</item>
<item>
<imageOwnerId>admin</imageOwnerId>
<isPublic>true</isPublic>
<imageId>ari-edge</imageId>
<imageState>available</imageState>
<architecture>x86_64</architecture>
<imageLocation>nebula/bleeding-edge-ramdisk</imageLocation>
<type>ramdisk</type>
</item>
<item>
<imageOwnerId>admin</imageOwnerId>
<isPublic>true</isPublic>
<imageId>aki-lucid</imageId>
<imageState>available</imageState>
<architecture>x86_64</architecture>
<imageLocation>nebula/lucid-kernel</imageLocation>
<type>kernel</type>
</item>
<item>
<imageOwnerId>admin</imageOwnerId>
<isPublic>true</isPublic>
<imageId>ami-pinginst</imageId>
<imageState>available</imageState>
<architecture>x86_64</architecture>
<imageLocation>pinglet/instances</imageLocation>
<type>machine</type>
</item>
<item>
<imageOwnerId>rkumar2</imageOwnerId>
<isPublic>true</isPublic>
<imageId>ami-alqbihe2</imageId>
<imageState>available</imageState>
<architecture>x86_64</architecture>
<imageLocation>bucket/testbuntu.manifest.xml</imageLocation>
<type>machine</type>
</item>
<item>
<imageOwnerId>ykliu</imageOwnerId>
<isPublic>true</isPublic>
<imageId>ami-i0aemtfp</imageId>
<imageState>available</imageState>
<architecture>x86_64</architecture>
<imageLocation>gfortran-bucket/gfortran.manifest.xml
</imageLocation>
<type>machine</type>
</item>
<item>
<imageOwnerId>admin</imageOwnerId>
<isPublic>true</isPublic>
<imageId>ari-22F211EF</imageId>
<imageState>available</imageState>
<architecture>x86_64</architecture>
<imageLocation>nebula/ramdisk</imageLocation>
<type>ramdisk</type>
</item>
<item>
<imageOwnerId>foo</imageOwnerId>
<isPublic>true</isPublic>
<imageId>ami-2ig7w1bh</imageId>
<imageState>available</imageState>
<architecture>x86_64</architecture>
<imageLocation>grinder/grinder-analyzer.manifest.xml
</imageLocation>
<type>machine</type>
</item>
<item>
<imageOwnerId>admin</imageOwnerId>
<isPublic>true</isPublic>
<imageId>aki-EAB510D9</imageId>
<imageState>available</imageState>
<architecture>x86_64</architecture>
<imageLocation>nebula/kernel</imageLocation>
<type>kernel</type>
</item>
<item>
<imageOwnerId>vishvananda</imageOwnerId>
<isPublic>true</isPublic>
<imageId>ami-lucid</imageId>
<imageState>available</imageState>
<architecture>x86_64</architecture>
<imageLocation>nebula/lucid</imageLocation>
<type>machine</type>
</item>
<item>
<imageOwnerId>admin</imageOwnerId>
<isPublic>true</isPublic>
<imageId>ami-karmiclg</imageId>
<imageState>available</imageState>
<architecture>x86_64</architecture>
<imageLocation>nebula/karmic-large</imageLocation>
<type>machine</type>
</item>
<item>
<imageOwnerId>jyothi</imageOwnerId>
<isPublic>true</isPublic>
<imageId>ami-8jen8kdn</imageId>
<imageState>available</imageState>
<architecture>x86_64</architecture>
<imageLocation>jo/qa-grinder.manifest.xml</imageLocation>
<type>machine</type>
</item>
<item>
<imageOwnerId>vishvananda</imageOwnerId>
<isPublic>true</isPublic>
<imageId>ami-lucidlg</imageId>
<imageState>available</imageState>
<architecture>x86_64</architecture>
<imageLocation>nebula/lucid-large</imageLocation>
<type>machine</type>
</item>
<item>
<imageOwnerId>admin</imageOwnerId>
<isPublic>true</isPublic>
<imageId>ami-6CD61336</imageId>
<imageState>available</imageState>
<architecture>x86_64</architecture>
<imageLocation>demos/wordpress</imageLocation>
<type>machine</type>
</item>
<item>
<imageOwnerId>admin</imageOwnerId>
<isPublic>true</isPublic>
<imageId>ami-25CB1213</imageId>
<imageState>available</imageState>
<architecture>x86_64</architecture>
<imageLocation>nebula/ubuntu-karmic</imageLocation>
<type>machine</type>
</item>
</imagesSet>
</DescribeImagesResponse>

View File

@ -1,58 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
====================================================================
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
====================================================================
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>jclouds-aws-project</artifactId>
<groupId>org.jclouds</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>jclouds-aws-extensions-project</artifactId>
<packaging>pom</packaging>
<name>jclouds AWS extensions aggregator</name>
<modules>
<module>jets3t</module>
</modules>
<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>jclouds-aws</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>jclouds-blobstore</artifactId>
<version>${project.version}</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>jclouds-aws</artifactId>
<version>${project.version}</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@ -33,7 +33,6 @@
<name>jclouds AWS project</name> <name>jclouds AWS project</name>
<modules> <modules>
<module>core</module> <module>core</module>
<module>extensions</module>
<module>demos</module> <module>demos</module>
</modules> </modules>
<properties> <properties>

View File

@ -83,6 +83,7 @@ import com.google.common.util.concurrent.ListenableFuture;
@SkipEncoding('/') @SkipEncoding('/')
@RequestFilters(SharedKeyLiteAuthentication.class) @RequestFilters(SharedKeyLiteAuthentication.class)
@Headers(keys = AzureStorageHeaders.VERSION, values = "2009-09-19") @Headers(keys = AzureStorageHeaders.VERSION, values = "2009-09-19")
@Path("/")
public interface AzureBlobAsyncClient { public interface AzureBlobAsyncClient {
public org.jclouds.azure.storage.blob.domain.AzureBlob newBlob(); public org.jclouds.azure.storage.blob.domain.AzureBlob newBlob();
@ -92,7 +93,7 @@ public interface AzureBlobAsyncClient {
*/ */
@GET @GET
@XMLResponseParser(AccountNameEnumerationResultsHandler.class) @XMLResponseParser(AccountNameEnumerationResultsHandler.class)
@Path("/") @Path("")
@QueryParams(keys = "comp", values = "list") @QueryParams(keys = "comp", values = "list")
ListenableFuture<? extends BoundedSet<ContainerProperties>> listContainers( ListenableFuture<? extends BoundedSet<ContainerProperties>> listContainers(
ListOptions... listOptions); ListOptions... listOptions);

View File

@ -0,0 +1,77 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.azure.storage.blob.blobstore;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.jclouds.blobstore.util.BlobStoreUtils.cleanRequest;
import java.lang.reflect.Method;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.jclouds.azure.storage.blob.AzureBlobAsyncClient;
import org.jclouds.azure.storage.blob.blobstore.functions.BlobToAzureBlob;
import org.jclouds.azure.storage.blob.domain.AzureBlob;
import org.jclouds.blobstore.BlobRequestSigner;
import org.jclouds.blobstore.domain.Blob;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.options.GetOptions;
import org.jclouds.rest.internal.RestAnnotationProcessor;
/**
*
* @author Adrian Cole
*/
@Singleton
public class AzureBlobRequestSigner implements BlobRequestSigner {
private final RestAnnotationProcessor<AzureBlobAsyncClient> processor;
private final BlobToAzureBlob blobToBlob;
private final Method getMethod;
private final Method deleteMethod;
private final Method createMethod;
@Inject
public AzureBlobRequestSigner(RestAnnotationProcessor<AzureBlobAsyncClient> processor, BlobToAzureBlob blobToBlob)
throws SecurityException, NoSuchMethodException {
this.processor = checkNotNull(processor, "processor");
this.blobToBlob = checkNotNull(blobToBlob, "blobToBlob");
this.getMethod = AzureBlobAsyncClient.class.getMethod("getBlob", String.class, String.class, GetOptions[].class);
this.deleteMethod = AzureBlobAsyncClient.class.getMethod("deleteBlob", String.class, String.class);
this.createMethod = AzureBlobAsyncClient.class.getMethod("putBlob", String.class, AzureBlob.class);
}
@Override
public HttpRequest signGetBlob(String container, String name) {
return cleanRequest(processor.createRequest(getMethod, container, name));
}
@Override
public HttpRequest signPutBlob(String container, Blob blob) {
return cleanRequest(processor.createRequest(createMethod, container, blobToBlob.apply(blob)));
}
@Override
public HttpRequest signRemoveBlob(String container, String name) {
return cleanRequest(processor.createRequest(deleteMethod, container, name));
}
}

View File

@ -26,9 +26,11 @@ import javax.inject.Singleton;
import org.jclouds.azure.storage.blob.AzureBlobAsyncClient; import org.jclouds.azure.storage.blob.AzureBlobAsyncClient;
import org.jclouds.azure.storage.blob.AzureBlobClient; import org.jclouds.azure.storage.blob.AzureBlobClient;
import org.jclouds.azure.storage.blob.blobstore.AzureAsyncBlobStore; import org.jclouds.azure.storage.blob.blobstore.AzureAsyncBlobStore;
import org.jclouds.azure.storage.blob.blobstore.AzureBlobRequestSigner;
import org.jclouds.azure.storage.blob.blobstore.AzureBlobStore; import org.jclouds.azure.storage.blob.blobstore.AzureBlobStore;
import org.jclouds.azure.storage.blob.blobstore.strategy.FindMD5InBlobProperties; import org.jclouds.azure.storage.blob.blobstore.strategy.FindMD5InBlobProperties;
import org.jclouds.blobstore.AsyncBlobStore; import org.jclouds.blobstore.AsyncBlobStore;
import org.jclouds.blobstore.BlobRequestSigner;
import org.jclouds.blobstore.BlobStore; import org.jclouds.blobstore.BlobStore;
import org.jclouds.blobstore.BlobStoreContext; import org.jclouds.blobstore.BlobStoreContext;
import org.jclouds.blobstore.attr.ConsistencyModel; import org.jclouds.blobstore.attr.ConsistencyModel;
@ -64,6 +66,7 @@ public class AzureBlobStoreContextModule extends AbstractModule {
bind(BlobStoreContext.class).to(new TypeLiteral<BlobStoreContextImpl<AzureBlobClient, AzureBlobAsyncClient>>() { bind(BlobStoreContext.class).to(new TypeLiteral<BlobStoreContextImpl<AzureBlobClient, AzureBlobAsyncClient>>() {
}).in(Scopes.SINGLETON); }).in(Scopes.SINGLETON);
bind(ContainsValueInListStrategy.class).to(FindMD5InBlobProperties.class); bind(ContainsValueInListStrategy.class).to(FindMD5InBlobProperties.class);
bind(BlobRequestSigner.class).to(AzureBlobRequestSigner.class);
} }
@Provides @Provides

View File

@ -88,14 +88,14 @@ public interface AzureQueueAsyncClient {
* @see AzureQueueClient#createQueue * @see AzureQueueClient#createQueue
*/ */
@PUT @PUT
@Path("{queue}") @Path("/{queue}")
ListenableFuture<Boolean> createQueue(@PathParam("queue") String queue, CreateOptions... options); ListenableFuture<Boolean> createQueue(@PathParam("queue") String queue, CreateOptions... options);
/** /**
* @see AzureQueueClient#getMessages * @see AzureQueueClient#getMessages
*/ */
@GET @GET
@Path("{queue}/messages") @Path("/{queue}/messages")
@XMLResponseParser(QueueMessagesListHandler.class) @XMLResponseParser(QueueMessagesListHandler.class)
ListenableFuture<Set<QueueMessage>> getMessages(@PathParam("queue") String queue, ListenableFuture<Set<QueueMessage>> getMessages(@PathParam("queue") String queue,
GetOptions... options); GetOptions... options);
@ -104,14 +104,14 @@ public interface AzureQueueAsyncClient {
* @see AzureQueueClient#deleteQueue * @see AzureQueueClient#deleteQueue
*/ */
@DELETE @DELETE
@Path("{queue}") @Path("/{queue}")
ListenableFuture<Void> deleteQueue(@PathParam("queue") String queue); ListenableFuture<Void> deleteQueue(@PathParam("queue") String queue);
/** /**
* @see AzureQueueClient#putMessage * @see AzureQueueClient#putMessage
*/ */
@POST @POST
@Path("{queue}/messages") @Path("/{queue}/messages")
ListenableFuture<Void> putMessage(@PathParam("queue") String queue, ListenableFuture<Void> putMessage(@PathParam("queue") String queue,
@BinderParam(BindToXmlStringPayload.class) String message, PutMessageOptions... options); @BinderParam(BindToXmlStringPayload.class) String message, PutMessageOptions... options);
@ -119,6 +119,6 @@ public interface AzureQueueAsyncClient {
* @see AzureQueueClient#clearMessages * @see AzureQueueClient#clearMessages
*/ */
@DELETE @DELETE
@Path("{queue}/messages") @Path("/{queue}/messages")
ListenableFuture<Void> clearMessages(@PathParam("queue") String queue); ListenableFuture<Void> clearMessages(@PathParam("queue") String queue);
} }

View File

@ -28,6 +28,7 @@ import java.lang.reflect.Method;
import java.util.Map; import java.util.Map;
import java.util.Properties; import java.util.Properties;
import org.jclouds.azure.storage.blob.functions.ParseBlobFromHeadersAndHttpContent;
import org.jclouds.azure.storage.blob.functions.ParseContainerPropertiesFromHeaders; import org.jclouds.azure.storage.blob.functions.ParseContainerPropertiesFromHeaders;
import org.jclouds.azure.storage.blob.functions.ReturnFalseIfContainerAlreadyExists; import org.jclouds.azure.storage.blob.functions.ReturnFalseIfContainerAlreadyExists;
import org.jclouds.azure.storage.blob.options.CreateContainerOptions; import org.jclouds.azure.storage.blob.options.CreateContainerOptions;
@ -37,11 +38,13 @@ import org.jclouds.azure.storage.blob.xml.ContainerNameEnumerationResultsHandler
import org.jclouds.azure.storage.filters.SharedKeyLiteAuthentication; import org.jclouds.azure.storage.filters.SharedKeyLiteAuthentication;
import org.jclouds.azure.storage.options.ListOptions; import org.jclouds.azure.storage.options.ListOptions;
import org.jclouds.blobstore.functions.ReturnNullOnContainerNotFound; import org.jclouds.blobstore.functions.ReturnNullOnContainerNotFound;
import org.jclouds.blobstore.functions.ReturnNullOnKeyNotFound;
import org.jclouds.http.HttpRequest; import org.jclouds.http.HttpRequest;
import org.jclouds.http.functions.ParseSax; import org.jclouds.http.functions.ParseSax;
import org.jclouds.http.functions.ReleasePayloadAndReturn; import org.jclouds.http.functions.ReleasePayloadAndReturn;
import org.jclouds.http.functions.ReturnTrueIf2xx; import org.jclouds.http.functions.ReturnTrueIf2xx;
import org.jclouds.http.functions.ReturnTrueOn404; import org.jclouds.http.functions.ReturnTrueOn404;
import org.jclouds.http.options.GetOptions;
import org.jclouds.rest.RestClientTest; import org.jclouds.rest.RestClientTest;
import org.jclouds.rest.RestContextFactory; import org.jclouds.rest.RestContextFactory;
import org.jclouds.rest.RestContextFactory.ContextSpec; import org.jclouds.rest.RestContextFactory.ContextSpec;
@ -140,7 +143,7 @@ public class AzureBlobAsyncClientTest extends RestClientTest<AzureBlobAsyncClien
HttpRequest request = processor.createRequest(method); HttpRequest request = processor.createRequest(method);
assertRequestLineEquals(request, "PUT https://identity.blob.core.windows.net/%24root?restype=container HTTP/1.1"); assertRequestLineEquals(request, "PUT https://identity.blob.core.windows.net/$root?restype=container HTTP/1.1");
assertNonPayloadHeadersEqual(request, "x-ms-version: 2009-09-19\n"); assertNonPayloadHeadersEqual(request, "x-ms-version: 2009-09-19\n");
assertPayloadEquals(request, null, null, false); assertPayloadEquals(request, null, null, false);
@ -153,8 +156,7 @@ public class AzureBlobAsyncClientTest extends RestClientTest<AzureBlobAsyncClien
Method method = AzureBlobAsyncClient.class.getMethod("deleteRootContainer"); Method method = AzureBlobAsyncClient.class.getMethod("deleteRootContainer");
HttpRequest request = processor.createRequest(method); HttpRequest request = processor.createRequest(method);
assertRequestLineEquals(request, assertRequestLineEquals(request, "DELETE https://identity.blob.core.windows.net/$root?restype=container HTTP/1.1");
"DELETE https://identity.blob.core.windows.net/%24root?restype=container HTTP/1.1");
assertNonPayloadHeadersEqual(request, "x-ms-version: 2009-09-19\n"); assertNonPayloadHeadersEqual(request, "x-ms-version: 2009-09-19\n");
assertPayloadEquals(request, null, null, false); assertPayloadEquals(request, null, null, false);
@ -168,7 +170,7 @@ public class AzureBlobAsyncClientTest extends RestClientTest<AzureBlobAsyncClien
HttpRequest request = processor.createRequest(method, withPublicAcl().withMetadata( HttpRequest request = processor.createRequest(method, withPublicAcl().withMetadata(
ImmutableMultimap.of("foo", "bar"))); ImmutableMultimap.of("foo", "bar")));
assertRequestLineEquals(request, "PUT https://identity.blob.core.windows.net/%24root?restype=container HTTP/1.1"); assertRequestLineEquals(request, "PUT https://identity.blob.core.windows.net/$root?restype=container HTTP/1.1");
assertNonPayloadHeadersEqual(request, assertNonPayloadHeadersEqual(request,
"x-ms-meta-foo: bar\nx-ms-prop-publicaccess: true\nx-ms-version: 2009-09-19\n"); "x-ms-meta-foo: bar\nx-ms-prop-publicaccess: true\nx-ms-version: 2009-09-19\n");
assertPayloadEquals(request, null, null, false); assertPayloadEquals(request, null, null, false);
@ -197,7 +199,7 @@ public class AzureBlobAsyncClientTest extends RestClientTest<AzureBlobAsyncClien
HttpRequest request = processor.createRequest(method); HttpRequest request = processor.createRequest(method);
assertRequestLineEquals(request, assertRequestLineEquals(request,
"GET https://identity.blob.core.windows.net/%24root?restype=container&comp=list HTTP/1.1"); "GET https://identity.blob.core.windows.net/$root?restype=container&comp=list HTTP/1.1");
assertNonPayloadHeadersEqual(request, "x-ms-version: 2009-09-19\n"); assertNonPayloadHeadersEqual(request, "x-ms-version: 2009-09-19\n");
assertPayloadEquals(request, null, null, false); assertPayloadEquals(request, null, null, false);
@ -235,6 +237,19 @@ public class AzureBlobAsyncClientTest extends RestClientTest<AzureBlobAsyncClien
assertExceptionParserClassEquals(method, null); assertExceptionParserClassEquals(method, null);
} }
public void testGetBlob() throws SecurityException, NoSuchMethodException, IOException {
Method method = AzureBlobAsyncClient.class.getMethod("getBlob", String.class, String.class, GetOptions[].class);
HttpRequest request = processor.createRequest(method, "container", "blob");
assertRequestLineEquals(request, "GET https://identity.blob.core.windows.net/container/blob HTTP/1.1");
assertNonPayloadHeadersEqual(request, "x-ms-version: 2009-09-19\n");
assertPayloadEquals(request, null, null, false);
assertResponseParserClassEquals(method, request, ParseBlobFromHeadersAndHttpContent.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, ReturnNullOnKeyNotFound.class);
}
public void testSetBlobMetadata() throws SecurityException, NoSuchMethodException, IOException { public void testSetBlobMetadata() throws SecurityException, NoSuchMethodException, IOException {
Method method = AzureBlobAsyncClient.class.getMethod("setBlobMetadata", String.class, String.class, Map.class); Method method = AzureBlobAsyncClient.class.getMethod("setBlobMetadata", String.class, String.class, Map.class);
HttpRequest request = processor.createRequest(method, "container", "blob", ImmutableMap.of("key", "value")); HttpRequest request = processor.createRequest(method, "container", "blob", ImmutableMap.of("key", "value"));

View File

@ -166,7 +166,7 @@ public class AzureBlobClientLiveTest {
} }
} }
ListBlobsResponse list = client.listBlobs(); ListBlobsResponse list = client.listBlobs();
assertEquals(list.getUrl(), URI.create(String.format("https://%s.blob.core.windows.net/%%24root", identity))); assertEquals(list.getUrl(), URI.create(String.format("https://%s.blob.core.windows.net/$root", identity)));
} }
@Test @Test

View File

@ -0,0 +1,139 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.azure.storage.blob.blobstore;
import static org.testng.Assert.assertEquals;
import java.io.IOException;
import java.util.Properties;
import org.jclouds.azure.storage.blob.AzureBlobAsyncClient;
import org.jclouds.azure.storage.blob.config.AzureBlobRestClientModule;
import org.jclouds.blobstore.BlobRequestSigner;
import org.jclouds.blobstore.domain.Blob;
import org.jclouds.blobstore.domain.Blob.Factory;
import org.jclouds.date.TimeStamp;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.RequiresHttp;
import org.jclouds.io.payloads.PhantomPayload;
import org.jclouds.rest.ConfiguresRestClient;
import org.jclouds.rest.RestClientTest;
import org.jclouds.rest.RestContextFactory;
import org.jclouds.rest.RestContextFactory.ContextSpec;
import org.jclouds.rest.internal.RestAnnotationProcessor;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import com.google.common.base.Supplier;
import com.google.inject.Module;
import com.google.inject.TypeLiteral;
@Test(groups = "unit", testName = "s3.AzureBlobBlobRequestSignerTest")
public class AzureBlobBlobRequestSignerTest extends RestClientTest<AzureBlobAsyncClient> {
private BlobRequestSigner signer;
private Factory blobFactory;
public void testSignGetBlob() throws ArrayIndexOutOfBoundsException, SecurityException, IllegalArgumentException,
NoSuchMethodException, IOException {
HttpRequest request = signer.signGetBlob("container", "name");
assertRequestLineEquals(request, "GET https://identity.blob.core.windows.net/container/name HTTP/1.1");
assertNonPayloadHeadersEqual(
request,
"Authorization: SharedKeyLite identity:nI6ca9CdLWhPoMuSzk4perqx5pzi2hx7YBJ92FCqeXM=\nDate: Thu, 05 Jun 2008 16:38:19 GMT\nx-ms-version: 2009-09-19\n");
assertPayloadEquals(request, null, null, false);
assertEquals(request.getFilters().size(), 0);
}
public void testSignRemoveBlob() throws ArrayIndexOutOfBoundsException, SecurityException, IllegalArgumentException,
NoSuchMethodException, IOException {
HttpRequest request = signer.signRemoveBlob("container", "name");
assertRequestLineEquals(request, "DELETE https://identity.blob.core.windows.net/container/name HTTP/1.1");
assertNonPayloadHeadersEqual(
request,
"Authorization: SharedKeyLite identity:+BDU2AGqS9LwevaKH+jaRKNrxTZ3LsFDpnnWFKpN0jc=\nDate: Thu, 05 Jun 2008 16:38:19 GMT\nx-ms-version: 2009-09-19\n");
assertPayloadEquals(request, null, null, false);
assertEquals(request.getFilters().size(), 0);
}
public void testSignPutBlob() throws ArrayIndexOutOfBoundsException, SecurityException, IllegalArgumentException,
NoSuchMethodException, IOException {
Blob blob = blobFactory.create(null);
blob.getMetadata().setName("name");
blob.setPayload(new PhantomPayload(2l, new byte[] { 0, 2, 4, 8 }));
blob.getPayload().setContentType("text/plain");
HttpRequest request = signer.signPutBlob("container", blob);
assertRequestLineEquals(request, "PUT https://identity.blob.core.windows.net/container/name HTTP/1.1");
assertNonPayloadHeadersEqual(
request,
"Authorization: SharedKeyLite identity:LT+HBNzhbRsZY07kC+/JxeuAURbxTmwJaIe464LO36c=\nDate: Thu, 05 Jun 2008 16:38:19 GMT\nx-ms-blob-type: BlockBlob\nx-ms-version: 2009-09-19\n");
assertContentHeadersEqual(request, "text/plain", (long) 2l, new byte[] { 0, 2, 4, 8 });
assertEquals(request.getFilters().size(), 0);
}
@BeforeClass
protected void setupFactory() throws IOException {
super.setupFactory();
this.blobFactory = injector.getInstance(Blob.Factory.class);
this.signer = injector.getInstance(BlobRequestSigner.class);
}
@Override
protected void checkFilters(HttpRequest request) {
}
@Override
protected TypeLiteral<RestAnnotationProcessor<AzureBlobAsyncClient>> createTypeLiteral() {
return new TypeLiteral<RestAnnotationProcessor<AzureBlobAsyncClient>>() {
};
}
@Override
protected Module createModule() {
return new TestAzureBlobRestClientModule();
}
@RequiresHttp
@ConfiguresRestClient
private static final class TestAzureBlobRestClientModule extends AzureBlobRestClientModule {
@Override
protected void configure() {
super.configure();
}
@Override
protected String provideTimeStamp(@TimeStamp Supplier<String> cache) {
return "Thu, 05 Jun 2008 16:38:19 GMT";
}
}
@Override
public ContextSpec<?, ?> createContextSpec() {
return new RestContextFactory().createContextSpec("azureblob", "identity", "credential", new Properties());
}
}

View File

@ -0,0 +1,32 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.azure.storage.blob.blobstore.integration;
import org.jclouds.blobstore.integration.internal.BaseBlobSignerLiveTest;
import org.testng.annotations.Test;
/**
*
* @author Adrian Cole
*/
@Test(groups = { "live" }, testName = "azureblob.AzureBlobSignerLiveTest")
public class AzureBlobSignerLiveTest extends BaseBlobSignerLiveTest {
}

View File

@ -21,7 +21,7 @@
"A clojure binding for the jclouds BlobStore. "A clojure binding for the jclouds BlobStore.
Current supported services are: Current supported services are:
[s3, azureblob, atmos, cloudfiles, walrus, googlestorage] [transient, filesystem, s3, azureblob, atmos, cloudfiles, walrus, googlestorage]
Here's a quick example of how to viewresources in rackspace Here's a quick example of how to viewresources in rackspace
@ -44,10 +44,11 @@ See http://code.google.com/p/jclouds for details."
AsyncBlobStore BlobStore BlobStoreContext BlobStoreContextFactory AsyncBlobStore BlobStore BlobStoreContext BlobStoreContextFactory
domain.BlobMetadata domain.StorageMetadata domain.Blob domain.BlobMetadata domain.StorageMetadata domain.Blob
options.ListContainerOptions] options.ListContainerOptions]
[org.jclouds.io Payloads] org.jclouds.io.Payloads
[java.util Arrays] org.jclouds.io.payloads.PhantomPayload
java.util.Arrays
[java.security DigestOutputStream MessageDigest] [java.security DigestOutputStream MessageDigest]
[com.google.common.collect ImmutableSet])) com.google.common.collect.ImmutableSet))
(try (try
(require '[clojure.contrib.io :as io]) (require '[clojure.contrib.io :as io])
@ -238,6 +239,54 @@ Options can also be specified for extension modules
([container-name path #^BlobStore blobstore] ([container-name path #^BlobStore blobstore]
(.getBlob blobstore container-name path))) (.getBlob blobstore container-name path)))
(defn sign-get-blob-request
"Get a signed http request for a blob, so that you can retrieve it
in another application. ex. curl"
([container-name path]
(sign-get-blob-request container-name path *blobstore*))
([container-name path #^BlobStore blobstore]
(.signGetBlob (.. blobstore getContext getSigner) container-name path)))
(defn sign-remove-blob-request
"Get a signed http request for deleting a blob in another application.
ex. curl"
([container-name path]
(sign-remove-blob-request container-name path *blobstore*))
([container-name path #^BlobStore blobstore]
(.signRemoveBlob (.. blobstore getContext getSigner) container-name path)))
(defn sign-put-blob-request
"Get a signed http request for uploading a blob in another application.
ex. curl"
([container-name path content-type size]
(sign-put-blob-request container-name path content-type size *blobstore*))
([container-name path content-type size #^BlobStore blobstore]
(.signPutBlob (.. blobstore getContext getSigner) container-name
(doto (.newBlob blobstore path)
(.setPayload (doto
;; until we pass content md5
(PhantomPayload. (long size) nil)
(.setContentType content-type)))))))
(defn sign-blob-request
"Get a signed http request for manipulating a blob in another application.
ex. curl"
([container-name path
{:keys [method content-type content-length content-md5] :as request}]
(sign-blob-request container-name path request *blobstore*))
([container-name path
{:keys [method content-type content-length content-md5]} blobstore]
{:pre [(or content-length (#{:delete :get} method))]}
(case method
:delete (sign-remove-blob-request container-name path blobstore)
:get (sign-get-blob-request container-name path blobstore)
:put (.signPutBlob
(.. blobstore getContext getSigner) container-name
(doto (.newBlob blobstore path)
(.setPayload
(doto (PhantomPayload. (long content-length) content-md5)
(.setContentType content-type))))))))
(defn get-blob-stream (defn get-blob-stream
"Get an inputstream from the blob at a given path" "Get an inputstream from the blob at a given path"
([container-name path] ([container-name path]

View File

@ -20,7 +20,6 @@
package org.jclouds.blobstore; package org.jclouds.blobstore;
import java.util.Set; import java.util.Set;
import com.google.common.util.concurrent.ListenableFuture;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@ -32,6 +31,8 @@ import org.jclouds.blobstore.options.GetOptions;
import org.jclouds.blobstore.options.ListContainerOptions; import org.jclouds.blobstore.options.ListContainerOptions;
import org.jclouds.domain.Location; import org.jclouds.domain.Location;
import com.google.common.util.concurrent.ListenableFuture;
/** /**
* Provides hooks needed to run a blob store asynchronously * Provides hooks needed to run a blob store asynchronously
* *

View File

@ -0,0 +1,83 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.blobstore;
import org.jclouds.blobstore.domain.Blob;
import org.jclouds.blobstore.internal.RequestSigningUnsupported;
import org.jclouds.http.HttpRequest;
import org.jclouds.io.payloads.PhantomPayload;
import com.google.inject.ImplementedBy;
/**
* Generates signed requests for blobs. useful in other tools such as backup utilities.
*
* @author Adrian Cole
*/
@ImplementedBy(RequestSigningUnsupported.class)
public interface BlobRequestSigner {
/**
* gets a signed request, including headers as necessary, to access a blob from an external
* client.
*
* @param container
* container where the blob resides
* @param directory
* full path to the blob
* @throws UnsupportedOperationException
* if not supported by the provider
*/
HttpRequest signGetBlob(String container, String name);
/**
* gets a signed request, including headers as necessary, to delete a blob from an external
* client.
*
* @param container
* container where the blob resides
* @param directory
* full path to the blob
* @throws UnsupportedOperationException
* if not supported by the provider
*/
HttpRequest signRemoveBlob(String container, String name);
/**
* gets a signed request, including headers as necessary, to upload a blob from an external
* client.
*
* <pre>
* Blob blob = context.getBlobStore.newBlob();
* blob.getMetadata().setName(&quot;name&quot;);
* blob.setPayload(new PhantomPayload(length, md5));
* blob.getPayload().setContentType(&quot;text/plain&quot;);
* </pre>
*
* @param container
* container where the blob resides
* @param blob
* what to upload
* @throws UnsupportedOperationException
* if not supported by the provider
* @see PhantomPayload
*/
HttpRequest signPutBlob(String container, Blob blob);
}

View File

@ -36,6 +36,12 @@ import com.google.inject.ImplementedBy;
*/ */
@ImplementedBy(BlobStoreContextImpl.class) @ImplementedBy(BlobStoreContextImpl.class)
public interface BlobStoreContext { public interface BlobStoreContext {
/**
*
* Generates signed requests for blobs. useful in other tools such as backup utilities.
*
*/
BlobRequestSigner getSigner();
/** /**
* Creates a <code>Map<String,InputStream></code> view of the specified container. Use this for * Creates a <code>Map<String,InputStream></code> view of the specified container. Use this for

View File

@ -0,0 +1,79 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.blobstore;
import static com.google.common.base.Preconditions.checkNotNull;
import java.net.URI;
import javax.inject.Inject;
import javax.inject.Singleton;
import javax.ws.rs.core.HttpHeaders;
import org.jclouds.blobstore.domain.Blob;
import org.jclouds.crypto.CryptoStreams;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.filters.BasicAuthentication;
/**
*
* @author Adrian Cole
*/
@Singleton
public class TransientBlobRequestSigner implements BlobRequestSigner {
private final BasicAuthentication basicAuth;
@Inject
public TransientBlobRequestSigner(BasicAuthentication basicAuth) {
this.basicAuth = checkNotNull(basicAuth, "basicAuth");
}
@Override
public HttpRequest signGetBlob(String container, String name) {
HttpRequest request = new HttpRequest("GET", URI.create(String.format("http://localhost/%s/%s", container, name)));
basicAuth.filter(request);
return request;
}
@Override
public HttpRequest signPutBlob(String container, Blob blob) {
HttpRequest request = new HttpRequest("PUT", URI.create(String.format("http://localhost/%s/%s", container, blob
.getMetadata().getName())));
if (blob.getPayload().getContentLength() != null)
request.getHeaders().put(HttpHeaders.CONTENT_LENGTH, blob.getPayload().getContentLength().toString());
if (blob.getPayload().getContentType() != null)
request.getHeaders().put(HttpHeaders.CONTENT_TYPE, blob.getPayload().getContentType());
if (blob.getPayload().getContentMD5() != null)
request.getHeaders().put("Content-MD5", CryptoStreams.base64(blob.getPayload().getContentMD5()));
request.setPayload(blob.getPayload());
basicAuth.filter(request);
return request;
}
@Override
public HttpRequest signRemoveBlob(String container, String name) {
HttpRequest request = new HttpRequest("DELETE", URI.create(String.format("http://localhost/%s/%s", container,
name)));
basicAuth.filter(request);
return request;
}
}

View File

@ -26,9 +26,11 @@ import java.util.concurrent.ConcurrentMap;
import javax.inject.Singleton; import javax.inject.Singleton;
import org.jclouds.blobstore.AsyncBlobStore; import org.jclouds.blobstore.AsyncBlobStore;
import org.jclouds.blobstore.BlobRequestSigner;
import org.jclouds.blobstore.BlobStore; import org.jclouds.blobstore.BlobStore;
import org.jclouds.blobstore.BlobStoreContext; import org.jclouds.blobstore.BlobStoreContext;
import org.jclouds.blobstore.TransientAsyncBlobStore; import org.jclouds.blobstore.TransientAsyncBlobStore;
import org.jclouds.blobstore.TransientBlobRequestSigner;
import org.jclouds.blobstore.attr.ConsistencyModel; import org.jclouds.blobstore.attr.ConsistencyModel;
import org.jclouds.blobstore.domain.Blob; import org.jclouds.blobstore.domain.Blob;
import org.jclouds.blobstore.internal.BlobStoreContextImpl; import org.jclouds.blobstore.internal.BlobStoreContextImpl;
@ -68,6 +70,7 @@ public class TransientBlobStoreContextModule extends AbstractModule {
install(new BlobStoreObjectModule()); install(new BlobStoreObjectModule());
install(new BlobStoreMapModule()); install(new BlobStoreMapModule());
bind(ConsistencyModel.class).toInstance(ConsistencyModel.STRICT); bind(ConsistencyModel.class).toInstance(ConsistencyModel.STRICT);
bind(BlobRequestSigner.class).to(TransientBlobRequestSigner.class);
} }
@Provides @Provides

View File

@ -266,4 +266,6 @@ public abstract class BaseAsyncBlobStore implements AsyncBlobStore {
} }
protected abstract boolean deleteAndVerifyContainerGone(String container); protected abstract boolean deleteAndVerifyContainerGone(String container);
} }

View File

@ -219,4 +219,5 @@ public abstract class BaseBlobStore implements BlobStore {
} }
protected abstract boolean deleteAndVerifyContainerGone(String container); protected abstract boolean deleteAndVerifyContainerGone(String container);
} }

View File

@ -26,6 +26,7 @@ import javax.inject.Singleton;
import org.jclouds.blobstore.AsyncBlobStore; import org.jclouds.blobstore.AsyncBlobStore;
import org.jclouds.blobstore.BlobMap; import org.jclouds.blobstore.BlobMap;
import org.jclouds.blobstore.BlobRequestSigner;
import org.jclouds.blobstore.BlobStore; import org.jclouds.blobstore.BlobStore;
import org.jclouds.blobstore.BlobStoreContext; import org.jclouds.blobstore.BlobStoreContext;
import org.jclouds.blobstore.InputStreamMap; import org.jclouds.blobstore.InputStreamMap;
@ -46,22 +47,23 @@ public class BlobStoreContextImpl<S, A> implements BlobStoreContext {
private final RestContext<S, A> providerSpecificContext; private final RestContext<S, A> providerSpecificContext;
private final ConsistencyModel consistencyModel; private final ConsistencyModel consistencyModel;
private final Utils utils; private final Utils utils;
private final BlobRequestSigner blobRequestSigner;
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@Inject @Inject
public BlobStoreContextImpl(BlobMap.Factory blobMapFactory, Utils utils, public BlobStoreContextImpl(BlobMap.Factory blobMapFactory, Utils utils, ConsistencyModel consistencyModel,
ConsistencyModel consistencyModel, InputStreamMap.Factory inputStreamMapFactory, InputStreamMap.Factory inputStreamMapFactory, AsyncBlobStore ablobStore, BlobStore blobStore,
AsyncBlobStore ablobStore, BlobStore blobStore, RestContext providerSpecificContext) { RestContext providerSpecificContext, BlobRequestSigner blobRequestSigner) {
// unravel guice and avoid passing in a million type args by not injecting generic types for // unravel guice and avoid passing in a million type args by not injecting generic types for
// rest context // rest context
this.providerSpecificContext = checkNotNull(providerSpecificContext, this.providerSpecificContext = checkNotNull(providerSpecificContext, "providerSpecificContext");
"providerSpecificContext");
this.consistencyModel = checkNotNull(consistencyModel, "consistencyModel"); this.consistencyModel = checkNotNull(consistencyModel, "consistencyModel");
this.blobMapFactory = checkNotNull(blobMapFactory, "blobMapFactory"); this.blobMapFactory = checkNotNull(blobMapFactory, "blobMapFactory");
this.inputStreamMapFactory = checkNotNull(inputStreamMapFactory, "inputStreamMapFactory"); this.inputStreamMapFactory = checkNotNull(inputStreamMapFactory, "inputStreamMapFactory");
this.ablobStore = checkNotNull(ablobStore, "ablobStore"); this.ablobStore = checkNotNull(ablobStore, "ablobStore");
this.blobStore = checkNotNull(blobStore, "blobStore"); this.blobStore = checkNotNull(blobStore, "blobStore");
this.utils = utils; this.utils = checkNotNull(utils, "utils");
this.blobRequestSigner = checkNotNull(blobRequestSigner, "blobRequestSigner");
} }
@Override @Override
@ -134,4 +136,9 @@ public class BlobStoreContextImpl<S, A> implements BlobStoreContext {
public boolean equals(Object obj) { public boolean equals(Object obj) {
return providerSpecificContext.equals(obj); return providerSpecificContext.equals(obj);
} }
@Override
public BlobRequestSigner getSigner() {
return blobRequestSigner;
}
} }

View File

@ -0,0 +1,50 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.blobstore.internal;
import javax.inject.Singleton;
import org.jclouds.blobstore.BlobRequestSigner;
import org.jclouds.blobstore.domain.Blob;
import org.jclouds.http.HttpRequest;
/**
*
* @author Adrian Cole
*/
@Singleton
public class RequestSigningUnsupported implements BlobRequestSigner {
@Override
public HttpRequest signGetBlob(String container, String name) {
throw new UnsupportedOperationException();
}
@Override
public HttpRequest signPutBlob(String container, Blob blob) {
throw new UnsupportedOperationException();
}
@Override
public HttpRequest signRemoveBlob(String container, String name) {
throw new UnsupportedOperationException();
}
}

View File

@ -37,14 +37,27 @@ import org.jclouds.blobstore.domain.Blob;
import org.jclouds.blobstore.domain.BlobMetadata; import org.jclouds.blobstore.domain.BlobMetadata;
import org.jclouds.blobstore.domain.StorageMetadata; import org.jclouds.blobstore.domain.StorageMetadata;
import org.jclouds.functions.ExceptionToValueOrPropagate; import org.jclouds.functions.ExceptionToValueOrPropagate;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.HttpRequestFilter;
import org.jclouds.http.HttpResponse; import org.jclouds.http.HttpResponse;
import org.jclouds.rest.internal.GeneratedHttpRequest; import org.jclouds.rest.internal.GeneratedHttpRequest;
import com.google.common.collect.ImmutableMultimap;
/** /**
* *
* @author Adrian Cole * @author Adrian Cole
*/ */
public class BlobStoreUtils { public class BlobStoreUtils {
public static <T> HttpRequest cleanRequest(GeneratedHttpRequest<T> returnVal) {
for (HttpRequestFilter filter : returnVal.getFilters())
filter.filter(returnVal);
HttpRequest toReturn = new HttpRequest(returnVal.getMethod(), returnVal.getEndpoint(), ImmutableMultimap
.copyOf(returnVal.getHeaders()));
if (returnVal.getPayload() != null)
toReturn.setPayload(returnVal.getPayload());
return toReturn;
}
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public static final ExceptionToValueOrPropagate keyNotFoundToNullOrPropagate = new ExceptionToValueOrPropagate( public static final ExceptionToValueOrPropagate keyNotFoundToNullOrPropagate = new ExceptionToValueOrPropagate(
@ -131,8 +144,7 @@ public class BlobStoreUtils {
} }
} }
public static void createParentIfNeededAsync(AsyncBlobStore asyncBlobStore, String container, public static void createParentIfNeededAsync(AsyncBlobStore asyncBlobStore, String container, Blob blob) {
Blob blob) {
String name = blob.getMetadata().getName(); String name = blob.getMetadata().getName();
if (name.indexOf('/') > 0) { if (name.indexOf('/') > 0) {
asyncBlobStore.createDirectory(container, parseDirectoryFromPath(name)); asyncBlobStore.createDirectory(container, parseDirectoryFromPath(name));

View File

@ -109,6 +109,27 @@
(download-blob container-name name data-file))) (download-blob container-name name data-file)))
(finally (.delete data-file)))))) (finally (.delete data-file))))))
;; this will fail until somebody fixes it!
#_
(deftest sing-put-blob-request-test
(let [request (sign-put-blob-request "container" "path" "text/plain" 10)]
(is (= "PUT" (.getMethod request)))
(is (= "10" (get "Content-Length" (.getHeaders request))))
(is (= "text/plain" (get "Content-Type" (.getHeaders request))))))
;; this will fail until somebody fixes it!
#_
(deftest sing-blob-request-test
(let [request (sign-blob-request "container" "path" {:method :delete})]
(is (= "DELETE" (.getMethod request))))
(let [request (sign-blob-request "container" "path" {:method :get})]
(is (= "GET" (.getMethod request))))
(let [request (sign-blob-request
"container" "path" {:method :put :content-length 10})]
(is (= "PUT" (.getMethod request)))
(is (= "10" (get "Content-Length" (.getHeaders request))))
(is (= "text/plain" (get "Content-Type" (.getHeaders request))))))
;; TODO: more tests involving blob-specific functions ;; TODO: more tests involving blob-specific functions
(deftest corruption-hunt (deftest corruption-hunt

View File

@ -0,0 +1,106 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.blobstore;
import static org.testng.Assert.assertEquals;
import java.io.IOException;
import java.util.Properties;
import org.jclouds.blobstore.domain.Blob;
import org.jclouds.blobstore.domain.Blob.Factory;
import org.jclouds.http.HttpRequest;
import org.jclouds.io.payloads.PhantomPayload;
import org.jclouds.rest.RestClientTest;
import org.jclouds.rest.RestContextFactory;
import org.jclouds.rest.RestContextFactory.ContextSpec;
import org.jclouds.rest.internal.RestAnnotationProcessor;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import com.google.inject.TypeLiteral;
@Test(groups = "unit", testName = "jclouds.TransientBlobRequestSignerTest")
public class TransientBlobRequestSignerTest extends RestClientTest<TransientAsyncBlobStore> {
private BlobRequestSigner signer;
private Factory blobFactory;
public void testSignGetBlob() throws ArrayIndexOutOfBoundsException, SecurityException, IllegalArgumentException,
NoSuchMethodException, IOException {
HttpRequest request = signer.signGetBlob("container", "name");
assertRequestLineEquals(request, "GET http://localhost/container/name HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Authorization: Basic aWRlbnRpdHk6Y3JlZGVudGlhbA==\n");
assertPayloadEquals(request, null, null, false);
assertEquals(request.getFilters().size(), 0);
}
public void testSignRemoveBlob() throws ArrayIndexOutOfBoundsException, SecurityException, IllegalArgumentException,
NoSuchMethodException, IOException {
HttpRequest request = signer.signRemoveBlob("container", "name");
assertRequestLineEquals(request, "DELETE http://localhost/container/name HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Authorization: Basic aWRlbnRpdHk6Y3JlZGVudGlhbA==\n");
assertPayloadEquals(request, null, null, false);
assertEquals(request.getFilters().size(), 0);
}
public void testSignPutBlob() throws ArrayIndexOutOfBoundsException, SecurityException, IllegalArgumentException,
NoSuchMethodException, IOException {
Blob blob = blobFactory.create(null);
blob.getMetadata().setName("name");
blob.setPayload(new PhantomPayload(2l, new byte[] { 0, 2, 4, 8 }));
blob.getPayload().setContentType("text/plain");
HttpRequest request = signer.signPutBlob("container", blob);
assertRequestLineEquals(request, "PUT http://localhost/container/name HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Authorization: Basic aWRlbnRpdHk6Y3JlZGVudGlhbA==\nContent-Length: 2\nContent-MD5: AAIECA==\nContent-Type: text/plain\n");
assertContentHeadersEqual(request, "text/plain", (long) 2l, new byte[] { 0, 2, 4, 8 });
assertEquals(request.getFilters().size(), 0);
}
@BeforeClass
protected void setupFactory() throws IOException {
super.setupFactory();
this.blobFactory = injector.getInstance(Blob.Factory.class);
this.signer = injector.getInstance(BlobRequestSigner.class);
}
@Override
protected void checkFilters(HttpRequest request) {
}
@Override
public ContextSpec<?, ?> createContextSpec() {
return new RestContextFactory().createContextSpec("transient", "identity", "credential", new Properties());
}
@Override
protected TypeLiteral<RestAnnotationProcessor<TransientAsyncBlobStore>> createTypeLiteral() {
return new TypeLiteral<RestAnnotationProcessor<TransientAsyncBlobStore>>() {
};
}
}

View File

@ -52,7 +52,7 @@ public class BaseBlobLiveTest extends BaseBlobStoreIntegrationTest {
httpStreamETag = checkNotNull(httpStreamETag != null ? httpStreamETag : sysHttpStreamETag, "httpStreamMd5"); httpStreamETag = checkNotNull(httpStreamETag != null ? httpStreamETag : sysHttpStreamETag, "httpStreamMd5");
String key = "hello"; String name = "hello";
URL url = new URL(httpStreamUrl); URL url = new URL(httpStreamUrl);
byte[] md5 = CryptoStreams.hex(httpStreamETag); byte[] md5 = CryptoStreams.hex(httpStreamETag);
@ -61,16 +61,17 @@ public class BaseBlobLiveTest extends BaseBlobStoreIntegrationTest {
long length = connection.getContentLength(); long length = connection.getContentLength();
InputStream input = connection.getInputStream(); InputStream input = connection.getInputStream();
Blob object = context.getBlobStore().newBlob(key); Blob blob = context.getBlobStore().newBlob(name);
object.setPayload(input); blob.setPayload(input);
object.getPayload().setContentLength(length); blob.getPayload().setContentLength(length);
object.getPayload().setContentMD5(md5); blob.getPayload().setContentMD5(md5);
String bucketName = getContainerName(); String container = getContainerName();
try { try {
context.getBlobStore().putBlob(bucketName, object); context.getBlobStore().putBlob(container, blob);
assertEquals(context.getBlobStore().blobMetadata(bucketName, key).getContentMD5(), md5); assertEquals(context.getBlobStore().blobMetadata(container, name).getContentMD5(), md5);
} finally { } finally {
returnContainer(bucketName); returnContainer(container);
} }
} }
} }

View File

@ -0,0 +1,97 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.blobstore.integration.internal;
import static org.testng.Assert.assertEquals;
import org.jclouds.blobstore.domain.Blob;
import org.jclouds.http.HttpRequest;
import org.jclouds.util.Utils;
import org.testng.annotations.Test;
/**
* Tests integrated functionality of all signature commands.
* <p/>
* Each test uses a different container name, so it should be perfectly fine to run in parallel.
*
* @author Adrian Cole
*/
@Test(groups = { "live" }, testName = "blobstore.BlobLiveTest")
public class BaseBlobSignerLiveTest extends BaseBlobStoreIntegrationTest {
@Test
public void testSignRemoveUrl() throws Exception {
String name = "hello";
String text = "fooooooooooooooooooooooo";
Blob blob = context.getBlobStore().newBlob(name);
blob.setPayload(text);
blob.getPayload().setContentType("text/plain");
String container = getContainerName();
try {
context.getBlobStore().putBlob(container, blob);
HttpRequest request = context.getSigner().signRemoveBlob(container, name);
assertEquals(request.getFilters().size(), 0);
context.utils().http().invoke(request);
assert !context.getBlobStore().blobExists(container, name);
} finally {
returnContainer(container);
}
}
@Test
public void testSignGetUrl() throws Exception {
String name = "hello";
String text = "fooooooooooooooooooooooo";
Blob blob = context.getBlobStore().newBlob(name);
blob.setPayload(text);
blob.getPayload().setContentType("text/plain");
String container = getContainerName();
try {
context.getBlobStore().putBlob(container, blob);
HttpRequest request = context.getSigner().signGetBlob(container, name);
assertEquals(request.getFilters().size(), 0);
assertEquals(Utils.toStringAndClose(context.utils().http().invoke(request)), text);
} finally {
returnContainer(container);
}
}
@Test
public void testSignPutUrl() throws Exception {
String name = "hello";
String text = "fooooooooooooooooooooooo";
Blob blob = context.getBlobStore().newBlob(name);
blob.setPayload(text);
blob.getPayload().setContentType("text/plain");
String container = getContainerName();
try {
HttpRequest request = context.getSigner().signPutBlob(container, blob);
assertEquals(request.getFilters().size(), 0);
Utils.toStringAndClose(context.utils().http().invoke(request));
assert context.getBlobStore().blobExists(container, name);
} finally {
returnContainer(container);
}
}
}

185
chef/compute/pom.xml Normal file
View File

@ -0,0 +1,185 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
$HeadURL$ $Revision$ $Date$ Copyright (C) 2010 Cloud Conscious,
LLC <info@cloudconscious.com>
====================================================================
Licensed to the Apache Software Foundation (ASF) under one or
more contributor license agreements. See the NOTICE file
distributed with this work for additional information regarding
copyright ownership. The ASF 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.html 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.
====================================================================
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.jclouds</groupId>
<artifactId>jclouds-chef-project</artifactId>
<version>1.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<groupId>org.jclouds</groupId>
<artifactId>jclouds-chef-compute</artifactId>
<name>jclouds chef compute integration</name>
<description>provisions nodes with jclouds and kick's off chef to configure and integrate</description>
<properties>
<!--
for example: ec2, trmk-ecloud, bluelock-vclouddirector,
cloudservers, etc
-->
<jclouds.compute.provider>YOUR_PREFERRED_PROVIDER</jclouds.compute.provider>
<!-- leave blank unless you have a different url to override -->
<jclouds.compute.endpoint></jclouds.compute.endpoint>
<jclouds.compute.identity>YOUR_ACCOUNT</jclouds.compute.identity>
<jclouds.compute.credential>YOUR_CREDENTIAL</jclouds.compute.credential>
<!-- tag for nodes used in the tests -->
<jclouds.compute.tag>jcloudschef</jclouds.compute.tag>
<jclouds.chef.identity>YOUR_USER</jclouds.chef.identity>
<jclouds.chef.credential.pem>${user.home}/.chef/${jclouds.chef.identity}.pem</jclouds.chef.credential.pem>
<jclouds.opscodeplatform.org>YOUR_ORG</jclouds.opscodeplatform.org>
<jclouds.chef.endpoint>https://api.opscode.com/organizations/${jclouds.opscodeplatform.org}</jclouds.chef.endpoint>
</properties>
<!-- bootstrapping: need to fetch the project POM -->
<repositories>
<repository>
<id>jclouds-googlecode-deploy</id>
<url>http://jclouds.googlecode.com/svn/repo</url>
</repository>
<repository>
<id>jclouds-rimu-snapshots-nexus</id>
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>jclouds-chef</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>jclouds-compute</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>jclouds-jsch</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>jclouds-log4j</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.14</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>jclouds-core</artifactId>
<version>${project.version}</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>jclouds-compute</artifactId>
<version>${project.version}</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>jclouds-allcompute</artifactId>
<version>${project.version}</version>
<scope>test</scope>
<optional>true</optional>
</dependency>
</dependencies>
<profiles>
<profile>
<id>live</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<executions>
<execution>
<id>integration</id>
<phase>integration-test</phase>
<goals>
<goal>test</goal>
</goals>
<configuration>
<excludes>
<exclude>none</exclude>
</excludes>
<includes>
<include>**/*LiveTest.java</include>
</includes>
<systemProperties>
<property>
<name>jclouds.compute.provider</name>
<value>${jclouds.compute.provider}</value>
</property>
<property>
<name>jclouds.compute.endpoint</name>
<value>${jclouds.compute.endpoint}</value>
</property>
<property>
<name>jclouds.compute.identity</name>
<value>${jclouds.compute.identity}</value>
</property>
<property>
<name>jclouds.compute.credential</name>
<value>${jclouds.compute.credential}</value>
</property>
<property>
<name>jclouds.compute.tag</name>
<value>${jclouds.compute.tag}</value>
</property>
<property>
<name>jclouds.compute.credential</name>
<value>${jclouds.compute.credential}</value>
</property>
<property>
<name>jclouds.chef.credential.pem</name>
<value>${jclouds.chef.credential.pem}</value>
</property>
<property>
<name>jclouds.chef.endpoint</name>
<value>${jclouds.chef.endpoint}</value>
</property>
</systemProperties>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>

View File

@ -0,0 +1,165 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.chef.compute;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.collect.Iterables.any;
import static com.google.common.collect.Iterables.concat;
import static com.google.common.collect.Iterables.getLast;
import static org.jclouds.chef.predicates.CookbookVersionPredicates.containsRecipe;
import static org.jclouds.chef.predicates.CookbookVersionPredicates.containsRecipes;
import static org.jclouds.compute.options.TemplateOptions.Builder.runScript;
import static org.testng.Assert.assertEquals;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.util.List;
import java.util.Properties;
import org.jclouds.chef.ChefContext;
import org.jclouds.chef.ChefContextFactory;
import org.jclouds.chef.domain.CookbookVersion;
import org.jclouds.chef.util.RunListBuilder;
import org.jclouds.compute.ComputeServiceContext;
import org.jclouds.compute.ComputeServiceContextFactory;
import org.jclouds.compute.RunNodesException;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.predicates.NodePredicates;
import org.jclouds.io.Payload;
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
import org.jclouds.ssh.jsch.config.JschSshClientModule;
import org.jclouds.util.Utils;
import org.testng.annotations.AfterGroups;
import org.testng.annotations.BeforeGroups;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableSet;
import com.google.inject.Module;
/**
*
* @author Adrian Cole
*/
@Test(groups = "live", testName = "chef.ChefComputeServiceLiveTest")
public class ChefComputeServiceLiveTest {
private ComputeServiceContext computeContext;
private ChefContext chefContext;
private String tag;
private String clientName;
private String chefEndpoint;
private Iterable<? extends NodeMetadata> nodes;
@BeforeGroups(groups = { "live" })
public void setupAll() throws FileNotFoundException, IOException {
tag = System.getProperty("jclouds.compute.tag") != null ? System.getProperty("jclouds.compute.tag")
: "jcloudschef";
String computeProvider = checkNotNull(System.getProperty("jclouds.compute.provider"), "jclouds.compute.provider");
String computeEndpoint = System.getProperty("jclouds.compute.endpoint");
String computeIdentity = checkNotNull(System.getProperty("jclouds.compute.identity"), "jclouds.compute.identity");
String computeCredential = checkNotNull(System.getProperty("jclouds.compute.credential"),
"jclouds.compute.credential");
chefEndpoint = checkNotNull(System.getProperty("jclouds.chef.endpoint"), "jclouds.chef.endpoint");
String chefIdentity = checkNotNull(System.getProperty("jclouds.chef.identity"), "jclouds.chef.identity");
String chefCredentialFile = System.getProperty("jclouds.chef.credential.pem");
if (chefCredentialFile == null || chefCredentialFile.equals(""))
chefCredentialFile = System.getProperty("user.home") + "/.chef/" + chefIdentity + ".pem";
Properties props = new Properties();
props.setProperty(computeProvider + ".identity", computeIdentity);
props.setProperty(computeProvider + ".credential", computeCredential);
props.setProperty("chef.endpoint", chefEndpoint);
props.setProperty("chef.identity", chefIdentity);
props.setProperty("chef.credential.file", chefCredentialFile);
if (computeEndpoint != null && !computeEndpoint.trim().equals(""))
props.setProperty(computeProvider + ".endpoint", computeEndpoint);
computeContext = new ComputeServiceContextFactory().createContext(computeProvider, ImmutableSet.of(
new Log4JLoggingModule(), getSshModule()), props);
chefContext = new ChefContextFactory().createContext(ImmutableSet.<Module> of(new Log4JLoggingModule()), props);
}
protected Module getSshModule() {
return new JschSshClientModule();
}
@Test
public void testCanUpdateRunList() throws IOException {
String recipe = "apache2";
Iterable<? extends CookbookVersion> cookbookVersions = chefContext.getChefService().listCookbookVersions();
if (any(cookbookVersions, containsRecipe(recipe))) {
List<String> runList = new RunListBuilder().addRecipe(recipe).build();
chefContext.getChefService().updateRunListForTag(runList, tag);
assertEquals(chefContext.getChefService().getRunListForTag(tag), runList);
} else {
assert false : String.format("recipe %s not in %s", recipe, cookbookVersions);
}
// TODO move this to a unit test
assert any(cookbookVersions, containsRecipe("apache2::mod_proxy"));
assert any(cookbookVersions, containsRecipes("apache2", "apache2::mod_proxy", "apache2::mod_proxy_http"));
assert !any(cookbookVersions, containsRecipe("apache2::bar"));
assert !any(cookbookVersions, containsRecipe("foo::bar"));
}
@Test(dependsOnMethods = "testCanUpdateRunList")
public void testRunNodesWithBootstrap() throws IOException {
Payload bootstrap = chefContext.getChefService().createClientAndBootstrapScriptForTag(tag);
try {
nodes = computeContext.getComputeService().runNodesWithTag(tag, 1, runScript(bootstrap));
} catch (RunNodesException e) {
nodes = concat(e.getSuccessfulNodes(), e.getNodeErrors().keySet());
}
for (NodeMetadata node : nodes) {
URI uri = URI.create("http://" + getLast(node.getPublicAddresses()));
InputStream content = computeContext.utils().http().get(uri);
String string = Utils.toStringAndClose(content);
assert string.indexOf("It works!") >= 0 : string;
}
}
@AfterGroups(groups = { "live" })
public void teardownCompute() {
if (computeContext != null) {
computeContext.getComputeService().destroyNodesMatching(NodePredicates.withTag(tag));
computeContext.close();
}
}
@AfterGroups(groups = { "live" })
public void teardownChef() {
if (chefContext != null) {
chefContext.getChefService().cleanupStaleNodesAndClients(tag + "-", 1);
if (clientName != null && chefContext.getApi().clientExists(clientName))
chefContext.getApi().deleteClient(clientName);
chefContext.close();
}
}
}

View File

@ -0,0 +1,203 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (C) 2009 Cloud Conscious, LLC.
<info@cloudconscious.com>
====================================================================
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0 Unless required by
applicable law or agreed to in writing, software distributed
under the License is distributed on an "AS IS" BASIS, WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions
and limitations under the License.
====================================================================
-->
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<!--
For more configuration infromation and examples see the Apache
Log4j website: http://logging.apache.org/log4j/
-->
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/"
debug="false">
<!-- A time/date based rolling appender -->
<appender name="COMPUTEFILE" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="target/test-data/jclouds-compute.log" />
<param name="Append" value="true" />
<!-- Rollover at midnight each day -->
<param name="DatePattern" value="'.'yyyy-MM-dd" />
<param name="Threshold" value="TRACE" />
<layout class="org.apache.log4j.PatternLayout">
<!-- The default pattern: Date Priority [Category] Message\n -->
<param name="ConversionPattern" value="%d %-5p [%c] (%t) %m%n" />
<!--
The full pattern: Date MS Priority [Category]
(Thread:NDC) Message\n <param name="ConversionPattern"
value="%d %-5r %-5p [%c] (%t:%x) %m%n"/>
-->
</layout>
</appender>
<!-- A time/date based rolling appender -->
<appender name="SSHFILE" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="target/test-data/jclouds-ssh.log" />
<param name="Append" value="true" />
<!-- Rollover at midnight each day -->
<param name="DatePattern" value="'.'yyyy-MM-dd" />
<param name="Threshold" value="TRACE" />
<layout class="org.apache.log4j.PatternLayout">
<!-- The default pattern: Date Priority [Category] Message\n -->
<param name="ConversionPattern" value="%d %-5p [%c] (%t) %m%n" />
<!--
The full pattern: Date MS Priority [Category]
(Thread:NDC) Message\n <param name="ConversionPattern"
value="%d %-5r %-5p [%c] (%t:%x) %m%n"/>
-->
</layout>
</appender>
<!-- A time/date based rolling appender -->
<appender name="CHEFFILE" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="target/test-data/jclouds-chef.log" />
<param name="Append" value="true" />
<!-- Rollover at midnight each day -->
<param name="DatePattern" value="'.'yyyy-MM-dd" />
<param name="Threshold" value="TRACE" />
<layout class="org.apache.log4j.PatternLayout">
<!-- The default pattern: Date Priority [Category] Message\n -->
<param name="ConversionPattern" value="%d %-5p [%c] (%t) %m%n" />
<!--
The full pattern: Date MS Priority [Category]
(Thread:NDC) Message\n <param name="ConversionPattern"
value="%d %-5r %-5p [%c] (%t:%x) %m%n"/>
-->
</layout>
</appender>
<!-- A time/date based rolling appender -->
<appender name="WIREFILE" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="target/test-data/jclouds-wire.log" />
<param name="Append" value="true" />
<!-- Rollover at midnight each day -->
<param name="DatePattern" value="'.'yyyy-MM-dd" />
<param name="Threshold" value="TRACE" />
<layout class="org.apache.log4j.PatternLayout">
<!-- The default pattern: Date Priority [Category] Message\n -->
<param name="ConversionPattern" value="%d %-5p [%c] (%t) %m%n" />
<!--
The full pattern: Date MS Priority [Category]
(Thread:NDC) Message\n <param name="ConversionPattern"
value="%d %-5r %-5p [%c] (%t:%x) %m%n"/>
-->
</layout>
</appender>
<!-- A time/date based rolling appender -->
<appender name="FILE" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="target/test-data/jclouds.log" />
<param name="Append" value="true" />
<!-- Rollover at midnight each day -->
<param name="DatePattern" value="'.'yyyy-MM-dd" />
<param name="Threshold" value="TRACE" />
<layout class="org.apache.log4j.PatternLayout">
<!-- The default pattern: Date Priority [Category] Message\n -->
<param name="ConversionPattern" value="%d %-5p [%c] (%t) %m%n" />
<!--
The full pattern: Date MS Priority [Category]
(Thread:NDC) Message\n <param name="ConversionPattern"
value="%d %-5r %-5p [%c] (%t:%x) %m%n"/>
-->
</layout>
</appender>
<appender name="ASYNCCOMPUTE" class="org.apache.log4j.AsyncAppender">
<appender-ref ref="COMPUTEFILE" />
</appender>
<appender name="ASYNCCHEF" class="org.apache.log4j.AsyncAppender">
<appender-ref ref="CHEFFILE" />
</appender>
<appender name="ASYNCSSH" class="org.apache.log4j.AsyncAppender">
<appender-ref ref="SSHFILE" />
</appender>
<appender name="ASYNC" class="org.apache.log4j.AsyncAppender">
<appender-ref ref="FILE" />
</appender>
<appender name="ASYNCWIRE" class="org.apache.log4j.AsyncAppender">
<appender-ref ref="WIREFILE" />
</appender>
<!-- ================ -->
<!-- Limit categories -->
<!-- ================ -->
<category name="org.jclouds">
<priority value="DEBUG" />
<appender-ref ref="ASYNC" />
</category>
<category name="jclouds.headers">
<priority value="DEBUG" />
<appender-ref ref="ASYNCWIRE" />
</category>
<category name="jclouds.wire">
<priority value="DEBUG" />
<appender-ref ref="ASYNCWIRE" />
</category>
<category name="jclouds.chef">
<priority value="TRACE" />
<appender-ref ref="ASYNCCHEF" />
</category>
<category name="jclouds.ssh">
<priority value="DEBUG" />
<appender-ref ref="ASYNCSSH" />
</category>
<category name="jclouds.compute">
<priority value="TRACE" />
<appender-ref ref="ASYNCCOMPUTE" />
</category>
<!--
<category name="jclouds.wire"> <priority value="DEBUG" />
<appender-ref ref="ASYNCWIRE" /> </category> <category
name="jclouds.signature"> <priority value="DEBUG" />
<appender-ref ref="ASYNCWIRE" /> </category>
-->
<!-- ======================= -->
<!-- Setup the Root category -->
<!-- ======================= -->
<root>
<priority value="WARN" />
</root>
</log4j:configuration>

View File

@ -1,21 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!-- <!--
Copyright (C) 2010 Cloud Conscious, LLC <info@cloudconscious.com> Copyright (C) 2010 Cloud Conscious, LLC
<info@cloudconscious.com>
==================================================================== ====================================================================
Licensed to the Apache Software Foundation (ASF) under one or more Licensed to the Apache Software Foundation (ASF) under one or
contributor license agreements. See the NOTICE file distributed with more contributor license agreements. See the NOTICE file
this work for additional information regarding copyright ownership. distributed with this work for additional information regarding
The ASF licenses this file to you under the Apache License, Version copyright ownership. The ASF licenses this file to you under the
2.0 (the "License"); you may not use this file except in compliance Apache License, Version 2.0 (the "License"); you may not use
with the License. You may obtain a copy of the License at 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.html Unless required by http://www.apache.org/licenses/LICENSE-2.0.html Unless required
applicable law or agreed to in writing, software distributed under the by applicable law or agreed to in writing, software distributed
License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR under the License is distributed on an "AS IS" BASIS, WITHOUT
CONDITIONS OF ANY KIND, either express or implied. See the License for WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
the specific language governing permissions and limitations under the See the License for the specific language governing permissions
License. and limitations under the License.
==================================================================== ====================================================================
--> -->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
@ -25,7 +27,7 @@
<groupId>org.jclouds</groupId> <groupId>org.jclouds</groupId>
<artifactId>jclouds-chef-project</artifactId> <artifactId>jclouds-chef-project</artifactId>
<version>1.0-SNAPSHOT</version> <version>1.0-SNAPSHOT</version>
<relativePath>../project/pom.xml</relativePath> <relativePath>../pom.xml</relativePath>
</parent> </parent>
<groupId>org.jclouds</groupId> <groupId>org.jclouds</groupId>
<artifactId>jclouds-chef</artifactId> <artifactId>jclouds-chef</artifactId>
@ -49,7 +51,7 @@
</repository> </repository>
<repository> <repository>
<id>jclouds-rimu-snapshots-nexus</id> <id>jclouds-rimu-snapshots-nexus</id>
<url>http://jclouds.rimuhosting.com:8081/nexus/content/repositories/snapshots</url> <url>https://oss.sonatype.org/content/repositories/snapshots</url>
<snapshots> <snapshots>
<enabled>true</enabled> <enabled>true</enabled>
</snapshots> </snapshots>
@ -71,6 +73,17 @@
<artifactId>jclouds-core</artifactId> <artifactId>jclouds-core</artifactId>
<version>${project.version}</version> <version>${project.version}</version>
</dependency> </dependency>
<!-- only required for Pems.java and only writing a private key file -->
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15</artifactId>
<version>1.44</version>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>jclouds-scriptbuilder</artifactId>
<version>${project.version}</version>
</dependency>
<dependency> <dependency>
<groupId>${project.groupId}</groupId> <groupId>${project.groupId}</groupId>
<artifactId>jclouds-core</artifactId> <artifactId>jclouds-core</artifactId>

View File

@ -129,7 +129,55 @@ unit testing"
"Retrieve the existing nodes in your chef server including all details." "Retrieve the existing nodes in your chef server including all details."
([] (nodes *chef*)) ([] (nodes *chef*))
([#^ChefService chef] ([#^ChefService chef]
(seq (.listNodesDetails chef)))) (seq (.listNodes chef))))
(defn clients
"Retrieve the names of the existing clients in your chef server."
([] (clients *chef*))
([#^ChefService chef]
(seq (.listClients (as-chef-api chef)))))
(defn clients-with-details
"Retrieve the existing clients in your chef server including all details."
([] (clients *chef*))
([#^ChefService chef]
(seq (.listClients chef))))
(defn cookbooks
"Retrieve the names of the existing cookbooks in your chef server."
([] (cookbooks *chef*))
([#^ChefService chef]
(seq (.listCookbooks (as-chef-api chef)))))
(defn cookbook-versions
"Retrieve the versions of an existing cookbook in your chef server."
([name] (cookbook-versions *chef*))
([#^ChefService name chef]
(seq (.getVersionsOfCookbook (as-chef-api chef) name))))
(defn cookbook-versions-with-details
"Retrieve the existing cookbook versions in your chef server including all details."
([] (cookbook-versions *chef*))
([#^ChefService chef]
(seq (.listCookbookVersions chef))))
(defn update-run-list
"Updates the run-list associated with a tag"
([run-list tag] (update-run-list run-list tag *chef*))
([run-list tag #^ChefService chef]
(.updateRunListForTag chef run-list tag)))
(defn run-list
"Retrieves the run-list associated with a tag"
([tag] (run-list tag *chef*))
([tag #^ChefService chef]
(seq (.getRunListForTag chef tag))))
(defn create-bootstrap
"creates a client and bootstrap script associated with a tag"
([tag] (create-bootstrap tag *chef*))
([tag #^ChefService chef]
(.createClientAndBootstrapScriptForTag chef tag)))
(defn databags (defn databags
"Retrieve the names of the existing data bags in your chef server." "Retrieve the names of the existing data bags in your chef server."

View File

@ -87,18 +87,19 @@ public interface ChefAsyncClient {
* @see ChefClient#getUploadSandboxForChecksums * @see ChefClient#getUploadSandboxForChecksums
*/ */
@POST @POST
@Path("sandboxes") @Path("/sandboxes")
ListenableFuture<UploadSandbox> getUploadSandboxForChecksums( ListenableFuture<UploadSandbox> getUploadSandboxForChecksums(
@BinderParam(BindChecksumsToJsonPayload.class) Set<List<Byte>> md5s); @BinderParam(BindChecksumsToJsonPayload.class) Set<List<Byte>> md5s);
@PUT @PUT
@Path("")
ListenableFuture<Void> uploadContent(@BinderParam(BindChecksumsToJsonPayload.class) Set<List<Byte>> md5s); ListenableFuture<Void> uploadContent(@BinderParam(BindChecksumsToJsonPayload.class) Set<List<Byte>> md5s);
/** /**
* @see ChefClient#commitSandbox * @see ChefClient#commitSandbox
*/ */
@PUT @PUT
@Path("sandboxes/{id}") @Path("/sandboxes/{id}")
ListenableFuture<Sandbox> commitSandbox(@PathParam("id") String id, ListenableFuture<Sandbox> commitSandbox(@PathParam("id") String id,
@BinderParam(BindIsCompletedToJsonPayload.class) boolean isCompleted); @BinderParam(BindIsCompletedToJsonPayload.class) boolean isCompleted);
@ -106,7 +107,7 @@ public interface ChefAsyncClient {
* @see ChefCookbooks#listCookbooks * @see ChefCookbooks#listCookbooks
*/ */
@GET @GET
@Path("cookbooks") @Path("/cookbooks")
@ResponseParser(ParseKeySetFromJson.class) @ResponseParser(ParseKeySetFromJson.class)
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class) @ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
ListenableFuture<Set<String>> listCookbooks(); ListenableFuture<Set<String>> listCookbooks();
@ -115,7 +116,7 @@ public interface ChefAsyncClient {
* @see ChefClient#updateCookbook * @see ChefClient#updateCookbook
*/ */
@PUT @PUT
@Path("cookbooks/{cookbookname}/{version}") @Path("/cookbooks/{cookbookname}/{version}")
ListenableFuture<CookbookVersion> updateCookbook(@PathParam("cookbookname") String cookbookName, ListenableFuture<CookbookVersion> updateCookbook(@PathParam("cookbookname") String cookbookName,
@PathParam("version") String version, @BinderParam(BindToJsonPayload.class) CookbookVersion cookbook); @PathParam("version") String version, @BinderParam(BindToJsonPayload.class) CookbookVersion cookbook);
@ -123,7 +124,7 @@ public interface ChefAsyncClient {
* @see ChefCookbook#deleteCookbook(String) * @see ChefCookbook#deleteCookbook(String)
*/ */
@DELETE @DELETE
@Path("cookbooks/{cookbookname}/{version}") @Path("/cookbooks/{cookbookname}/{version}")
@ExceptionParser(ReturnNullOnNotFoundOr404.class) @ExceptionParser(ReturnNullOnNotFoundOr404.class)
ListenableFuture<CookbookVersion> deleteCookbook(@PathParam("cookbookname") String cookbookName, ListenableFuture<CookbookVersion> deleteCookbook(@PathParam("cookbookname") String cookbookName,
@PathParam("version") String version); @PathParam("version") String version);
@ -132,7 +133,7 @@ public interface ChefAsyncClient {
* @see ChefCookbook#getVersionsOfCookbook * @see ChefCookbook#getVersionsOfCookbook
*/ */
@GET @GET
@Path("cookbooks/{cookbookname}") @Path("/cookbooks/{cookbookname}")
@Unwrap @Unwrap
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class) @ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
ListenableFuture<Set<String>> getVersionsOfCookbook(@PathParam("cookbookname") String cookbookName); ListenableFuture<Set<String>> getVersionsOfCookbook(@PathParam("cookbookname") String cookbookName);
@ -141,7 +142,7 @@ public interface ChefAsyncClient {
* @see ChefCookbook#getCookbook * @see ChefCookbook#getCookbook
*/ */
@GET @GET
@Path("cookbooks/{cookbookname}/{version}") @Path("/cookbooks/{cookbookname}/{version}")
@ExceptionParser(ReturnNullOnNotFoundOr404.class) @ExceptionParser(ReturnNullOnNotFoundOr404.class)
ListenableFuture<CookbookVersion> getCookbook(@PathParam("cookbookname") String cookbookName, ListenableFuture<CookbookVersion> getCookbook(@PathParam("cookbookname") String cookbookName,
@PathParam("version") String version); @PathParam("version") String version);
@ -150,14 +151,14 @@ public interface ChefAsyncClient {
* @see ChefClient#createClient * @see ChefClient#createClient
*/ */
@POST @POST
@Path("clients") @Path("/clients")
ListenableFuture<Client> createClient(@BinderParam(BindClientnameToJsonPayload.class) String clientname); ListenableFuture<Client> createClient(@BinderParam(BindClientnameToJsonPayload.class) String clientname);
/** /**
* @see ChefClient#generateKeyForClient * @see ChefClient#generateKeyForClient
*/ */
@PUT @PUT
@Path("clients/{clientname}") @Path("/clients/{clientname}")
ListenableFuture<Client> generateKeyForClient( ListenableFuture<Client> generateKeyForClient(
@PathParam("clientname") @BinderParam(BindGenerateKeyForClientToJsonPayload.class) String clientname); @PathParam("clientname") @BinderParam(BindGenerateKeyForClientToJsonPayload.class) String clientname);
@ -165,7 +166,7 @@ public interface ChefAsyncClient {
* @see ChefClient#clientExists * @see ChefClient#clientExists
*/ */
@HEAD @HEAD
@Path("clients/{clientname}") @Path("/clients/{clientname}")
@ExceptionParser(ReturnFalseOnNotFoundOr404.class) @ExceptionParser(ReturnFalseOnNotFoundOr404.class)
ListenableFuture<Boolean> clientExists(@PathParam("clientname") String clientname); ListenableFuture<Boolean> clientExists(@PathParam("clientname") String clientname);
@ -173,7 +174,7 @@ public interface ChefAsyncClient {
* @see ChefClient#getClient * @see ChefClient#getClient
*/ */
@GET @GET
@Path("clients/{clientname}") @Path("/clients/{clientname}")
@ExceptionParser(ReturnNullOnNotFoundOr404.class) @ExceptionParser(ReturnNullOnNotFoundOr404.class)
ListenableFuture<Client> getClient(@PathParam("clientname") String clientname); ListenableFuture<Client> getClient(@PathParam("clientname") String clientname);
@ -181,7 +182,7 @@ public interface ChefAsyncClient {
* @see ChefClient#deleteClient * @see ChefClient#deleteClient
*/ */
@DELETE @DELETE
@Path("clients/{clientname}") @Path("/clients/{clientname}")
@ExceptionParser(ReturnNullOnNotFoundOr404.class) @ExceptionParser(ReturnNullOnNotFoundOr404.class)
ListenableFuture<Client> deleteClient(@PathParam("clientname") String clientname); ListenableFuture<Client> deleteClient(@PathParam("clientname") String clientname);
@ -189,7 +190,7 @@ public interface ChefAsyncClient {
* @see ChefClient#listClients * @see ChefClient#listClients
*/ */
@GET @GET
@Path("clients") @Path("/clients")
@ResponseParser(ParseKeySetFromJson.class) @ResponseParser(ParseKeySetFromJson.class)
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class) @ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
ListenableFuture<Set<String>> listClients(); ListenableFuture<Set<String>> listClients();
@ -198,14 +199,14 @@ public interface ChefAsyncClient {
* @see ChefClient#createNode * @see ChefClient#createNode
*/ */
@POST @POST
@Path("nodes") @Path("/nodes")
ListenableFuture<Void> createNode(@BinderParam(BindToJsonPayload.class) Node node); ListenableFuture<Void> createNode(@BinderParam(BindToJsonPayload.class) Node node);
/** /**
* @see ChefClient#updateNode * @see ChefClient#updateNode
*/ */
@PUT @PUT
@Path("nodes/{nodename}") @Path("/nodes/{nodename}")
ListenableFuture<Node> updateNode( ListenableFuture<Node> updateNode(
@PathParam("nodename") @ParamParser(NodeName.class) @BinderParam(BindToJsonPayload.class) Node node); @PathParam("nodename") @ParamParser(NodeName.class) @BinderParam(BindToJsonPayload.class) Node node);
@ -213,7 +214,7 @@ public interface ChefAsyncClient {
* @see ChefNode#nodeExists * @see ChefNode#nodeExists
*/ */
@HEAD @HEAD
@Path("nodes/{nodename}") @Path("/nodes/{nodename}")
@ExceptionParser(ReturnFalseOnNotFoundOr404.class) @ExceptionParser(ReturnFalseOnNotFoundOr404.class)
ListenableFuture<Boolean> nodeExists(@PathParam("nodename") String nodename); ListenableFuture<Boolean> nodeExists(@PathParam("nodename") String nodename);
@ -221,7 +222,7 @@ public interface ChefAsyncClient {
* @see ChefNode#getNode * @see ChefNode#getNode
*/ */
@GET @GET
@Path("nodes/{nodename}") @Path("/nodes/{nodename}")
@ExceptionParser(ReturnNullOnNotFoundOr404.class) @ExceptionParser(ReturnNullOnNotFoundOr404.class)
ListenableFuture<Node> getNode(@PathParam("nodename") String nodename); ListenableFuture<Node> getNode(@PathParam("nodename") String nodename);
@ -229,7 +230,7 @@ public interface ChefAsyncClient {
* @see ChefNode#deleteNode * @see ChefNode#deleteNode
*/ */
@DELETE @DELETE
@Path("nodes/{nodename}") @Path("/nodes/{nodename}")
@ExceptionParser(ReturnNullOnNotFoundOr404.class) @ExceptionParser(ReturnNullOnNotFoundOr404.class)
ListenableFuture<Node> deleteNode(@PathParam("nodename") String nodename); ListenableFuture<Node> deleteNode(@PathParam("nodename") String nodename);
@ -237,7 +238,7 @@ public interface ChefAsyncClient {
* @see ChefNode#listNodes * @see ChefNode#listNodes
*/ */
@GET @GET
@Path("nodes") @Path("/nodes")
@ResponseParser(ParseKeySetFromJson.class) @ResponseParser(ParseKeySetFromJson.class)
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class) @ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
ListenableFuture<Set<String>> listNodes(); ListenableFuture<Set<String>> listNodes();
@ -246,14 +247,14 @@ public interface ChefAsyncClient {
* @see ChefClient#createRole * @see ChefClient#createRole
*/ */
@POST @POST
@Path("roles") @Path("/roles")
ListenableFuture<Void> createRole(@BinderParam(BindToJsonPayload.class) Role role); ListenableFuture<Void> createRole(@BinderParam(BindToJsonPayload.class) Role role);
/** /**
* @see ChefClient#updateRole * @see ChefClient#updateRole
*/ */
@PUT @PUT
@Path("roles/{rolename}") @Path("/roles/{rolename}")
ListenableFuture<Role> updateRole( ListenableFuture<Role> updateRole(
@PathParam("rolename") @ParamParser(RoleName.class) @BinderParam(BindToJsonPayload.class) Role role); @PathParam("rolename") @ParamParser(RoleName.class) @BinderParam(BindToJsonPayload.class) Role role);
@ -261,7 +262,7 @@ public interface ChefAsyncClient {
* @see ChefRole#roleExists * @see ChefRole#roleExists
*/ */
@HEAD @HEAD
@Path("roles/{rolename}") @Path("/roles/{rolename}")
@ExceptionParser(ReturnFalseOnNotFoundOr404.class) @ExceptionParser(ReturnFalseOnNotFoundOr404.class)
ListenableFuture<Boolean> roleExists(@PathParam("rolename") String rolename); ListenableFuture<Boolean> roleExists(@PathParam("rolename") String rolename);
@ -269,7 +270,7 @@ public interface ChefAsyncClient {
* @see ChefRole#getRole * @see ChefRole#getRole
*/ */
@GET @GET
@Path("roles/{rolename}") @Path("/roles/{rolename}")
@ExceptionParser(ReturnNullOnNotFoundOr404.class) @ExceptionParser(ReturnNullOnNotFoundOr404.class)
ListenableFuture<Role> getRole(@PathParam("rolename") String rolename); ListenableFuture<Role> getRole(@PathParam("rolename") String rolename);
@ -277,7 +278,7 @@ public interface ChefAsyncClient {
* @see ChefRole#deleteRole * @see ChefRole#deleteRole
*/ */
@DELETE @DELETE
@Path("roles/{rolename}") @Path("/roles/{rolename}")
@ExceptionParser(ReturnNullOnNotFoundOr404.class) @ExceptionParser(ReturnNullOnNotFoundOr404.class)
ListenableFuture<Role> deleteRole(@PathParam("rolename") String rolename); ListenableFuture<Role> deleteRole(@PathParam("rolename") String rolename);
@ -285,7 +286,7 @@ public interface ChefAsyncClient {
* @see ChefRole#listRoles * @see ChefRole#listRoles
*/ */
@GET @GET
@Path("roles") @Path("/roles")
@ResponseParser(ParseKeySetFromJson.class) @ResponseParser(ParseKeySetFromJson.class)
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class) @ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
ListenableFuture<Set<String>> listRoles(); ListenableFuture<Set<String>> listRoles();
@ -294,7 +295,7 @@ public interface ChefAsyncClient {
* @see ChefClient#listDatabags * @see ChefClient#listDatabags
*/ */
@GET @GET
@Path("data") @Path("/data")
@ResponseParser(ParseKeySetFromJson.class) @ResponseParser(ParseKeySetFromJson.class)
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class) @ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
ListenableFuture<Set<String>> listDatabags(); ListenableFuture<Set<String>> listDatabags();
@ -303,14 +304,14 @@ public interface ChefAsyncClient {
* @see ChefClient#createDatabag * @see ChefClient#createDatabag
*/ */
@POST @POST
@Path("data") @Path("/data")
ListenableFuture<Void> createDatabag(@BinderParam(BindNameToJsonPayload.class) String databagName); ListenableFuture<Void> createDatabag(@BinderParam(BindNameToJsonPayload.class) String databagName);
/** /**
* @see ChefClient#databagExists * @see ChefClient#databagExists
*/ */
@HEAD @HEAD
@Path("data/{name}") @Path("/data/{name}")
@ExceptionParser(ReturnFalseOnNotFoundOr404.class) @ExceptionParser(ReturnFalseOnNotFoundOr404.class)
ListenableFuture<Boolean> databagExists(@PathParam("name") String databagName); ListenableFuture<Boolean> databagExists(@PathParam("name") String databagName);
@ -318,7 +319,7 @@ public interface ChefAsyncClient {
* @see ChefClient#deleteDatabag * @see ChefClient#deleteDatabag
*/ */
@DELETE @DELETE
@Path("data/{name}") @Path("/data/{name}")
@ExceptionParser(ReturnVoidOnNotFoundOr404.class) @ExceptionParser(ReturnVoidOnNotFoundOr404.class)
ListenableFuture<Void> deleteDatabag(@PathParam("name") String databagName); ListenableFuture<Void> deleteDatabag(@PathParam("name") String databagName);
@ -326,7 +327,7 @@ public interface ChefAsyncClient {
* @see ChefClient#listDatabagItems * @see ChefClient#listDatabagItems
*/ */
@GET @GET
@Path("data/{name}") @Path("/data/{name}")
@ResponseParser(ParseKeySetFromJson.class) @ResponseParser(ParseKeySetFromJson.class)
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class) @ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
ListenableFuture<Set<String>> listDatabagItems(@PathParam("name") String databagName); ListenableFuture<Set<String>> listDatabagItems(@PathParam("name") String databagName);
@ -335,7 +336,7 @@ public interface ChefAsyncClient {
* @see ChefClient#createDatabagItem * @see ChefClient#createDatabagItem
*/ */
@POST @POST
@Path("data/{databagName}") @Path("/data/{databagName}")
ListenableFuture<DatabagItem> createDatabagItem(@PathParam("databagName") String databagName, ListenableFuture<DatabagItem> createDatabagItem(@PathParam("databagName") String databagName,
@BinderParam(BindToJsonPayload.class) DatabagItem databagItem); @BinderParam(BindToJsonPayload.class) DatabagItem databagItem);
@ -343,7 +344,7 @@ public interface ChefAsyncClient {
* @see ChefClient#updateDatabagItem * @see ChefClient#updateDatabagItem
*/ */
@PUT @PUT
@Path("data/{databagName}/{databagItemId}") @Path("/data/{databagName}/{databagItemId}")
ListenableFuture<DatabagItem> updateDatabagItem( ListenableFuture<DatabagItem> updateDatabagItem(
@PathParam("databagName") String databagName, @PathParam("databagName") String databagName,
@PathParam("databagItemId") @ParamParser(DatabagItemId.class) @BinderParam(BindToJsonPayload.class) DatabagItem item); @PathParam("databagItemId") @ParamParser(DatabagItemId.class) @BinderParam(BindToJsonPayload.class) DatabagItem item);
@ -352,7 +353,7 @@ public interface ChefAsyncClient {
* @see ChefClient#databagItemExists * @see ChefClient#databagItemExists
*/ */
@HEAD @HEAD
@Path("data/{databagName}/{databagItemId}") @Path("/data/{databagName}/{databagItemId}")
@ExceptionParser(ReturnFalseOnNotFoundOr404.class) @ExceptionParser(ReturnFalseOnNotFoundOr404.class)
ListenableFuture<Boolean> databagItemExists(@PathParam("databagName") String databagName, ListenableFuture<Boolean> databagItemExists(@PathParam("databagName") String databagName,
@PathParam("databagItemId") String databagItemId); @PathParam("databagItemId") String databagItemId);
@ -361,7 +362,7 @@ public interface ChefAsyncClient {
* @see ChefClient#getDatabagItem * @see ChefClient#getDatabagItem
*/ */
@GET @GET
@Path("data/{databagName}/{databagItemId}") @Path("/data/{databagName}/{databagItemId}")
@ExceptionParser(ReturnNullOnNotFoundOr404.class) @ExceptionParser(ReturnNullOnNotFoundOr404.class)
ListenableFuture<DatabagItem> getDatabagItem(@PathParam("databagName") String databagName, ListenableFuture<DatabagItem> getDatabagItem(@PathParam("databagName") String databagName,
@PathParam("databagItemId") String databagItemId); @PathParam("databagItemId") String databagItemId);
@ -370,7 +371,7 @@ public interface ChefAsyncClient {
* @see ChefClient#deleteDatabagItem * @see ChefClient#deleteDatabagItem
*/ */
@DELETE @DELETE
@Path("data/{databagName}/{databagItemId}") @Path("/data/{databagName}/{databagItemId}")
@ExceptionParser(ReturnNullOnNotFoundOr404.class) @ExceptionParser(ReturnNullOnNotFoundOr404.class)
ListenableFuture<DatabagItem> deleteDatabagItem(@PathParam("databagName") String databagName, ListenableFuture<DatabagItem> deleteDatabagItem(@PathParam("databagName") String databagName,
@PathParam("databagItemId") String databagItemId); @PathParam("databagItemId") String databagItemId);
@ -379,7 +380,7 @@ public interface ChefAsyncClient {
* @see ChefClient#listSearchIndexes * @see ChefClient#listSearchIndexes
*/ */
@GET @GET
@Path("search") @Path("/search")
@ResponseParser(ParseKeySetFromJson.class) @ResponseParser(ParseKeySetFromJson.class)
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class) @ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
ListenableFuture<Set<String>> listSearchIndexes(); ListenableFuture<Set<String>> listSearchIndexes();
@ -388,7 +389,7 @@ public interface ChefAsyncClient {
* @see ChefClient#searchRoles * @see ChefClient#searchRoles
*/ */
@GET @GET
@Path("search/role") @Path("/search/role")
@ResponseParser(ParseSearchRolesFromJson.class) @ResponseParser(ParseSearchRolesFromJson.class)
ListenableFuture<? extends SearchResult<? extends Role>> searchRoles(); ListenableFuture<? extends SearchResult<? extends Role>> searchRoles();
@ -396,7 +397,7 @@ public interface ChefAsyncClient {
* @see ChefClient#searchClients * @see ChefClient#searchClients
*/ */
@GET @GET
@Path("search/client") @Path("/search/client")
@ResponseParser(ParseSearchClientsFromJson.class) @ResponseParser(ParseSearchClientsFromJson.class)
ListenableFuture<? extends SearchResult<? extends Client>> searchClients(); ListenableFuture<? extends SearchResult<? extends Client>> searchClients();
@ -404,7 +405,7 @@ public interface ChefAsyncClient {
* @see ChefClient#searchNodes * @see ChefClient#searchNodes
*/ */
@GET @GET
@Path("search/node") @Path("/search/node")
@ResponseParser(ParseSearchNodesFromJson.class) @ResponseParser(ParseSearchNodesFromJson.class)
ListenableFuture<? extends SearchResult<? extends Node>> searchNodes(); ListenableFuture<? extends SearchResult<? extends Node>> searchNodes();
@ -412,7 +413,7 @@ public interface ChefAsyncClient {
* @see ChefClient#searchDatabag * @see ChefClient#searchDatabag
*/ */
@GET @GET
@Path("search/{databagName}") @Path("/search/{databagName}")
@ResponseParser(ParseSearchDatabagFromJson.class) @ResponseParser(ParseSearchDatabagFromJson.class)
ListenableFuture<? extends SearchResult<? extends DatabagItem>> searchDatabag( ListenableFuture<? extends SearchResult<? extends DatabagItem>> searchDatabag(
@PathParam("databagName") String databagName); @PathParam("databagName") String databagName);

Some files were not shown because too many files have changed in this diff Show More