Issue 130, Issue 29: normalize location, called Region in amazon speak, restructured domain model across compute and blobstore

git-svn-id: http://jclouds.googlecode.com/svn/trunk@2658 3d8758e0-26b5-11de-8745-db77d3ebf521
This commit is contained in:
adrian.f.cole 2010-01-15 23:13:35 +00:00
parent bc334b9447
commit d8e6c0e248
137 changed files with 2109 additions and 1593 deletions

View File

@ -32,7 +32,7 @@ import javax.ws.rs.core.MediaType;
import org.jclouds.atmosonline.saas.binders.BindAtmosObjectToPayloadAndMetadataToHeaders;
import org.jclouds.atmosonline.saas.domain.AtmosObject;
import org.jclouds.atmosonline.saas.domain.BoundedSortedSet;
import org.jclouds.atmosonline.saas.domain.BoundedSet;
import org.jclouds.atmosonline.saas.domain.DirectoryEntry;
import org.jclouds.atmosonline.saas.domain.SystemMetadata;
import org.jclouds.atmosonline.saas.domain.UserMetadata;
@ -84,7 +84,7 @@ public interface AtmosStorageAsyncClient {
@Path("/rest/namespace")
@ResponseParser(ParseDirectoryListFromContentAndHeaders.class)
@Consumes(MediaType.TEXT_XML)
ListenableFuture<? extends BoundedSortedSet<? extends DirectoryEntry>> listDirectories(
ListenableFuture<? extends BoundedSet<? extends DirectoryEntry>> listDirectories(
ListOptions... options);
/**
@ -95,7 +95,7 @@ public interface AtmosStorageAsyncClient {
@ResponseParser(ParseDirectoryListFromContentAndHeaders.class)
@ExceptionParser(ThrowContainerNotFoundOn404.class)
@Consumes(MediaType.TEXT_XML)
ListenableFuture<? extends BoundedSortedSet<? extends DirectoryEntry>> listDirectory(
ListenableFuture<? extends BoundedSet<? extends DirectoryEntry>> listDirectory(
@PathParam("directoryName") String directoryName, ListOptions... options);
/**

View File

@ -22,7 +22,7 @@ import java.net.URI;
import java.util.concurrent.TimeUnit;
import org.jclouds.atmosonline.saas.domain.AtmosObject;
import org.jclouds.atmosonline.saas.domain.BoundedSortedSet;
import org.jclouds.atmosonline.saas.domain.BoundedSet;
import org.jclouds.atmosonline.saas.domain.DirectoryEntry;
import org.jclouds.atmosonline.saas.domain.SystemMetadata;
import org.jclouds.atmosonline.saas.domain.UserMetadata;
@ -43,9 +43,9 @@ public interface AtmosStorageClient {
AtmosObject newObject();
BoundedSortedSet<? extends DirectoryEntry> listDirectories(ListOptions... options);
BoundedSet<? extends DirectoryEntry> listDirectories(ListOptions... options);
BoundedSortedSet<? extends DirectoryEntry> listDirectory(String directoryName,
BoundedSet<? extends DirectoryEntry> listDirectory(String directoryName,
ListOptions... options);
URI createDirectory(String directoryName);

View File

@ -43,7 +43,7 @@ import org.jclouds.blobstore.domain.Blob;
import org.jclouds.blobstore.domain.BlobMetadata;
import org.jclouds.blobstore.domain.ListContainerResponse;
import org.jclouds.blobstore.domain.ListResponse;
import org.jclouds.blobstore.domain.ResourceMetadata;
import org.jclouds.blobstore.domain.StorageMetadata;
import org.jclouds.blobstore.domain.Blob.Factory;
import org.jclouds.blobstore.functions.BlobToHttpGetOptions;
import org.jclouds.blobstore.strategy.ClearListStrategy;
@ -101,7 +101,10 @@ public class AtmosAsyncBlobStore extends BaseAtmosBlobStore implements AsyncBlob
}));
}
public ListenableFuture<Boolean> createContainer(String container) {
/**
* Note that location is currently ignored.
*/
public ListenableFuture<Boolean> createContainerInLocation(String location, String container) {
return compose(async.createDirectory(container), new Function<URI, Boolean>() {
public Boolean apply(URI from) {
@ -155,11 +158,11 @@ public class AtmosAsyncBlobStore extends BaseAtmosBlobStore implements AsyncBlob
return compose(returnVal, object2Blob, service);
}
public ListenableFuture<? extends ListResponse<? extends ResourceMetadata>> list() {
public ListenableFuture<? extends ListResponse<? extends StorageMetadata>> list() {
return compose(async.listDirectories(), container2ResourceList, service);
}
public ListenableFuture<? extends ListContainerResponse<? extends ResourceMetadata>> list(
public ListenableFuture<? extends ListContainerResponse<? extends StorageMetadata>> list(
String container, org.jclouds.blobstore.options.ListContainerOptions... optionsList) {
if (optionsList.length == 1) {
if (optionsList[0].isRecursive()) {

View File

@ -38,7 +38,7 @@ import org.jclouds.blobstore.domain.Blob;
import org.jclouds.blobstore.domain.BlobMetadata;
import org.jclouds.blobstore.domain.ListContainerResponse;
import org.jclouds.blobstore.domain.ListResponse;
import org.jclouds.blobstore.domain.ResourceMetadata;
import org.jclouds.blobstore.domain.StorageMetadata;
import org.jclouds.blobstore.domain.Blob.Factory;
import org.jclouds.blobstore.functions.BlobToHttpGetOptions;
import org.jclouds.blobstore.strategy.ClearListStrategy;
@ -59,7 +59,8 @@ public class AtmosBlobStore extends BaseAtmosBlobStore implements BlobStore {
ObjectToBlob object2Blob, BlobToObject blob2Object,
BlobStoreListOptionsToListOptions container2ContainerListOptions,
BlobToHttpGetOptions blob2ObjectGetOptions,
DirectoryEntryListToResourceMetadataList container2ResourceList, ExecutorService service,EncryptionService encryptionService) {
DirectoryEntryListToResourceMetadataList container2ResourceList,
ExecutorService service, EncryptionService encryptionService) {
super(async, sync, blobFactory, logFactory, clearContainerStrategy, object2BlobMd,
object2Blob, blob2Object, container2ContainerListOptions, blob2ObjectGetOptions,
container2ResourceList, service);
@ -77,7 +78,10 @@ public class AtmosBlobStore extends BaseAtmosBlobStore implements BlobStore {
clearContainerStrategy.execute(container, recursive());
}
public boolean createContainer(String container) {
/**
* Note that location is currently ignored.
*/
public boolean createContainerInLocation(String location, String container) {
sync.createDirectory(container);
return true;// no etag
}
@ -120,11 +124,11 @@ public class AtmosBlobStore extends BaseAtmosBlobStore implements BlobStore {
return object2Blob.apply(sync.readFile(container + "/" + key, httpOptions));
}
public ListResponse<? extends ResourceMetadata> list() {
public ListResponse<? extends StorageMetadata> list() {
return container2ResourceList.apply(sync.listDirectories());
}
public ListContainerResponse<? extends ResourceMetadata> list(String container,
public ListContainerResponse<? extends StorageMetadata> list(String container,
org.jclouds.blobstore.options.ListContainerOptions... optionsList) {
if (optionsList.length == 1) {
if (optionsList[0].isRecursive()) {

View File

@ -20,15 +20,15 @@ package org.jclouds.atmosonline.saas.blobstore.functions;
import javax.inject.Singleton;
import org.jclouds.atmosonline.saas.domain.BoundedSortedSet;
import org.jclouds.atmosonline.saas.domain.BoundedSet;
import org.jclouds.atmosonline.saas.domain.DirectoryEntry;
import org.jclouds.atmosonline.saas.domain.FileType;
import org.jclouds.blobstore.domain.ListContainerResponse;
import org.jclouds.blobstore.domain.ResourceMetadata;
import org.jclouds.blobstore.domain.ResourceType;
import org.jclouds.blobstore.domain.StorageMetadata;
import org.jclouds.blobstore.domain.StorageType;
import org.jclouds.blobstore.domain.internal.BlobMetadataImpl;
import org.jclouds.blobstore.domain.internal.ListContainerResponseImpl;
import org.jclouds.blobstore.domain.internal.ResourceMetadataImpl;
import org.jclouds.blobstore.domain.internal.StorageMetadataImpl;
import com.google.common.base.Function;
import com.google.common.collect.Iterables;
@ -40,24 +40,24 @@ import com.google.common.collect.Maps;
@Singleton
public class DirectoryEntryListToResourceMetadataList
implements
Function<BoundedSortedSet<? extends DirectoryEntry>, ListContainerResponse<? extends ResourceMetadata>> {
Function<BoundedSet<? extends DirectoryEntry>, ListContainerResponse<? extends StorageMetadata>> {
public ListContainerResponse<? extends ResourceMetadata> apply(
BoundedSortedSet<? extends DirectoryEntry> from) {
public ListContainerResponse<? extends StorageMetadata> apply(
BoundedSet<? extends DirectoryEntry> from) {
return new ListContainerResponseImpl<ResourceMetadata>(Iterables.transform(from,
new Function<DirectoryEntry, ResourceMetadata>() {
return new ListContainerResponseImpl<StorageMetadata>(Iterables.transform(from,
new Function<DirectoryEntry, StorageMetadata>() {
public ResourceMetadata apply(DirectoryEntry from) {
ResourceType type = from.getType() == FileType.DIRECTORY ? ResourceType.FOLDER
: ResourceType.BLOB;
if (type == ResourceType.FOLDER)
return new ResourceMetadataImpl(type, from.getObjectID(), from
.getObjectName(), null, null, null, null, Maps
public StorageMetadata apply(DirectoryEntry from) {
StorageType type = from.getType() == FileType.DIRECTORY ? StorageType.FOLDER
: StorageType.BLOB;
if (type == StorageType.FOLDER)
return new StorageMetadataImpl(type, from.getObjectID(), from
.getObjectName(), null, null, null, null, null, Maps
.<String, String> newHashMap());
else
return new BlobMetadataImpl(from.getObjectID(), from.getObjectName(), null,
null, null, null, Maps.<String, String> newHashMap(), null, null);
null, null, null, null, Maps.<String, String> newHashMap(), null, null);
}
}), null, from.getToken(),

View File

@ -29,7 +29,7 @@ import org.jclouds.atmosonline.saas.domain.AtmosObject;
import org.jclouds.atmosonline.saas.domain.FileType;
import org.jclouds.atmosonline.saas.functions.AtmosObjectName;
import org.jclouds.blobstore.domain.MutableBlobMetadata;
import org.jclouds.blobstore.domain.ResourceType;
import org.jclouds.blobstore.domain.StorageType;
import org.jclouds.blobstore.domain.internal.MutableBlobMetadataImpl;
import org.jclouds.encryption.EncryptionService;
@ -66,9 +66,9 @@ public class ObjectToBlobMetadata implements Function<AtmosObject, MutableBlobMe
to.setName(objectName.apply(from));
to.setSize(from.getSystemMetadata().getSize());
if (from.getSystemMetadata().getType() == FileType.DIRECTORY) {
to.setType(ResourceType.FOLDER);
to.setType(StorageType.FOLDER);
} else {
to.setType(ResourceType.BLOB);
to.setType(StorageType.BLOB);
}
Map<String, String> lowerKeyMetadata = Maps.newHashMap();
for (Entry<String, String> entry : from.getUserMetadata().getMetadata().entrySet()) {

View File

@ -20,12 +20,12 @@ package org.jclouds.atmosonline.saas.blobstore.functions;
import javax.inject.Singleton;
import org.jclouds.atmosonline.saas.domain.BoundedSortedSet;
import org.jclouds.atmosonline.saas.domain.BoundedSet;
import org.jclouds.atmosonline.saas.domain.DirectoryEntry;
import org.jclouds.atmosonline.saas.domain.FileType;
import org.jclouds.atmosonline.saas.domain.internal.BoundedTreeSet;
import org.jclouds.blobstore.domain.ResourceMetadata;
import org.jclouds.blobstore.domain.ResourceType;
import org.jclouds.atmosonline.saas.domain.internal.BoundedHashSet;
import org.jclouds.blobstore.domain.StorageMetadata;
import org.jclouds.blobstore.domain.StorageType;
import com.google.common.base.Function;
import com.google.common.collect.Iterables;
@ -36,15 +36,15 @@ import com.google.common.collect.Iterables;
@Singleton
public class ResourceMetadataListToDirectoryEntryList
implements
Function<org.jclouds.blobstore.domain.ListResponse<? extends ResourceMetadata>, BoundedSortedSet<? extends DirectoryEntry>> {
Function<org.jclouds.blobstore.domain.ListResponse<? extends StorageMetadata>, BoundedSet<? extends DirectoryEntry>> {
public BoundedSortedSet<DirectoryEntry> apply(
org.jclouds.blobstore.domain.ListResponse<? extends ResourceMetadata> from) {
public BoundedSet<DirectoryEntry> apply(
org.jclouds.blobstore.domain.ListResponse<? extends StorageMetadata> from) {
return new BoundedTreeSet<DirectoryEntry>(Iterables.transform(from,
new Function<ResourceMetadata, DirectoryEntry>() {
public DirectoryEntry apply(ResourceMetadata from) {
FileType type = (from.getType() == ResourceType.FOLDER || from.getType() == ResourceType.RELATIVE_PATH) ? FileType.DIRECTORY
return new BoundedHashSet<DirectoryEntry>(Iterables.transform(from,
new Function<StorageMetadata, DirectoryEntry>() {
public DirectoryEntry apply(StorageMetadata from) {
FileType type = (from.getType() == StorageType.FOLDER || from.getType() == StorageType.RELATIVE_PATH) ? FileType.DIRECTORY
: FileType.REGULAR;
return new DirectoryEntry(from.getId(), type, from.getName());
}

View File

@ -18,9 +18,9 @@
*/
package org.jclouds.atmosonline.saas.domain;
import java.util.SortedSet;
import java.util.Set;
import org.jclouds.atmosonline.saas.domain.internal.BoundedTreeSet;
import org.jclouds.atmosonline.saas.domain.internal.BoundedHashSet;
import com.google.inject.ImplementedBy;
@ -29,8 +29,8 @@ import com.google.inject.ImplementedBy;
* @author Adrian Cole
*
*/
@ImplementedBy(BoundedTreeSet.class)
public interface BoundedSortedSet<T> extends SortedSet<T> {
@ImplementedBy(BoundedHashSet.class)
public interface BoundedSet<T> extends Set<T> {
String getToken();

View File

@ -18,9 +18,9 @@
*/
package org.jclouds.atmosonline.saas.domain.internal;
import java.util.TreeSet;
import java.util.HashSet;
import org.jclouds.atmosonline.saas.domain.BoundedSortedSet;
import org.jclouds.atmosonline.saas.domain.BoundedSet;
import com.google.common.collect.Iterables;
@ -29,13 +29,13 @@ import com.google.common.collect.Iterables;
* @author Adrian Cole
*
*/
public class BoundedTreeSet<T> extends TreeSet<T> implements BoundedSortedSet<T> {
public class BoundedHashSet<T> extends HashSet<T> implements BoundedSet<T> {
/** The serialVersionUID */
private static final long serialVersionUID = -7133632087734650835L;
protected final String token;
public BoundedTreeSet(Iterable<T> contents, String token) {
public BoundedHashSet(Iterable<T> contents, String token) {
Iterables.addAll(this, contents);
this.token = token;
}

View File

@ -22,9 +22,9 @@ import javax.inject.Inject;
import javax.inject.Provider;
import javax.inject.Singleton;
import org.jclouds.atmosonline.saas.domain.BoundedSortedSet;
import org.jclouds.atmosonline.saas.domain.BoundedSet;
import org.jclouds.atmosonline.saas.domain.DirectoryEntry;
import org.jclouds.atmosonline.saas.domain.internal.BoundedTreeSet;
import org.jclouds.atmosonline.saas.domain.internal.BoundedHashSet;
import org.jclouds.atmosonline.saas.reference.AtmosStorageHeaders;
import org.jclouds.atmosonline.saas.xml.ListDirectoryResponseHandler;
import org.jclouds.http.HttpResponse;
@ -34,13 +34,13 @@ import org.jclouds.http.functions.ParseSax.Factory;
import com.google.common.base.Function;
/**
* This parses {@link BoundedSortedSet} from HTTP headers and xml content.
* This parses {@link BoundedSet} from HTTP headers and xml content.
*
* @author Adrian Cole
*/
@Singleton
public class ParseDirectoryListFromContentAndHeaders implements
Function<HttpResponse, BoundedSortedSet<DirectoryEntry>> {
Function<HttpResponse, BoundedSet<DirectoryEntry>> {
private final ParseSax.Factory factory;
private final Provider<ListDirectoryResponseHandler> listHandlerProvider;
@ -53,11 +53,11 @@ public class ParseDirectoryListFromContentAndHeaders implements
}
/**
* parses the http response headers to create a new {@link BoundedSortedSet} object.
* parses the http response headers to create a new {@link BoundedSet} object.
*/
public BoundedSortedSet<DirectoryEntry> apply(HttpResponse from) {
public BoundedSet<DirectoryEntry> apply(HttpResponse from) {
String token = from.getFirstHeaderOrNull(AtmosStorageHeaders.TOKEN);
return new BoundedTreeSet<DirectoryEntry>(factory.create(listHandlerProvider.get()).parse(
return new BoundedHashSet<DirectoryEntry>(factory.create(listHandlerProvider.get()).parse(
from.getContent()), token);
}
}

View File

@ -30,7 +30,7 @@ import java.util.concurrent.TimeoutException;
import org.jclouds.atmosonline.saas.blobstore.strategy.RecursiveRemove;
import org.jclouds.atmosonline.saas.domain.AtmosObject;
import org.jclouds.atmosonline.saas.domain.BoundedSortedSet;
import org.jclouds.atmosonline.saas.domain.BoundedSet;
import org.jclouds.atmosonline.saas.domain.DirectoryEntry;
import org.jclouds.atmosonline.saas.domain.FileType;
import org.jclouds.atmosonline.saas.domain.SystemMetadata;
@ -128,7 +128,7 @@ public class AtmosStorageClientLiveTest {
@Test
public void testListDirectorys() throws Exception {
BoundedSortedSet<? extends DirectoryEntry> response = connection.listDirectories();
BoundedSet<? extends DirectoryEntry> response = connection.listDirectories();
assert null != response;
}
@ -150,9 +150,9 @@ public class AtmosStorageClientLiveTest {
throw e;
}
}
BoundedSortedSet<? extends DirectoryEntry> response = connection.listDirectories();
BoundedSet<? extends DirectoryEntry> response = connection.listDirectories();
for (DirectoryEntry id : response) {
BoundedSortedSet<? extends DirectoryEntry> r2 = connection.listDirectory(id
BoundedSet<? extends DirectoryEntry> r2 = connection.listDirectory(id
.getObjectName());
assert r2 != null;
}
@ -163,7 +163,7 @@ public class AtmosStorageClientLiveTest {
createOrReplaceObject("object2", "here is my data!", "meta-value1");
createOrReplaceObject("object3", "here is my data!", "meta-value1");
createOrReplaceObject("object4", "here is my data!", "meta-value1");
BoundedSortedSet<? extends DirectoryEntry> r2 = connection.listDirectory(privateDirectory,
BoundedSet<? extends DirectoryEntry> r2 = connection.listDirectory(privateDirectory,
ListOptions.Builder.limit(1));
// test bug exists:
assertEquals(r2.size(), 3);

View File

@ -35,7 +35,7 @@ import org.jclouds.atmosonline.saas.blobstore.functions.ListOptionsToBlobStoreLi
import org.jclouds.atmosonline.saas.blobstore.functions.ObjectToBlob;
import org.jclouds.atmosonline.saas.blobstore.functions.ResourceMetadataListToDirectoryEntryList;
import org.jclouds.atmosonline.saas.domain.AtmosObject;
import org.jclouds.atmosonline.saas.domain.BoundedSortedSet;
import org.jclouds.atmosonline.saas.domain.BoundedSet;
import org.jclouds.atmosonline.saas.domain.DirectoryEntry;
import org.jclouds.atmosonline.saas.domain.SystemMetadata;
import org.jclouds.atmosonline.saas.domain.UserMetadata;
@ -96,13 +96,14 @@ public class StubAtmosStorageAsyncClient implements AtmosStorageAsyncClient {
container = directoryName.substring(0, directoryName.indexOf('/'));
else
container = directoryName;
return Futures.compose(blobStore.createContainer(container), new Function<Boolean, URI>() {
return Futures.compose(blobStore.createContainerInLocation("default", container),
new Function<Boolean, URI>() {
public URI apply(Boolean from) {
return URI.create("http://stub/containers/" + container);
}
public URI apply(Boolean from) {
return URI.create("http://stub/containers/" + container);
}
});
});
}
public ListenableFuture<URI> createFile(String parent, AtmosObject object) {
@ -171,14 +172,14 @@ public class StubAtmosStorageAsyncClient implements AtmosStorageAsyncClient {
}
}
public ListenableFuture<? extends BoundedSortedSet<? extends DirectoryEntry>> listDirectories(
public ListenableFuture<? extends BoundedSet<? extends DirectoryEntry>> listDirectories(
ListOptions... optionsList) {
// org.jclouds.blobstore.options.ListOptions options = container2ContainerListOptions
// .apply(optionsList);
return Futures.compose(blobStore.list(), resource2ObjectList);
}
public ListenableFuture<? extends BoundedSortedSet<? extends DirectoryEntry>> listDirectory(
public ListenableFuture<? extends BoundedSet<? extends DirectoryEntry>> listDirectory(
String directoryName, ListOptions... optionsList) {
org.jclouds.blobstore.options.ListContainerOptions options = container2ContainerListOptions
.apply(optionsList);

View File

@ -27,10 +27,63 @@ import com.google.common.base.CaseFormat;
* Regions used for all aws commands.
*
* @author Adrian Cole
* @see <a href=
* "http://docs.amazonwebservices.com/AmazonS3/latest/dev/index.html?LocationSelection.html" />
*
*/
public enum Region {
DEFAULT, UNKNOWN, EU_WEST_1, US_EAST_1, US_WEST_1;
/**
* Allow the default region to be chosen based on the user-configured endpoint.
*/
DEFAULT,
/**
* Region returned is unknown.
*/
UNKNOWN,
/**
* EU (Ireland)
* <p/>
* <h3>S3</h3>
* <p/>
* In Amazon S3, the EU (Ireland) Region provides read-after-write consistency for PUTS of new
* objects in your Amazon S3 bucket and eventual consistency for overwrite PUTS and DELETES.
*/
EU_WEST_1,
/**
*
* US Standard
* <p/>
* <h3>S3</h3>
* <p/>
* This is the default Region. All requests sent to s3.amazonaws.com go to this Region unless you
* specify a LocationConstraint on a bucket. The US Standard Region automatically places your
* data in either Amazon's east or west coast data centers depending on what will provide you
* with the lowest latency. To use this region, do not set the LocationConstraint bucket
* parameter. The US Standard Region provides eventual consistency for all requests.
*/
US_STANDARD,
/**
*
*/
US_EAST_1,
/**
* US-West (Northern California) <h3>S3</h3> Uses Amazon S3 servers in Northern California
* <p/>
* Optionally, use the endpoint s3-us-west-1.amazonaws.com on all requests to this bucket to
* reduce the latency you might experience after the first hour of creating a bucket in this
* Region.
* <p/>
* In Amazon S3, the US-West (Northern California) Region provides read-after-write consistency
* for PUTS of new objects in your Amazon S3 bucket and eventual consistency for overwrite PUTS
* and DELETES.
*/
US_WEST_1;
public String value() {
return CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.LOWER_HYPHEN, name());

View File

@ -18,12 +18,15 @@
*/
package org.jclouds.aws.ec2.compute;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.jclouds.aws.ec2.options.RunInstancesOptions.Builder.withKeyName;
import static org.jclouds.scriptbuilder.domain.Statements.exec;
import java.net.InetAddress;
import java.util.Arrays;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Set;
import javax.annotation.Resource;
@ -38,18 +41,19 @@ import org.jclouds.aws.ec2.domain.InstanceState;
import org.jclouds.aws.ec2.domain.InstanceType;
import org.jclouds.aws.ec2.domain.IpProtocol;
import org.jclouds.aws.ec2.domain.KeyPair;
import org.jclouds.aws.ec2.domain.Reservation;
import org.jclouds.aws.ec2.domain.RunningInstance;
import org.jclouds.compute.ComputeService;
import org.jclouds.compute.domain.ComputeMetadata;
import org.jclouds.compute.domain.ComputeType;
import org.jclouds.compute.domain.CreateNodeResponse;
import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.LoginType;
import org.jclouds.compute.domain.NodeIdentity;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.NodeState;
import org.jclouds.compute.domain.Profile;
import org.jclouds.compute.domain.Size;
import org.jclouds.compute.domain.internal.ComputeMetadataImpl;
import org.jclouds.compute.domain.internal.CreateNodeResponseImpl;
import org.jclouds.compute.domain.internal.NodeIdentityImpl;
import org.jclouds.compute.domain.internal.NodeMetadataImpl;
import org.jclouds.compute.reference.ComputeServiceConstants;
import org.jclouds.domain.Credentials;
@ -107,14 +111,17 @@ public class EC2ComputeService implements ComputeService {
NodeState.PENDING).put(InstanceState.TERMINATED, NodeState.TERMINATED).build();
@Override
public CreateNodeResponse createNode(String name, Profile profile, Image image) {
public CreateNodeResponse startNodeInLocation(String location, String name, Profile profile,
Image image) {
Region region = Region.fromValue(location);
InstanceType type = checkNotNull(profileInstanceTypeMap.get(profile),
"profile not supported: " + profile);
String ami = checkNotNull(imageAmiIdMap.get(type).get(image), "image not supported: " + image);
KeyPair keyPair = createKeyPair(name);
KeyPair keyPair = createKeyPairInRegion(region, name);
String securityGroupName = name;
createSecurityGroup(securityGroupName, 22, 80, 8080, 443);
createSecurityGroupInRegion(region, securityGroupName, 22, 80, 8080, 443);
String script = new ScriptBuilder() // update and install jdk
.addStatement(exec("apt-get update"))//
@ -127,43 +134,46 @@ public class EC2ComputeService implements ComputeService {
logger.debug(">> running instance ami(%s) type(%s) keyPair(%s) securityGroup(%s)", ami, type,
keyPair.getKeyName(), securityGroupName);
RunningInstance runningInstance = Iterables.getLast(ec2Client.getInstanceServices()
.runInstancesInRegion(Region.DEFAULT, null, ami, 1, 1,
withKeyName(keyPair.getKeyName())// key I created above
.asType(type)// instance size
.withSecurityGroup(securityGroupName)// group I created above
.withAdditionalInfo(name)// description
.withUserData(script.getBytes()) // script to run as root
).getRunningInstances());
RunningInstance runningInstance = Iterables.getOnlyElement(ec2Client.getInstanceServices()
.runInstancesInRegion(region, null, ami, 1, 1, withKeyName(keyPair.getKeyName())// key
// I
// created
// above
.asType(type)// instance size
.withSecurityGroup(securityGroupName)// group I created above
.withAdditionalInfo(name)// description
.withUserData(script.getBytes()) // script to run as root
));
logger.debug("<< started instance(%s)", runningInstance.getId());
instanceStateRunning.apply(runningInstance);
logger.debug("<< running instance(%s)", runningInstance.getId());
// refresh to get IP address
runningInstance = getRunningInstance(runningInstance.getId());
runningInstance = getOnlyRunningInstanceInRegion(region, runningInstance.getId());
Set<InetAddress> publicAddresses = runningInstance.getIpAddress() == null ? ImmutableSet
.<InetAddress> of() : ImmutableSet.<InetAddress> of(runningInstance.getIpAddress());
Set<InetAddress> privateAddresses = runningInstance.getPrivateIpAddress() == null ? ImmutableSet
.<InetAddress> of()
: ImmutableSet.<InetAddress> of(runningInstance.getPrivateIpAddress());
return new CreateNodeResponseImpl(runningInstance.getId(), name, instanceToNodeState
return new CreateNodeResponseImpl(runningInstance.getId(), name, runningInstance.getRegion()
.toString(), null, ImmutableMap.<String, String> of(), instanceToNodeState
.get(runningInstance.getInstanceState()), publicAddresses, privateAddresses, 22,
LoginType.SSH, new Credentials("root", keyPair.getKeyMaterial()), ImmutableMap
.<String, String> of());
LoginType.SSH, new Credentials(image == Image.UBUNTU_90 ? "ubuntu" : "root", keyPair
.getKeyMaterial()), ImmutableMap.<String, String> of());
}
private KeyPair createKeyPair(String name) {
private KeyPair createKeyPairInRegion(Region region, String name) {
logger.debug(">> creating keyPair name(%s)", name);
KeyPair keyPair;
try {
keyPair = ec2Client.getKeyPairServices().createKeyPairInRegion(Region.DEFAULT, name);
keyPair = ec2Client.getKeyPairServices().createKeyPairInRegion(region, name);
logger.debug("<< created keyPair(%s)", keyPair.getKeyName());
} catch (AWSResponseException e) {
if (e.getError().getCode().equals("InvalidKeyPair.Duplicate")) {
keyPair = Iterables.getLast(ec2Client.getKeyPairServices().describeKeyPairsInRegion(
Region.DEFAULT, name));
region, name));
logger.debug("<< reused keyPair(%s)", keyPair.getKeyName());
} else {
@ -173,18 +183,17 @@ public class EC2ComputeService implements ComputeService {
return keyPair;
}
private void createSecurityGroup(String name, int... ports) {
private void createSecurityGroupInRegion(Region region, String name, int... ports) {
logger.debug(">> creating securityGroup name(%s)", name);
try {
ec2Client.getSecurityGroupServices().createSecurityGroupInRegion(Region.DEFAULT, name,
name);
ec2Client.getSecurityGroupServices().createSecurityGroupInRegion(region, name, name);
logger.debug("<< created securityGroup(%s)", name);
logger.debug(">> authorizing securityGroup name(%s) ports(%s)", name, ImmutableSet
.of(ports));
logger
.debug(">> authorizing securityGroup name(%s) ports(%s)", name, Arrays
.asList(ports));
for (int port : ports) {
ec2Client.getSecurityGroupServices().authorizeSecurityGroupIngressInRegion(
Region.DEFAULT, name, IpProtocol.TCP, port, port, "0.0.0.0/0");
ec2Client.getSecurityGroupServices().authorizeSecurityGroupIngressInRegion(region,
name, IpProtocol.TCP, port, port, "0.0.0.0/0");
}
logger.debug("<< authorized securityGroup(%s)", name);
} catch (AWSResponseException e) {
@ -198,8 +207,13 @@ public class EC2ComputeService implements ComputeService {
}
@Override
public NodeMetadata getNodeMetadata(String id) {
RunningInstance runningInstance = getRunningInstance(id);
public NodeMetadata getNodeMetadata(ComputeMetadata node) {
checkArgument(node.getType() == ComputeType.NODE, "this is only valid for nodes, not "
+ node.getType());
checkNotNull(node.getId(), "node.id");
Region region = getRegionFromNodeOrDefault(node);
RunningInstance runningInstance = Iterables.getOnlyElement(getAllRunningInstancesInRegion(
region, node.getId()));
return runningInstanceToNodeMetadata.apply(runningInstance);
}
@ -209,9 +223,12 @@ public class EC2ComputeService implements ComputeService {
@Override
public NodeMetadata apply(RunningInstance from) {
return new NodeMetadataImpl(from.getId(), from.getKeyName(), instanceToNodeState.get(from
.getInstanceState()), nullSafeSet(from.getIpAddress()), nullSafeSet(from
.getPrivateIpAddress()), 22, LoginType.SSH, ImmutableMap.<String, String> of());
return new NodeMetadataImpl(from.getId(), from.getKeyName(), from.getRegion().toString(),
null, ImmutableMap.<String, String> of(), instanceToNodeState.get(from
.getInstanceState()), nullSafeSet(from.getIpAddress()), nullSafeSet(from
.getPrivateIpAddress()), 22, LoginType.SSH, ImmutableMap
.<String, String> of("availabilityZone", from.getAvailabilityZone()
.toString()));
}
Set<InetAddress> nullSafeSet(InetAddress in) {
@ -222,21 +239,32 @@ public class EC2ComputeService implements ComputeService {
}
}
private RunningInstance getRunningInstance(String id) {
RunningInstance runningInstance = Iterables.getLast(Iterables.getLast(
ec2Client.getInstanceServices().describeInstancesInRegion(Region.DEFAULT, id))
.getRunningInstances());
return runningInstance;
private RunningInstance getOnlyRunningInstanceInRegion(Region region, String id) {
Iterable<RunningInstance> instances = Iterables.filter(getAllRunningInstancesInRegion(region,
id), new Predicate<RunningInstance>() {
@Override
public boolean apply(RunningInstance instance) {
return instance.getInstanceState() == InstanceState.PENDING
|| instance.getInstanceState() == InstanceState.RUNNING;
}
});
int size = Iterables.size(instances);
if (size == 0)
throw new NoSuchElementException(String.format(
"%d instances in region %s have an instance with id %s running.", size, region,
id));
if (size > 1)
throw new IllegalStateException(String.format(
"%d instances in region %s have an instance with id %s running. Expected 1",
size, region, id));
return Iterables.getOnlyElement(instances);
}
@Override
public Set<NodeIdentity> getNodeByName(final String name) {
return Sets.newHashSet(Iterables.filter(listNodes(), new Predicate<NodeIdentity>() {
@Override
public boolean apply(NodeIdentity input) {
return input.getName().equalsIgnoreCase(name);
}
}));
private Iterable<RunningInstance> getAllRunningInstancesInRegion(Region region, String id) {
return Iterables
.concat(ec2Client.getInstanceServices().describeInstancesInRegion(region, id));
}
/**
@ -244,16 +272,18 @@ public class EC2ComputeService implements ComputeService {
* keyname. This will break.
*/
@Override
public Set<NodeIdentity> listNodes() {
public Set<ComputeMetadata> listNodes() {
logger.debug(">> listing servers");
Set<NodeIdentity> servers = Sets.newHashSet();
for (Reservation reservation : ec2Client.getInstanceServices().describeInstancesInRegion(
Region.DEFAULT)) {
Iterables.addAll(servers, Iterables.transform(reservation.getRunningInstances(),
new Function<RunningInstance, NodeIdentity>() {
Set<ComputeMetadata> servers = Sets.newHashSet();
for (Region region : ImmutableSet.of(Region.US_EAST_1, Region.US_WEST_1, Region.EU_WEST_1)) {
Iterables.addAll(servers, Iterables.transform(Iterables.concat(ec2Client
.getInstanceServices().describeInstancesInRegion(region)),
new Function<RunningInstance, ComputeMetadata>() {
@Override
public NodeIdentity apply(RunningInstance from) {
return new NodeIdentityImpl(from.getId(), from.getKeyName());
public ComputeMetadata apply(RunningInstance from) {
return new ComputeMetadataImpl(ComputeType.NODE, from.getId(), from
.getKeyName(), from.getRegion().toString(), null, ImmutableMap
.<String, String> of());
}
}));
}
@ -262,18 +292,34 @@ public class EC2ComputeService implements ComputeService {
}
@Override
public void destroyNode(String id) {
RunningInstance runningInstance = getRunningInstance(id);
// grab the old keyname
String name = runningInstance.getKeyName();
logger.debug(">> terminating instance(%s)", runningInstance.getId());
ec2Client.getInstanceServices().terminateInstancesInRegion(Region.DEFAULT, id);
logger.debug("<< terminated instance(%s)", runningInstance.getId());
logger.debug(">> deleting keyPair(%s)", name);
ec2Client.getKeyPairServices().deleteKeyPairInRegion(Region.DEFAULT, name);
logger.debug("<< deleted keyPair(%s)", name);
logger.debug(">> deleting securityGroup(%s)", name);
ec2Client.getSecurityGroupServices().deleteSecurityGroupInRegion(Region.DEFAULT, name);
logger.debug("<< deleted securityGroup(%s)", name);
public void destroyNode(ComputeMetadata node) {
checkArgument(node.getType() == ComputeType.NODE, "this is only valid for nodes, not "
+ node.getType());
checkNotNull(node.getId(), "node.id");
Region region = getRegionFromNodeOrDefault(node);
for (RunningInstance runningInstance : getAllRunningInstancesInRegion(region, node.getId())) {
// grab the old keyname
String name = runningInstance.getKeyName();
logger.debug(">> terminating instance(%s)", node.getId());
ec2Client.getInstanceServices().terminateInstancesInRegion(region, node.getId());
logger.debug("<< terminated instance(%s)", node.getId());
logger.debug(">> deleting keyPair(%s)", name);
ec2Client.getKeyPairServices().deleteKeyPairInRegion(region, name);
logger.debug("<< deleted keyPair(%s)", name);
logger.debug(">> deleting securityGroup(%s)", name);
ec2Client.getSecurityGroupServices().deleteSecurityGroupInRegion(region, name);
logger.debug("<< deleted securityGroup(%s)", name);
}
}
private Region getRegionFromNodeOrDefault(ComputeMetadata node) {
Region region = node.getLocation() != null ? Region.fromValue(node.getLocation())
: Region.DEFAULT;
return region;
}
@Override
public Map<String, Size> getSizes() {
throw new UnsupportedOperationException();
}
}

View File

@ -20,10 +20,13 @@ package org.jclouds.aws.ec2.domain;
import static com.google.common.base.Preconditions.checkNotNull;
import java.util.LinkedHashSet;
import java.util.Set;
import org.jclouds.aws.domain.Region;
import com.google.common.collect.Iterables;
import com.google.common.collect.Sets;
import com.google.inject.internal.Nullable;
/**
@ -32,11 +35,13 @@ import com.google.inject.internal.Nullable;
* />
* @author Adrian Cole
*/
public class Reservation implements Comparable<Reservation> {
public class Reservation extends LinkedHashSet<RunningInstance> implements Comparable<Reservation>,
Set<RunningInstance> {
/** The serialVersionUID */
private static final long serialVersionUID = -9051777593518861395L;
private final Region region;
private final Set<String> groupIds;
private final Set<RunningInstance> instances;
private final Set<String> groupIds = Sets.newLinkedHashSet();
private final @Nullable
String ownerId;
private final @Nullable
@ -44,11 +49,12 @@ public class Reservation implements Comparable<Reservation> {
private final @Nullable
String reservationId;
public Reservation(Region region, Set<String> groupIds, Set<RunningInstance> instances,
@Nullable String ownerId, @Nullable String requesterId, @Nullable String reservationId) {
public Reservation(Region region, Iterable<String> groupIds,
Iterable<RunningInstance> instances, @Nullable String ownerId,
@Nullable String requesterId, @Nullable String reservationId) {
this.region = checkNotNull(region, "region");
this.groupIds = checkNotNull(groupIds, "groupIds");
this.instances = checkNotNull(instances, "instances");
Iterables.addAll(this.groupIds, checkNotNull(groupIds, "groupIds"));
Iterables.addAll(this, checkNotNull(instances, "instances"));
this.ownerId = ownerId;
this.requesterId = requesterId;
this.reservationId = reservationId;
@ -72,10 +78,6 @@ public class Reservation implements Comparable<Reservation> {
return groupIds;
}
public Set<RunningInstance> getRunningInstances() {
return instances;
}
/**
* AWS Access Key ID of the user who owns the reservation.
*/
@ -100,9 +102,8 @@ public class Reservation implements Comparable<Reservation> {
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
int result = super.hashCode();
result = prime * result + ((groupIds == null) ? 0 : groupIds.hashCode());
result = prime * result + ((instances == null) ? 0 : instances.hashCode());
result = prime * result + ((ownerId == null) ? 0 : ownerId.hashCode());
result = prime * result + ((region == null) ? 0 : region.hashCode());
result = prime * result + ((requesterId == null) ? 0 : requesterId.hashCode());
@ -114,7 +115,7 @@ public class Reservation implements Comparable<Reservation> {
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
if (!super.equals(obj))
return false;
if (getClass() != obj.getClass())
return false;
@ -124,11 +125,6 @@ public class Reservation implements Comparable<Reservation> {
return false;
} else if (!groupIds.equals(other.groupIds))
return false;
if (instances == null) {
if (other.instances != null)
return false;
} else if (!instances.equals(other.instances))
return false;
if (ownerId == null) {
if (other.ownerId != null)
return false;

View File

@ -22,7 +22,6 @@ import javax.annotation.Resource;
import javax.inject.Singleton;
import org.jclouds.aws.AWSResponseException;
import org.jclouds.aws.domain.Region;
import org.jclouds.aws.ec2.domain.RunningInstance;
import org.jclouds.aws.ec2.services.InstanceClient;
import org.jclouds.logging.Logger;
@ -53,7 +52,7 @@ public class InstanceHasIpAddress implements Predicate<RunningInstance> {
public boolean apply(RunningInstance instance) {
logger.trace("looking for ipAddress on instance %s", instance);
try {
instance = refresh(instance.getId());
instance = refresh(instance);
return instance.getIpAddress() != null;
} catch (AWSResponseException e) {
if (e.getError().getCode().equals("InvalidInstanceID.NotFound"))
@ -62,8 +61,8 @@ public class InstanceHasIpAddress implements Predicate<RunningInstance> {
}
}
private RunningInstance refresh(String instanceId) {
return Iterables.getLast(Iterables.getLast(
client.describeInstancesInRegion(Region.DEFAULT, instanceId)).getRunningInstances());
private RunningInstance refresh(RunningInstance instance) {
return Iterables.getOnlyElement(Iterables.getOnlyElement(client.describeInstancesInRegion(
instance.getRegion(), instance.getId())));
}
}

View File

@ -22,7 +22,6 @@ import javax.annotation.Resource;
import javax.inject.Singleton;
import org.jclouds.aws.AWSResponseException;
import org.jclouds.aws.domain.Region;
import org.jclouds.aws.ec2.domain.InstanceState;
import org.jclouds.aws.ec2.domain.RunningInstance;
import org.jclouds.aws.ec2.services.InstanceClient;
@ -54,7 +53,7 @@ public class InstanceStateRunning implements Predicate<RunningInstance> {
public boolean apply(RunningInstance instance) {
logger.trace("looking for state on instance %s", instance);
try {
instance = refresh(instance.getId());
instance = refresh(instance);
logger.trace("%s: looking for instance state %s: currently: %s", instance.getId(),
InstanceState.RUNNING, instance.getInstanceState());
return instance.getInstanceState() == InstanceState.RUNNING;
@ -65,8 +64,8 @@ public class InstanceStateRunning implements Predicate<RunningInstance> {
}
}
private RunningInstance refresh(String instanceId) {
return Iterables.getLast(Iterables.getLast(
client.describeInstancesInRegion(Region.DEFAULT, instanceId)).getRunningInstances());
private RunningInstance refresh(RunningInstance instance) {
return Iterables.getOnlyElement(Iterables.getOnlyElement(client.describeInstancesInRegion(
instance.getRegion(), instance.getId())));
}
}

View File

@ -21,7 +21,6 @@ package org.jclouds.aws.ec2.predicates;
import javax.annotation.Resource;
import javax.inject.Singleton;
import org.jclouds.aws.domain.Region;
import org.jclouds.aws.ec2.domain.InstanceState;
import org.jclouds.aws.ec2.domain.RunningInstance;
import org.jclouds.aws.ec2.services.InstanceClient;
@ -53,15 +52,14 @@ public class InstanceStateStopped implements Predicate<RunningInstance> {
public boolean apply(RunningInstance instance) {
logger.trace("looking for state on instance %s", instance);
instance = refresh(instance.getId());
instance = refresh(instance);
logger.trace("%s: looking for instance state %s: currently: %s", instance.getId(),
InstanceState.STOPPED, instance.getInstanceState());
return instance.getInstanceState() == InstanceState.STOPPED;
}
private RunningInstance refresh(String instanceId) {
return Iterables.getLast(Iterables.getLast(client.describeInstancesInRegion(
Region.DEFAULT,instanceId))
.getRunningInstances());
private RunningInstance refresh(RunningInstance instance) {
return Iterables.getOnlyElement(Iterables.getOnlyElement(client.describeInstancesInRegion(
instance.getRegion(), instance.getId())));
}
}

View File

@ -21,7 +21,6 @@ package org.jclouds.aws.ec2.predicates;
import javax.annotation.Resource;
import javax.inject.Singleton;
import org.jclouds.aws.domain.Region;
import org.jclouds.aws.ec2.domain.InstanceState;
import org.jclouds.aws.ec2.domain.RunningInstance;
import org.jclouds.aws.ec2.services.InstanceClient;
@ -53,14 +52,14 @@ public class InstanceStateTerminated implements Predicate<RunningInstance> {
public boolean apply(RunningInstance instance) {
logger.trace("looking for state on instance %s", instance);
instance = refresh(instance.getId());
instance = refresh(instance);
logger.trace("%s: looking for instance state %s: currently: %s", instance.getId(),
InstanceState.TERMINATED, instance.getInstanceState());
return instance.getInstanceState() == InstanceState.TERMINATED;
}
private RunningInstance refresh(String instanceId) {
return Iterables.getLast(Iterables.getLast(
client.describeInstancesInRegion(Region.DEFAULT, instanceId)).getRunningInstances());
private RunningInstance refresh(RunningInstance instance) {
return Iterables.getOnlyElement(Iterables.getOnlyElement(client.describeInstancesInRegion(
instance.getRegion(), instance.getId())));
}
}

View File

@ -30,6 +30,7 @@ import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import org.jclouds.aws.domain.Region;
import org.jclouds.aws.s3.binders.BindACLToXMLPayload;
import org.jclouds.aws.s3.binders.BindBucketLoggingToXmlPayload;
import org.jclouds.aws.s3.binders.BindNoBucketLoggingToXmlPayload;
@ -42,8 +43,8 @@ import org.jclouds.aws.s3.domain.ListBucketResponse;
import org.jclouds.aws.s3.domain.ObjectMetadata;
import org.jclouds.aws.s3.domain.Payer;
import org.jclouds.aws.s3.domain.S3Object;
import org.jclouds.aws.s3.domain.BucketMetadata.LocationConstraint;
import org.jclouds.aws.s3.filters.RequestAuthorizeSignature;
import org.jclouds.aws.s3.functions.BindRegionToXmlPayload;
import org.jclouds.aws.s3.functions.ObjectKey;
import org.jclouds.aws.s3.functions.ParseObjectFromHeadersAndHttpContent;
import org.jclouds.aws.s3.functions.ParseObjectMetadataFromHeaders;
@ -150,13 +151,14 @@ public interface S3AsyncClient {
PutObjectOptions... options);
/**
* @see S3Client#putBucketIfNotExists
* @see S3Client#putBucketInRegion
*/
@PUT
@Path("/")
@ExceptionParser(ReturnTrueIfBucketAlreadyOwnedByYou.class)
ListenableFuture<Boolean> putBucketIfNotExists(@HostPrefixParam String bucketName,
PutBucketOptions... options);
ListenableFuture<Boolean> putBucketInRegion(//TODO endpoint based on region
@BinderParam(BindRegionToXmlPayload.class) Region region,
@HostPrefixParam String bucketName, PutBucketOptions... options);
/**
* @see S3Client#deleteBucketIfEmpty
@ -182,7 +184,7 @@ public interface S3AsyncClient {
@QueryParams(keys = "location")
@Path("/")
@XMLResponseParser(LocationConstraintHandler.class)
ListenableFuture<LocationConstraint> getBucketLocation(@HostPrefixParam String bucketName);
ListenableFuture<Region> getBucketLocation(@HostPrefixParam String bucketName);
/**
* @see S3Client#getBucketPayer

View File

@ -22,6 +22,7 @@ import java.util.SortedSet;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import org.jclouds.aws.domain.Region;
import org.jclouds.aws.s3.domain.AccessControlList;
import org.jclouds.aws.s3.domain.BucketLogging;
import org.jclouds.aws.s3.domain.BucketMetadata;
@ -29,7 +30,6 @@ import org.jclouds.aws.s3.domain.ListBucketResponse;
import org.jclouds.aws.s3.domain.ObjectMetadata;
import org.jclouds.aws.s3.domain.Payer;
import org.jclouds.aws.s3.domain.S3Object;
import org.jclouds.aws.s3.domain.BucketMetadata.LocationConstraint;
import org.jclouds.aws.s3.options.CopyObjectOptions;
import org.jclouds.aws.s3.options.ListBucketOptions;
import org.jclouds.aws.s3.options.PutBucketOptions;
@ -42,8 +42,9 @@ import com.google.common.util.concurrent.ListenableFuture;
/**
* Provides access to S3 via their REST API.
* <p/>
* All commands return a ListenableFuture of the result from S3. Any exceptions incurred during processing
* will be wrapped in an {@link ExecutionException} as documented in {@link ListenableFuture#get()}.
* All commands return a ListenableFuture of the result from S3. Any exceptions incurred during
* processing will be wrapped in an {@link ExecutionException} as documented in
* {@link ListenableFuture#get()}.
*
* @author Adrian Cole
* @author James Murty
@ -78,8 +79,8 @@ public interface S3Client {
* namespace of the object you are retrieving
* @param key
* unique key in the s3Bucket identifying the object
* @return ListenableFuture reference to a fully populated S3Object including data stored in S3 or
* {@link S3Object#NOT_FOUND} if not present.
* @return ListenableFuture reference to a fully populated S3Object including data stored in S3
* or {@link S3Object#NOT_FOUND} if not present.
*
* @throws org.jclouds.http.HttpResponseException
* if the conditions requested set were not satisfied by the object on the server.
@ -181,7 +182,7 @@ public interface S3Client {
* />
*
*/
boolean putBucketIfNotExists(String bucketName, PutBucketOptions... options);
boolean putBucketInRegion(Region region, String bucketName, PutBucketOptions... options);
/**
* Deletes the bucket, if it is empty.
@ -217,8 +218,8 @@ public interface S3Client {
*
* @param bucketName
* namespace of the objects you wish to list
* @return ListenableFuture reference to a fully populated S3Bucket including metadata of the S3Objects it
* contains or {@link BoundedList<ObjectMetadata>#NOT_FOUND} if not present.
* @return ListenableFuture reference to a fully populated S3Bucket including metadata of the
* S3Objects it contains or {@link BoundedList<ObjectMetadata>#NOT_FOUND} if not present.
* @see ListBucketOptions
*
* @see <a
@ -344,7 +345,7 @@ public interface S3Client {
* "http://docs.amazonwebservices.com/AmazonS3/latest/index.html?RESTBucketLocationGET.html"
* />
*/
LocationConstraint getBucketLocation(String bucketName);
Region getBucketLocation(String bucketName);
/**
* A GET request operation on a requestPayment resource returns the request payment configuration

View File

@ -28,6 +28,7 @@ import java.util.concurrent.ExecutorService;
import javax.inject.Inject;
import org.jclouds.aws.domain.Region;
import org.jclouds.aws.s3.S3AsyncClient;
import org.jclouds.aws.s3.S3Client;
import org.jclouds.aws.s3.blobstore.functions.BlobToObject;
@ -48,7 +49,7 @@ import org.jclouds.blobstore.domain.Blob;
import org.jclouds.blobstore.domain.BlobMetadata;
import org.jclouds.blobstore.domain.ListContainerResponse;
import org.jclouds.blobstore.domain.ListResponse;
import org.jclouds.blobstore.domain.ResourceMetadata;
import org.jclouds.blobstore.domain.StorageMetadata;
import org.jclouds.blobstore.domain.Blob.Factory;
import org.jclouds.blobstore.domain.internal.ListResponseImpl;
import org.jclouds.blobstore.options.ListContainerOptions;
@ -120,8 +121,8 @@ public class S3AsyncBlobStore extends BaseS3BlobStore implements AsyncBlobStore
}));
}
public ListenableFuture<Boolean> createContainer(String container) {
return async.putBucketIfNotExists(container);
public ListenableFuture<Boolean> createContainerInLocation(String location, String container) {
return async.putBucketInRegion(Region.DEFAULT, container);// TODO
}
public ListenableFuture<Boolean> containerExists(String container) {
@ -160,19 +161,19 @@ public class S3AsyncBlobStore extends BaseS3BlobStore implements AsyncBlobStore
return compose(async.getObject(container, key, httpOptions), object2Blob, service);
}
public ListenableFuture<? extends ListResponse<? extends ResourceMetadata>> list() {
public ListenableFuture<? extends ListResponse<? extends StorageMetadata>> list() {
return compose(
async.listOwnedBuckets(),
new Function<SortedSet<BucketMetadata>, org.jclouds.blobstore.domain.ListResponse<? extends ResourceMetadata>>() {
public org.jclouds.blobstore.domain.ListResponse<? extends ResourceMetadata> apply(
new Function<SortedSet<BucketMetadata>, org.jclouds.blobstore.domain.ListResponse<? extends StorageMetadata>>() {
public org.jclouds.blobstore.domain.ListResponse<? extends StorageMetadata> apply(
SortedSet<BucketMetadata> from) {
return new ListResponseImpl<ResourceMetadata>(Iterables.transform(from,
return new ListResponseImpl<StorageMetadata>(Iterables.transform(from,
bucket2ResourceMd), null, null, false);
}
}, service);
}
public ListenableFuture<? extends ListContainerResponse<? extends ResourceMetadata>> list(
public ListenableFuture<? extends ListContainerResponse<? extends StorageMetadata>> list(
String container, ListContainerOptions... optionsList) {
ListBucketOptions httpOptions = container2BucketListOptions.apply(optionsList);
ListenableFuture<ListBucketResponse> returnVal = async.listBucket(container, httpOptions);

View File

@ -25,6 +25,7 @@ import java.util.concurrent.ExecutorService;
import javax.inject.Inject;
import org.jclouds.aws.domain.Region;
import org.jclouds.aws.s3.S3AsyncClient;
import org.jclouds.aws.s3.S3Client;
import org.jclouds.aws.s3.blobstore.functions.BlobToObject;
@ -43,7 +44,7 @@ import org.jclouds.blobstore.domain.Blob;
import org.jclouds.blobstore.domain.BlobMetadata;
import org.jclouds.blobstore.domain.ListContainerResponse;
import org.jclouds.blobstore.domain.ListResponse;
import org.jclouds.blobstore.domain.ResourceMetadata;
import org.jclouds.blobstore.domain.StorageMetadata;
import org.jclouds.blobstore.domain.Blob.Factory;
import org.jclouds.blobstore.domain.internal.ListResponseImpl;
import org.jclouds.blobstore.options.ListContainerOptions;
@ -90,8 +91,8 @@ public class S3BlobStore extends BaseS3BlobStore implements BlobStore {
return sync.bucketExists(container);
}
public boolean createContainer(String container) {
return sync.putBucketIfNotExists(container);
public boolean createContainerInLocation(String location, String container) {
return sync.putBucketInRegion(Region.DEFAULT, container);// TODO parameterize
}
public void deleteContainer(String container) {
@ -118,17 +119,17 @@ public class S3BlobStore extends BaseS3BlobStore implements BlobStore {
return object2Blob.apply(sync.getObject(container, key, httpOptions));
}
public ListResponse<? extends ResourceMetadata> list() {
return new Function<SortedSet<BucketMetadata>, org.jclouds.blobstore.domain.ListResponse<? extends ResourceMetadata>>() {
public org.jclouds.blobstore.domain.ListResponse<? extends ResourceMetadata> apply(
public ListResponse<? extends StorageMetadata> list() {
return new Function<SortedSet<BucketMetadata>, org.jclouds.blobstore.domain.ListResponse<? extends StorageMetadata>>() {
public org.jclouds.blobstore.domain.ListResponse<? extends StorageMetadata> apply(
SortedSet<BucketMetadata> from) {
return new ListResponseImpl<ResourceMetadata>(Iterables.transform(from,
return new ListResponseImpl<StorageMetadata>(Iterables.transform(from,
bucket2ResourceMd), null, null, false);
}
}.apply(sync.listOwnedBuckets());
}
public ListContainerResponse<? extends ResourceMetadata> list(String container,
public ListContainerResponse<? extends StorageMetadata> list(String container,
ListContainerOptions... optionsList) {
ListBucketOptions httpOptions = container2BucketListOptions.apply(optionsList);
return bucket2ResourceList.apply(sync.listBucket(container, httpOptions));

View File

@ -25,7 +25,7 @@ import javax.inject.Singleton;
import org.jclouds.aws.s3.domain.ListBucketResponse;
import org.jclouds.blobstore.domain.ListContainerResponse;
import org.jclouds.blobstore.domain.ResourceMetadata;
import org.jclouds.blobstore.domain.StorageMetadata;
import org.jclouds.blobstore.domain.internal.ListContainerResponseImpl;
import com.google.common.base.Function;
@ -37,7 +37,7 @@ import com.google.common.collect.Sets;
*/
@Singleton
public class BucketToResourceList implements
Function<ListBucketResponse, ListContainerResponse<? extends ResourceMetadata>> {
Function<ListBucketResponse, ListContainerResponse<? extends StorageMetadata>> {
private final ObjectToBlobMetadata object2blobMd;
private final CommonPrefixesToResourceMetadata prefix2ResourceMd;
@ -48,10 +48,10 @@ public class BucketToResourceList implements
this.prefix2ResourceMd = prefix2ResourceMd;
}
public ListContainerResponse<? extends ResourceMetadata> apply(ListBucketResponse from) {
SortedSet<ResourceMetadata> contents = Sets.newTreeSet(Iterables.concat(Iterables.transform(
public ListContainerResponse<? extends StorageMetadata> apply(ListBucketResponse from) {
SortedSet<StorageMetadata> contents = Sets.newTreeSet(Iterables.concat(Iterables.transform(
from, object2blobMd), prefix2ResourceMd.apply(from.getCommonPrefixes())));
return new ListContainerResponseImpl<ResourceMetadata>(contents, from.getPrefix(), from.getMarker(),
return new ListContainerResponseImpl<StorageMetadata>(contents, from.getPrefix(), from.getMarker(),
from.getMaxKeys(), from.isTruncated());
}

View File

@ -21,10 +21,10 @@ package org.jclouds.aws.s3.blobstore.functions;
import javax.inject.Singleton;
import org.jclouds.aws.s3.domain.BucketMetadata;
import org.jclouds.blobstore.domain.MutableResourceMetadata;
import org.jclouds.blobstore.domain.ResourceMetadata;
import org.jclouds.blobstore.domain.ResourceType;
import org.jclouds.blobstore.domain.internal.MutableResourceMetadataImpl;
import org.jclouds.blobstore.domain.MutableStorageMetadata;
import org.jclouds.blobstore.domain.StorageMetadata;
import org.jclouds.blobstore.domain.StorageType;
import org.jclouds.blobstore.domain.internal.MutableStorageMetadataImpl;
import com.google.common.base.Function;
@ -32,11 +32,11 @@ import com.google.common.base.Function;
* @author Adrian Cole
*/
@Singleton
public class BucketToResourceMetadata implements Function<BucketMetadata, ResourceMetadata> {
public ResourceMetadata apply(BucketMetadata from) {
MutableResourceMetadata to = new MutableResourceMetadataImpl();
public class BucketToResourceMetadata implements Function<BucketMetadata, StorageMetadata> {
public StorageMetadata apply(BucketMetadata from) {
MutableStorageMetadata to = new MutableStorageMetadataImpl();
to.setName(from.getName());
to.setType(ResourceType.CONTAINER);
to.setType(StorageType.CONTAINER);
return to;
}
}

View File

@ -20,10 +20,10 @@ package org.jclouds.aws.s3.blobstore.functions;
import javax.inject.Singleton;
import org.jclouds.blobstore.domain.MutableResourceMetadata;
import org.jclouds.blobstore.domain.ResourceMetadata;
import org.jclouds.blobstore.domain.ResourceType;
import org.jclouds.blobstore.domain.internal.MutableResourceMetadataImpl;
import org.jclouds.blobstore.domain.MutableStorageMetadata;
import org.jclouds.blobstore.domain.StorageMetadata;
import org.jclouds.blobstore.domain.StorageType;
import org.jclouds.blobstore.domain.internal.MutableStorageMetadataImpl;
import com.google.common.base.Function;
import com.google.common.collect.Iterables;
@ -33,14 +33,14 @@ import com.google.common.collect.Iterables;
*/
@Singleton
public class CommonPrefixesToResourceMetadata implements
Function<Iterable<String>, Iterable<ResourceMetadata>> {
public Iterable<ResourceMetadata> apply(
Function<Iterable<String>, Iterable<StorageMetadata>> {
public Iterable<StorageMetadata> apply(
Iterable<String> prefixes) {
return Iterables.transform(prefixes, new Function<String, ResourceMetadata>() {
public ResourceMetadata apply(String from) {
MutableResourceMetadata returnVal = new MutableResourceMetadataImpl();
returnVal.setType(ResourceType.RELATIVE_PATH);
return Iterables.transform(prefixes, new Function<String, StorageMetadata>() {
public StorageMetadata apply(String from) {
MutableStorageMetadata returnVal = new MutableStorageMetadataImpl();
returnVal.setType(StorageType.RELATIVE_PATH);
returnVal.setName(from);
return returnVal;
}

View File

@ -23,7 +23,7 @@ import javax.inject.Singleton;
import org.jclouds.aws.s3.domain.ObjectMetadata;
import org.jclouds.blobstore.domain.MutableBlobMetadata;
import org.jclouds.blobstore.domain.ResourceType;
import org.jclouds.blobstore.domain.StorageType;
import org.jclouds.blobstore.domain.internal.MutableBlobMetadataImpl;
import org.jclouds.blobstore.strategy.IsDirectoryStrategy;
@ -49,11 +49,11 @@ public class ObjectToBlobMetadata implements Function<ObjectMetadata, MutableBlo
to.setETag(from.getETag());
to.setName(from.getKey());
to.setSize(from.getSize());
to.setType(ResourceType.BLOB);
to.setType(StorageType.BLOB);
to.setLastModified(from.getLastModified());
to.setUserMetadata(from.getUserMetadata());
if (isDirectoryStrategy.execute(to)) {
to.setType(ResourceType.RELATIVE_PATH);
to.setType(StorageType.RELATIVE_PATH);
}
return to;
}

View File

@ -29,8 +29,8 @@ import org.jclouds.aws.s3.domain.ObjectMetadata;
import org.jclouds.aws.s3.domain.internal.TreeSetListBucketResponse;
import org.jclouds.blobstore.domain.BlobMetadata;
import org.jclouds.blobstore.domain.ListContainerResponse;
import org.jclouds.blobstore.domain.ResourceMetadata;
import org.jclouds.blobstore.domain.ResourceType;
import org.jclouds.blobstore.domain.StorageMetadata;
import org.jclouds.blobstore.domain.StorageType;
import com.google.common.base.Function;
import com.google.common.base.Predicate;
@ -42,7 +42,7 @@ import com.google.common.collect.Sets;
*/
@Singleton
public class ResourceToBucketList implements
Function<ListContainerResponse<? extends ResourceMetadata>, ListBucketResponse> {
Function<ListContainerResponse<? extends StorageMetadata>, ListBucketResponse> {
private final BlobToObjectMetadata blob2ObjectMd;
@Inject
@ -50,33 +50,33 @@ public class ResourceToBucketList implements
this.blob2ObjectMd = blob2ObjectMd;
}
public ListBucketResponse apply(ListContainerResponse<? extends ResourceMetadata> list) {
public ListBucketResponse apply(ListContainerResponse<? extends StorageMetadata> list) {
Iterable<ObjectMetadata> contents = Iterables.transform(Iterables.filter(
list, new Predicate<ResourceMetadata>() {
list, new Predicate<StorageMetadata>() {
public boolean apply(ResourceMetadata input) {
return input.getType() == ResourceType.BLOB;
public boolean apply(StorageMetadata input) {
return input.getType() == StorageType.BLOB;
}
}), new Function<ResourceMetadata, ObjectMetadata>() {
}), new Function<StorageMetadata, ObjectMetadata>() {
public MutableObjectMetadata apply(ResourceMetadata from) {
public MutableObjectMetadata apply(StorageMetadata from) {
return blob2ObjectMd.apply((BlobMetadata) from);
}
});
SortedSet<String> commonPrefixes = Sets.newTreeSet(Iterables.transform(Iterables.filter(list,
new Predicate<ResourceMetadata>() {
new Predicate<StorageMetadata>() {
public boolean apply(ResourceMetadata input) {
return input.getType() == ResourceType.RELATIVE_PATH;
public boolean apply(StorageMetadata input) {
return input.getType() == StorageType.RELATIVE_PATH;
}
}), new Function<ResourceMetadata, String>() {
}), new Function<StorageMetadata, String>() {
public String apply(ResourceMetadata from) {
public String apply(StorageMetadata from) {
return from.getName();
}

View File

@ -32,84 +32,6 @@ public class BucketMetadata implements Comparable<BucketMetadata> {
private final CanonicalUser owner;
private final String name;
/**
* Location constraint of the bucket.
*
* @author Adrian Cole
* @see <a href= "http://docs.amazonwebservices.com/AmazonS3/latest/RESTBucketLocationGET.html"
* />
* @see <a href=
* "http://docs.amazonwebservices.com/AmazonS3/latest/dev/index.html?LocationSelection.html"
* />
*/
public static enum LocationConstraint {
/**
*
* US StandardUses Amazon S3 servers in the United States
* <p/>
* This is the default Region. All requests sent to s3.amazonaws.com go to this Region unless
* you specify a LocationConstraint on a bucket. The US Standard Region automatically places
* your data in either Amazon's east or west coast data centers depending on what will provide
* you with the lowest latency. To use this region, do not set the LocationConstraint bucket
* parameter. The US Standard Region provides eventual consistency for all requests.
*/
US_STANDARD,
/**
* Uses Amazon S3 servers in Ireland.
* <p/>
* In Amazon S3, the EU (Ireland) Region provides read-after-write consistency for PUTS of new
* objects in your Amazon S3 bucket and eventual consistency for overwrite PUTS and DELETES.
*/
EU,
/**
* US-West (Northern California)Uses Amazon S3 servers in Northern California
* <p/>
* Optionally, use the endpoint s3-us-west-1.amazonaws.com on all requests to this bucket to
* reduce the latency you might experience after the first hour of creating a bucket in this
* Region.
* <p/>
* In Amazon S3, the US-West (Northern California) Region provides read-after-write
* consistency for PUTS of new objects in your Amazon S3 bucket and eventual consistency for
* overwrite PUTS and DELETES.
*/
US_WEST;
/**
* returns the value expected in xml documents from the S3 service.
* <p/>
* {@code US_STANDARD} is returned as "" xml documents, so we return "".
*/
public String value() {
switch (this) {
case US_STANDARD:
return "";
case EU:
return "EU";
case US_WEST:
return "us-west-1";
default:
throw new IllegalStateException("unimplemented location: " + this);
}
}
/**
* parses the value expected in xml documents from the S3 service.=
* <p/>
* {@code US_STANDARD} is returned as "" xml documents.
*/
public static LocationConstraint fromValue(String v) {
if (v.equals(""))
return US_STANDARD;
if (v.equals("EU"))
return EU;
else if (v.equals("us-west-1"))
return US_WEST;
throw new IllegalStateException("unimplemented location: " + v);
}
}
public BucketMetadata(String name, Date creationDate, CanonicalUser owner) {
this.name = name;
this.creationDate = creationDate;

View File

@ -0,0 +1,51 @@
package org.jclouds.aws.s3.functions;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import javax.inject.Singleton;
import org.jclouds.aws.domain.Region;
import org.jclouds.http.HttpRequest;
import org.jclouds.rest.binders.BindToStringPayload;
/**
*
* Depending on your latency and legal requirements, you can specify a location constraint that will
* affect where your data physically resides.
*
* @author Adrian Cole
*
*/
@Singleton
public class BindRegionToXmlPayload extends BindToStringPayload {
@Override
public void bindToRequest(HttpRequest request, Object input) {
checkArgument(checkNotNull(input, "input") instanceof Region,
"this binder is only valid for Region!");
Region constraint = (Region) input;
String value = null;
switch (constraint) {
case US_STANDARD:
case US_EAST_1:
case DEFAULT:// TODO get this from the url
return;
case EU_WEST_1:
value = "EU";
break;
case US_WEST_1:
value = "us-west-1";
break;
default:
throw new IllegalStateException("unimplemented location: " + this);
}
super
.bindToRequest(
request,
String
.format(
"<CreateBucketConfiguration><LocationConstraint>%s</LocationConstraint></CreateBucketConfiguration>",
value));
}
}

View File

@ -21,7 +21,6 @@ package org.jclouds.aws.s3.options;
import static com.google.common.base.Preconditions.checkNotNull;
import org.jclouds.aws.s3.domain.CannedAccessPolicy;
import org.jclouds.aws.s3.domain.BucketMetadata.LocationConstraint;
import org.jclouds.aws.s3.reference.S3Headers;
import org.jclouds.http.options.BaseHttpRequestOptions;
@ -47,20 +46,6 @@ import org.jclouds.http.options.BaseHttpRequestOptions;
*/
public class PutBucketOptions extends BaseHttpRequestOptions {
private CannedAccessPolicy acl = CannedAccessPolicy.PRIVATE;
private LocationConstraint constraint;
/**
* Depending on your latency and legal requirements, you can specify a location constraint that
* will affect where your data physically resides.
*/
public PutBucketOptions createIn(LocationConstraint constraint) {
this.constraint = checkNotNull(constraint, "constraint");
this.payload = String
.format(
"<CreateBucketConfiguration><LocationConstraint>%s</LocationConstraint></CreateBucketConfiguration>",
constraint.value());
return this;
}
/**
* Override the default ACL (private) with the specified one.
@ -75,30 +60,15 @@ public class PutBucketOptions extends BaseHttpRequestOptions {
}
/**
* @see PutBucketOptions#withBucketAcl(CannedAccessPolicy)
* @see PutBucketOptions#withBucketAcl
*/
public CannedAccessPolicy getAcl() {
return acl;
}
/**
* @see PutBucketOptions#createIn(org.jclouds.aws.s3.domain.BucketMetadata.LocationConstraint)
*/
public LocationConstraint getLocationConstraint() {
return constraint;
}
public static class Builder {
/**
* @see PutBucketOptions#createIn(org.jclouds.aws.s3.domain.BucketMetadata.LocationConstraint)
*/
public static PutBucketOptions createIn(LocationConstraint constraint) {
PutBucketOptions options = new PutBucketOptions();
return options.createIn(constraint);
}
/**
* @see PutBucketOptions#withBucketAcl(CannedAccessPolicy)
* @see PutBucketOptions#withBucketAcl
*/
public static PutBucketOptions withBucketAcl(CannedAccessPolicy acl) {
PutBucketOptions options = new PutBucketOptions();

View File

@ -18,27 +18,42 @@
*/
package org.jclouds.aws.s3.xml;
import org.jclouds.aws.s3.domain.BucketMetadata.LocationConstraint;
import org.jclouds.aws.domain.Region;
import org.jclouds.http.functions.ParseSax;
/**
* Parses the response from Amazon S3 GET Bucket Location
* <p/>
* LocationConstraint is the document we expect to parse.
* Region is the document we expect to parse.
*
* @see <a href= "http://docs.amazonwebservices.com/AmazonS3/latest/RESTBucketLocationGET.html" />
* @author Adrian Cole
*/
public class LocationConstraintHandler extends ParseSax.HandlerWithResult<LocationConstraint> {
public class LocationConstraintHandler extends ParseSax.HandlerWithResult<Region> {
private StringBuilder currentText = new StringBuilder();
private LocationConstraint constraint;
private Region region;
public LocationConstraint getResult() {
return constraint;
public Region getResult() {
return region;
}
public void endElement(String uri, String name, String qName) {
constraint = LocationConstraint.fromValue(currentText.toString().trim());
region = fromValue(currentText.toString().trim());
}
/**
* parses the value expected in xml documents from the S3 service.=
* <p/>
* {@code US_STANDARD} is returned as "" xml documents.
*/
public static Region fromValue(String v) {
if (v.equals(""))
return Region.US_STANDARD;
if (v.equals("EU"))
return Region.EU_WEST_1;
else if (v.equals("us-west-1"))
return Region.US_WEST_1;
throw new IllegalStateException("unimplemented location: " + v);
}
public void characters(char ch[], int start, int length) {

View File

@ -68,7 +68,7 @@ public interface SQSAsyncClient {
ListQueuesOptions... options);
/**
* @see SQSClient#createQueuesInRegion
* @see SQSClient#createQueueInRegion
*/
@POST
@Path("/")

View File

@ -164,7 +164,7 @@ public class CloudApplicationArchitecturesEC2ClientLiveTest {
.withSecurityGroup(securityGroupName) // group I created above
.withUserData(script.getBytes())); // script to run as root
instance = Iterables.getOnlyElement(reservation.getRunningInstances());
instance = Iterables.getOnlyElement(reservation);
} catch (HttpResponseException htpe) {
if (htpe.getResponse().getStatusCode() == 400)
@ -339,9 +339,8 @@ public class CloudApplicationArchitecturesEC2ClientLiveTest {
Reservation reservation = Iterables.getOnlyElement(client.getInstanceServices()
.describeInstancesInRegion(Region.DEFAULT, instanceId));
assertNotNull(Iterables.getOnlyElement(reservation.getRunningInstances()).getIpAddress());
assertFalse(Iterables.getOnlyElement(reservation.getRunningInstances()).getIpAddress()
.equals(address));
assertNotNull(Iterables.getOnlyElement(reservation).getIpAddress());
assertFalse(Iterables.getOnlyElement(reservation).getIpAddress().equals(address));
doCheckKey(address);
@ -393,7 +392,7 @@ public class CloudApplicationArchitecturesEC2ClientLiveTest {
Set<Reservation> reservations = client.getInstanceServices().describeInstancesInRegion(
Region.DEFAULT, instanceId); // last parameter (ids) narrows the search
return Iterables.getOnlyElement(Iterables.getOnlyElement(reservations).getRunningInstances());
return Iterables.getOnlyElement(Iterables.getOnlyElement(reservations));
}
/**

View File

@ -206,7 +206,7 @@ public class EBSBootEC2ClientLiveTest {
withKeyName(keyPair.getKeyName())// key I created above
.asType(InstanceType.M1_SMALL)// smallest instance size
.withSecurityGroup(securityGroupName));// group I created above
instance = Iterables.getOnlyElement(reservation.getRunningInstances());
instance = Iterables.getOnlyElement(reservation);
} catch (HttpResponseException htpe) {
if (htpe.getResponse().getStatusCode() == 400)
continue;
@ -540,8 +540,7 @@ public class EBSBootEC2ClientLiveTest {
Set<Reservation> reservations = client.getInstanceServices().describeInstancesInRegion(
instance.getRegion(), instance.getId()); // last parameter (ids) narrows the search
instance = Iterables.getOnlyElement(Iterables.getOnlyElement(reservations)
.getRunningInstances());
instance = Iterables.getOnlyElement(Iterables.getOnlyElement(reservations));
System.out.printf("%d: %s awaiting ssh service to start%n", System.currentTimeMillis(),
instance.getIpAddress());

View File

@ -23,7 +23,6 @@ import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
import java.io.IOException;
import java.io.InputStream;
import java.net.InetSocketAddress;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
@ -31,19 +30,20 @@ import java.util.concurrent.TimeoutException;
import org.jclouds.compute.ComputeServiceContext;
import org.jclouds.compute.ComputeServiceContextFactory;
import org.jclouds.compute.domain.ComputeMetadata;
import org.jclouds.compute.domain.ComputeType;
import org.jclouds.compute.domain.CreateNodeResponse;
import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.LoginType;
import org.jclouds.compute.domain.NodeIdentity;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.Profile;
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
import org.jclouds.predicates.RetryablePredicate;
import org.jclouds.predicates.SocketOpen;
import org.jclouds.ssh.ExecResponse;
import org.jclouds.ssh.SshClient;
import org.jclouds.ssh.SshException;
import org.jclouds.ssh.jsch.config.JschSshClientModule;
import org.jclouds.util.Utils;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeGroups;
import org.testng.annotations.Test;
@ -62,7 +62,7 @@ import com.google.inject.Injector;
public class EC2ComputeServiceLiveTest {
protected SshClient.Factory sshFactory;
private String nodePrefix = System.getProperty("user.name") + ".ec2";
private String nodePrefix = System.getProperty("user.name") + ".ec2serv";
private RetryablePredicate<InetSocketAddress> socketTester;
private CreateNodeResponse node;
@ -83,7 +83,8 @@ public class EC2ComputeServiceLiveTest {
}
public void testCreate() throws Exception {
node = context.getComputeService().createNode(nodePrefix, Profile.SMALLEST, Image.RHEL_53);
node = context.getComputeService().startNodeInLocation("default", nodePrefix,
Profile.SMALLEST, Image.UBUNTU_90);
assertNotNull(node.getId());
assertEquals(node.getLoginPort(), 22);
assertEquals(node.getLoginType(), LoginType.SSH);
@ -98,7 +99,7 @@ public class EC2ComputeServiceLiveTest {
@Test(dependsOnMethods = "testCreate")
public void testGet() throws Exception {
NodeMetadata metadata = context.getComputeService().getNodeMetadata(node.getId());
NodeMetadata metadata = context.getComputeService().getNodeMetadata(node);
assertEquals(metadata.getId(), node.getId());
assertEquals(metadata.getLoginPort(), node.getLoginPort());
assertEquals(metadata.getLoginType(), node.getLoginType());
@ -108,8 +109,10 @@ public class EC2ComputeServiceLiveTest {
}
public void testList() throws Exception {
for (NodeIdentity node : context.getComputeService().listNodes()) {
for (ComputeMetadata node : context.getComputeService().listNodes()) {
assert node.getId() != null;
assert node.getLocation() != null;
assertEquals(node.getType(), ComputeType.NODE);
}
}
@ -129,22 +132,24 @@ public class EC2ComputeServiceLiveTest {
InetSocketAddress socket = new InetSocketAddress(node.getPublicAddresses().last(), node
.getLoginPort());
socketTester.apply(socket);
SshClient connection = sshFactory.create(socket, node.getCredentials().account, node
.getCredentials().key.getBytes());
SshClient ssh = node.getCredentials().key.startsWith("-----BEGIN RSA PRIVATE KEY-----") ? sshFactory
.create(socket, node.getCredentials().account, node.getCredentials().key.getBytes())
: sshFactory
.create(socket, node.getCredentials().account, node.getCredentials().key);
try {
connection.connect();
InputStream etcPasswd = connection.get("/etc/passwd");
Utils.toStringAndClose(etcPasswd);
ssh.connect();
ExecResponse hello = ssh.exec("echo hello");
assertEquals(hello.getOutput().trim(), "hello");
} finally {
if (connection != null)
connection.disconnect();
if (ssh != null)
ssh.disconnect();
}
}
@AfterTest
void cleanup() throws InterruptedException, ExecutionException, TimeoutException {
if (node != null)
context.getComputeService().destroyNode(node.getId());
context.getComputeService().destroyNode(node);
context.close();
}

View File

@ -19,11 +19,9 @@
package org.jclouds.aws.ec2.services;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
import java.util.Iterator;
import java.util.SortedSet;
import java.util.Set;
import org.jclouds.aws.domain.Region;
import org.jclouds.aws.ec2.EC2ContextFactory;
@ -33,7 +31,6 @@ import org.testng.annotations.BeforeGroups;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
/**
* Tests behavior of {@code EC2Client}
@ -60,27 +57,9 @@ public class InstanceClientLiveTest {
void testDescribeInstances() {
for (Region region : ImmutableSet.of(Region.DEFAULT, Region.EU_WEST_1, Region.US_EAST_1,
Region.US_WEST_1)) {
SortedSet<Reservation> allResults = Sets.newTreeSet(client
.describeInstancesInRegion(region));
Set<Reservation> allResults = client.describeInstancesInRegion(region);
assertNotNull(allResults);
assert allResults.size() >= 0 : allResults.size();
if (allResults.size() >= 2) {
Iterator<Reservation> iterator = allResults.iterator();
String id1 = Sets.newTreeSet(iterator.next().getRunningInstances()).first()
.getId();
String id2 = Sets.newTreeSet(iterator.next().getRunningInstances()).first()
.getId();
SortedSet<Reservation> twoResults = Sets.newTreeSet(client.describeInstancesInRegion(
region, id1, id2));
assertNotNull(twoResults);
assertEquals(twoResults.size(), 2);
iterator = allResults.iterator();
assertEquals(Sets.newTreeSet(iterator.next().getRunningInstances()).first()
.getId(), id1);
assertEquals(Sets.newTreeSet(iterator.next().getRunningInstances()).first()
.getId(), id2);
}
}
}
}

View File

@ -42,6 +42,7 @@ import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSortedSet;
import com.google.common.collect.Sets;
@ -68,7 +69,7 @@ public class RunInstancesResponseHandlerTest extends BaseHandlerTest {
InputStream is = getClass().getResourceAsStream("/ec2/run_instances.xml");
Reservation expected = new Reservation(Region.DEFAULT, ImmutableSortedSet.of("default"),
ImmutableSortedSet.of(new RunningInstance(Region.DEFAULT, "0", null, "ami-60a54009",
ImmutableSet.of(new RunningInstance(Region.DEFAULT, "0", null, "ami-60a54009",
"i-2ba64342", InstanceState.PENDING, InstanceType.M1_SMALL,
(InetAddress) null, null, "example-key-name", dateService
.iso8601DateParse("2007-08-07T11:51:50.000Z"), true,
@ -76,7 +77,7 @@ public class RunInstancesResponseHandlerTest extends BaseHandlerTest {
.<String> newTreeSet(), null, null, null, null,
RootDeviceType.INSTANCE_STORE, null, ImmutableMap
.<String, EbsBlockDevice> of()), new RunningInstance(
Region.DEFAULT, "0", null, "ami-60a54009", "i-2bc64242",
Region.DEFAULT, "1", null, "ami-60a54009", "i-2bc64242",
InstanceState.PENDING, InstanceType.M1_SMALL, (InetAddress) null, null,
"example-key-name", dateService
.iso8601DateParse("2007-08-07T11:51:50.000Z"), true,
@ -84,7 +85,7 @@ public class RunInstancesResponseHandlerTest extends BaseHandlerTest {
.<String> newTreeSet(), null, null, null, null,
RootDeviceType.INSTANCE_STORE, null, ImmutableMap
.<String, EbsBlockDevice> of()), new RunningInstance(
Region.DEFAULT, "0", null, "ami-60a54009", "i-2be64332",
Region.DEFAULT, "2", null, "ami-60a54009", "i-2be64332",
InstanceState.PENDING, InstanceType.M1_SMALL, (InetAddress) null, null,
"example-key-name", dateService
.iso8601DateParse("2007-08-07T11:51:50.000Z"), true,

View File

@ -25,6 +25,7 @@ import java.lang.reflect.Array;
import java.lang.reflect.Method;
import java.net.URI;
import org.jclouds.aws.domain.Region;
import org.jclouds.aws.s3.blobstore.functions.BlobToObject;
import org.jclouds.aws.s3.config.S3ObjectModule;
import org.jclouds.aws.s3.domain.AccessControlList;
@ -352,11 +353,12 @@ public class S3AsyncClientTest extends RestClientTest<S3AsyncClient> {
checkFilters(httpMethod);
}
public void testPutBucketIfNotExists() throws ArrayIndexOutOfBoundsException, SecurityException,
public void testPutBucketDefault() throws ArrayIndexOutOfBoundsException, SecurityException,
IllegalArgumentException, NoSuchMethodException, IOException {
Method method = S3AsyncClient.class.getMethod("putBucketIfNotExists", String.class, Array
.newInstance(PutBucketOptions.class, 0).getClass());
GeneratedHttpRequest<S3AsyncClient> httpMethod = processor.createRequest(method, "bucket");
Method method = S3AsyncClient.class.getMethod("putBucketInRegion", Region.class,
String.class, Array.newInstance(PutBucketOptions.class, 0).getClass());
GeneratedHttpRequest<S3AsyncClient> httpMethod = processor.createRequest(method,
Region.DEFAULT, "bucket");
assertRequestLineEquals(httpMethod, "PUT http://bucket.stub:8080/ HTTP/1.1");
assertHeadersEqual(httpMethod, "Content-Length: 0\nHost: bucket.stub\n");
@ -369,6 +371,24 @@ public class S3AsyncClientTest extends RestClientTest<S3AsyncClient> {
checkFilters(httpMethod);
}
public void testPutBucketEu() throws ArrayIndexOutOfBoundsException, SecurityException,
IllegalArgumentException, NoSuchMethodException, IOException {
Method method = S3AsyncClient.class.getMethod("putBucketInRegion", Region.class,
String.class, Array.newInstance(PutBucketOptions.class, 0).getClass());
GeneratedHttpRequest<S3AsyncClient> httpMethod = processor.createRequest(method,
Region.EU_WEST_1, "bucket");
assertRequestLineEquals(httpMethod, "PUT http://bucket.stub:8080/ HTTP/1.1");
assertHeadersEqual(httpMethod, "Content-Length: 98\nContent-Type: application/unknown\nHost: bucket.stub\n");
assertPayloadEquals(httpMethod, "<CreateBucketConfiguration><LocationConstraint>EU</LocationConstraint></CreateBucketConfiguration>");
assertResponseParserClassEquals(method, httpMethod, ReturnTrueIf2xx.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, ReturnTrueIfBucketAlreadyOwnedByYou.class);
checkFilters(httpMethod);
}
public void testPutObject() throws ArrayIndexOutOfBoundsException, SecurityException,
IllegalArgumentException, NoSuchMethodException, IOException {

View File

@ -31,6 +31,7 @@ import java.util.concurrent.ConcurrentMap;
import javax.inject.Inject;
import org.jclouds.aws.domain.Region;
import org.jclouds.aws.s3.S3AsyncClient;
import org.jclouds.aws.s3.blobstore.S3AsyncBlobStore;
import org.jclouds.aws.s3.blobstore.functions.BlobToObject;
@ -49,7 +50,6 @@ import org.jclouds.aws.s3.domain.S3Object;
import org.jclouds.aws.s3.domain.AccessControlList.CanonicalUserGrantee;
import org.jclouds.aws.s3.domain.AccessControlList.EmailAddressGrantee;
import org.jclouds.aws.s3.domain.AccessControlList.Grant;
import org.jclouds.aws.s3.domain.BucketMetadata.LocationConstraint;
import org.jclouds.aws.s3.options.CopyObjectOptions;
import org.jclouds.aws.s3.options.ListBucketOptions;
import org.jclouds.aws.s3.options.PutBucketOptions;
@ -114,7 +114,7 @@ public class StubS3AsyncClient implements S3AsyncClient {
public static final String TEST_ACL_ID = "1a405254c932b52e5b5caaa88186bc431a1bacb9ece631f835daddaf0c47677c";
public static final String TEST_ACL_EMAIL = "james@misterm.org";
private static Map<String, BucketMetadata.LocationConstraint> bucketToLocation = new ConcurrentHashMap<String, BucketMetadata.LocationConstraint>();
private static Map<String, Region> bucketToLocation = new ConcurrentHashMap<String, Region>();
/**
* An S3 item's "ACL" may be a {@link CannedAccessPolicy} or an {@link AccessControlList}.
@ -123,14 +123,14 @@ public class StubS3AsyncClient implements S3AsyncClient {
public static final String DEFAULT_OWNER_ID = "abc123";
public ListenableFuture<Boolean> putBucketIfNotExists(String name,
@Override
public ListenableFuture<Boolean> putBucketInRegion(Region region, String name,
PutBucketOptions... optionsList) {
final PutBucketOptions options = (optionsList.length == 0) ? new PutBucketOptions()
: optionsList[0];
if (options.getLocationConstraint() != null)
bucketToLocation.put(name, options.getLocationConstraint());
bucketToLocation.put(name, region);
keyToAcl.put(name, options.getAcl());
return blobStore.createContainer(name);
return blobStore.createContainerInLocation(region.value(), name);
}
public ListenableFuture<ListBucketResponse> listBucket(final String name,
@ -292,8 +292,8 @@ public class StubS3AsyncClient implements S3AsyncClient {
}
@Override
public ListenableFuture<LocationConstraint> getBucketLocation(String bucketName) {
return immediateFuture(LocationConstraint.US_STANDARD);
public ListenableFuture<Region> getBucketLocation(String bucketName) {
return immediateFuture(bucketToLocation.get(bucketName));
}
@Override

View File

@ -18,80 +18,43 @@
*/
package org.jclouds.aws.s3.options;
import com.google.common.collect.Multimap;
import static org.jclouds.aws.s3.options.PutBucketOptions.Builder.createIn;
import static org.jclouds.aws.s3.options.PutBucketOptions.Builder.withBucketAcl;
import org.jclouds.aws.s3.domain.CannedAccessPolicy;
import org.jclouds.aws.s3.domain.BucketMetadata.LocationConstraint;
import org.jclouds.aws.s3.options.PutBucketOptions;
import org.jclouds.aws.s3.reference.S3Headers;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNull;
import org.testng.annotations.Test;
import java.io.UnsupportedEncodingException;
import org.jclouds.aws.s3.domain.CannedAccessPolicy;
import org.jclouds.aws.s3.reference.S3Headers;
import org.testng.annotations.Test;
import com.google.common.collect.Multimap;
/**
* Tests possible uses of PutBucketOptions and PutBucketOptions.Builder.*
*
*
* @author Adrian Cole
*/
@Test(groups = "unit", testName = "s3.PutBucketOptionsTest")
public class PutBucketOptionsTest {
@Test
public void testLocationConstraint() {
PutBucketOptions options = new PutBucketOptions();
options.createIn(LocationConstraint.EU);
assertEquals(options.getLocationConstraint(), LocationConstraint.EU);
}
@Test
public void testAclDefault() {
PutBucketOptions options = new PutBucketOptions();
assertEquals(options.getAcl(), CannedAccessPolicy.PRIVATE);
}
@Test
public void testPayload() {
PutBucketOptions options = new PutBucketOptions();
options.createIn(LocationConstraint.EU);
assertEquals(
options.buildStringPayload(),
"<CreateBucketConfiguration><LocationConstraint>EU</LocationConstraint></CreateBucketConfiguration>");
}
@Test
public void testAclStatic() {
PutBucketOptions options = withBucketAcl(CannedAccessPolicy.AUTHENTICATED_READ);
assertEquals(options.getAcl(), CannedAccessPolicy.AUTHENTICATED_READ);
}
@Test
public void testNullLocationConstraint() {
PutBucketOptions options = new PutBucketOptions();
assertNull(options.getLocationConstraint());
}
@Test
void testBuildRequestHeaders() throws UnsupportedEncodingException {
@Test
public void testLocationConstraintStatic() {
PutBucketOptions options = createIn(LocationConstraint.EU);
assertEquals(options.getLocationConstraint(), LocationConstraint.EU);
}
@Test(expectedExceptions = NullPointerException.class)
public void testNPE() {
createIn(null);
}
@Test
public void testAclDefault() {
PutBucketOptions options = new PutBucketOptions();
assertEquals(options.getAcl(), CannedAccessPolicy.PRIVATE);
}
@Test
public void testAclStatic() {
PutBucketOptions options = withBucketAcl(CannedAccessPolicy.AUTHENTICATED_READ);
assertEquals(options.getAcl(), CannedAccessPolicy.AUTHENTICATED_READ);
}
@Test
void testBuildRequestHeaders() throws UnsupportedEncodingException {
Multimap<String, String> headers = withBucketAcl(
CannedAccessPolicy.AUTHENTICATED_READ).buildRequestHeaders();
assertEquals(headers.get(S3Headers.CANNED_ACL).iterator().next(),
CannedAccessPolicy.AUTHENTICATED_READ.toString());
}
Multimap<String, String> headers = withBucketAcl(CannedAccessPolicy.AUTHENTICATED_READ)
.buildRequestHeaders();
assertEquals(headers.get(S3Headers.CANNED_ACL).iterator().next(),
CannedAccessPolicy.AUTHENTICATED_READ.toString());
}
}

View File

@ -22,7 +22,6 @@ import static org.jclouds.aws.s3.options.ListBucketOptions.Builder.afterMarker;
import static org.jclouds.aws.s3.options.ListBucketOptions.Builder.delimiter;
import static org.jclouds.aws.s3.options.ListBucketOptions.Builder.maxResults;
import static org.jclouds.aws.s3.options.ListBucketOptions.Builder.withPrefix;
import static org.jclouds.aws.s3.options.PutBucketOptions.Builder.createIn;
import static org.jclouds.aws.s3.options.PutBucketOptions.Builder.withBucketAcl;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNull;
@ -36,6 +35,7 @@ import java.util.SortedSet;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeoutException;
import org.jclouds.aws.domain.Region;
import org.jclouds.aws.s3.S3AsyncClient;
import org.jclouds.aws.s3.S3Client;
import org.jclouds.aws.s3.domain.AccessControlList;
@ -50,7 +50,6 @@ import org.jclouds.aws.s3.domain.AccessControlList.EmailAddressGrantee;
import org.jclouds.aws.s3.domain.AccessControlList.Grant;
import org.jclouds.aws.s3.domain.AccessControlList.GroupGranteeURI;
import org.jclouds.aws.s3.domain.AccessControlList.Permission;
import org.jclouds.aws.s3.domain.BucketMetadata.LocationConstraint;
import org.jclouds.aws.s3.internal.StubS3AsyncClient;
import org.jclouds.blobstore.integration.internal.BaseBlobStoreIntegrationTest;
import org.jclouds.util.Utils;
@ -148,7 +147,7 @@ public class BucketsLiveTest extends BaseBlobStoreIntegrationTest<S3AsyncClient,
public void testPublicReadAccessPolicy() throws Exception {
String bucketName = getScratchContainerName();
try {
context.getApi().putBucketIfNotExists(bucketName,
context.getApi().putBucketInRegion(Region.DEFAULT, bucketName,
withBucketAcl(CannedAccessPolicy.PUBLIC_READ));
AccessControlList acl = context.getApi().getBucketACL(bucketName);
assertTrue(acl.hasPermission(GroupGranteeURI.ALL_USERS, Permission.READ), acl.toString());
@ -176,8 +175,7 @@ public class BucketsLiveTest extends BaseBlobStoreIntegrationTest<S3AsyncClient,
public void testDefaultBucketLocation() throws Exception {
String bucketName = getContainerName();
try {
assertEquals(LocationConstraint.US_STANDARD, context.getApi()
.getBucketLocation(bucketName));
assertEquals(Region.US_STANDARD, context.getApi().getBucketLocation(bucketName));
} finally {
returnContainer(bucketName);
}
@ -232,8 +230,8 @@ public class BucketsLiveTest extends BaseBlobStoreIntegrationTest<S3AsyncClient,
BucketLogging newLogging = context.getApi().getBucketLogging(bucketName);
AccessControlList acl = new AccessControlList();
for (Grant grant : newLogging.getTargetGrants()) { // TODO: add permission
// checking features to
// bucketlogging
// checking features to
// bucketlogging
acl.addPermission(grant.getGrantee(), grant.getPermission());
}
// EmailAddressGrantee is replaced by a CanonicalUserGrantee, so we cannot test by
@ -277,8 +275,8 @@ public class BucketsLiveTest extends BaseBlobStoreIntegrationTest<S3AsyncClient,
public void testEu() throws Exception {
final String bucketName = getScratchContainerName();
try {
context.getApi().putBucketIfNotExists(bucketName + "eu",
createIn(LocationConstraint.EU).withBucketAcl(CannedAccessPolicy.PUBLIC_READ));
context.getApi().putBucketInRegion(Region.EU_WEST_1, bucketName + "eu",
withBucketAcl(CannedAccessPolicy.PUBLIC_READ));
assertConsistencyAware(new Runnable() {
public void run() {
try {
@ -290,7 +288,7 @@ public class BucketsLiveTest extends BaseBlobStoreIntegrationTest<S3AsyncClient,
}
}
});
assertEquals(LocationConstraint.EU, context.getApi().getBucketLocation(bucketName + "eu"));
assertEquals(Region.EU_WEST_1, context.getApi().getBucketLocation(bucketName + "eu"));
// TODO: I believe that the following should work based on the above acl assertion passing.
// However, it fails on 403
// URL url = new URL(String.format("http://%s.s3.amazonaws.com", bucketName));
@ -306,10 +304,8 @@ public class BucketsLiveTest extends BaseBlobStoreIntegrationTest<S3AsyncClient,
public void testNorthernCalifornia() throws Exception {
final String bucketName = getScratchContainerName();
try {
context.getApi().putBucketIfNotExists(
bucketName + "cali",
createIn(LocationConstraint.US_WEST)
.withBucketAcl(CannedAccessPolicy.PUBLIC_READ));
context.getApi().putBucketInRegion(Region.EU_WEST_1, bucketName + "cali",
withBucketAcl(CannedAccessPolicy.PUBLIC_READ));
assertConsistencyAware(new Runnable() {
public void run() {
try {
@ -321,8 +317,7 @@ public class BucketsLiveTest extends BaseBlobStoreIntegrationTest<S3AsyncClient,
}
}
});
assertEquals(LocationConstraint.US_WEST, context.getApi().getBucketLocation(
bucketName + "cali"));
assertEquals(Region.EU_WEST_1, context.getApi().getBucketLocation(bucketName + "cali"));
// TODO: I believe that the following should work based on the above acl assertion passing.
// However, it fails on 403
// URL url = new URL(String.format("http://%s.s3.amazonaws.com", bucketName));

View File

@ -18,12 +18,13 @@
*/
package org.jclouds.aws.s3.samples;
import org.jclouds.aws.domain.Region;
import org.jclouds.aws.s3.blobstore.S3BlobStoreContextFactory;
import org.jclouds.blobstore.BlobStore;
import org.jclouds.blobstore.BlobStoreContext;
import org.jclouds.blobstore.domain.Blob;
import org.jclouds.blobstore.domain.ResourceMetadata;
import org.jclouds.blobstore.domain.ResourceType;
import org.jclouds.blobstore.domain.StorageMetadata;
import org.jclouds.blobstore.domain.StorageType;
/**
* This the Main class of an Application that demonstrates the use of the blobstore.
@ -56,16 +57,16 @@ public class MainApp {
// Create Container
BlobStore blobStore = context.getBlobStore();
blobStore.createContainer(containerName);
blobStore.createContainerInLocation(Region.DEFAULT.toString(), containerName);
Blob blob = blobStore.newBlob("test");
blob.setPayload("testdata");
blobStore.putBlob(containerName, blob);
// List Container
for (ResourceMetadata resourceMd : blobStore.list()) {
if (resourceMd.getType() == ResourceType.CONTAINER
|| resourceMd.getType() == ResourceType.FOLDER) {
for (StorageMetadata resourceMd : blobStore.list()) {
if (resourceMd.getType() == StorageType.CONTAINER
|| resourceMd.getType() == StorageType.FOLDER) {
System.out.printf(" %s: %s entries%n", resourceMd.getName(), context
.createInputStreamMap(resourceMd.getName()).size());
}

View File

@ -174,7 +174,7 @@ public class MainApp {
.withSecurityGroup(securityGroupName) // group I created above
.withUserData(script.getBytes())); // script to run as root
return Iterables.getOnlyElement(reservation.getRunningInstances());
return Iterables.getOnlyElement(reservation);
}
@ -217,7 +217,7 @@ public class MainApp {
Region.DEFAULT, instanceId); // last parameter (ids) narrows the search
// since we refined by instanceId there should only be one instance
return Iterables.getOnlyElement(Iterables.getOnlyElement(reservations).getRunningInstances());
return Iterables.getOnlyElement(Iterables.getOnlyElement(reservations));
}
private static RunningInstance findInstanceByKeyName(EC2Client client, final String keyName) {
@ -228,7 +228,7 @@ public class MainApp {
// extract all the instances from all reservations
Set<RunningInstance> allInstances = Sets.newHashSet();
for (Reservation reservation : reservations) {
allInstances.addAll(reservation.getRunningInstances());
allInstances.addAll(reservation);
}
// get the first one that has a keyname matching what I just created

View File

@ -26,6 +26,7 @@ import java.util.List;
import java.util.Map;
import java.util.SortedSet;
import org.jclouds.aws.domain.Region;
import org.jclouds.aws.s3.S3AsyncClient;
import org.jclouds.aws.s3.S3Client;
import org.jclouds.aws.s3.blobstore.S3AsyncBlobStore;
@ -121,7 +122,7 @@ public class JCloudsS3Service extends S3Service {
throw new UnsupportedOperationException("Bucket ACL is not yet supported");
try {
if (connection.putBucketIfNotExists(bucketName)) {
if (connection.putBucketInRegion(Region.fromValue(location), bucketName)) {
// Bucket created.
}
} catch (Exception e) {

View File

@ -47,7 +47,7 @@ import org.jclouds.blobstore.KeyNotFoundException;
import org.jclouds.blobstore.domain.Blob;
import org.jclouds.blobstore.domain.BlobMetadata;
import org.jclouds.blobstore.domain.ListContainerResponse;
import org.jclouds.blobstore.domain.ResourceMetadata;
import org.jclouds.blobstore.domain.StorageMetadata;
import org.jclouds.blobstore.domain.Blob.Factory;
import org.jclouds.blobstore.domain.internal.ListResponseImpl;
import org.jclouds.blobstore.functions.BlobToHttpGetOptions;
@ -109,7 +109,10 @@ public class AzureAsyncBlobStore extends BaseAzureBlobStore implements AsyncBlob
}));
}
public ListenableFuture<Boolean> createContainer(String container) {
/**
* Note that location is currently ignored.
*/
public ListenableFuture<Boolean> createContainerInLocation(String location, String container) {
return async.createContainer(container);
}
@ -129,19 +132,19 @@ public class AzureAsyncBlobStore extends BaseAzureBlobStore implements AsyncBlob
return compose(returnVal, object2Blob, service);
}
public ListenableFuture<? extends org.jclouds.blobstore.domain.ListResponse<? extends ResourceMetadata>> list() {
public ListenableFuture<? extends org.jclouds.blobstore.domain.ListResponse<? extends StorageMetadata>> list() {
return compose(
async.listContainers(),
new Function<SortedSet<ListableContainerProperties>, org.jclouds.blobstore.domain.ListResponse<? extends ResourceMetadata>>() {
public org.jclouds.blobstore.domain.ListResponse<? extends ResourceMetadata> apply(
new Function<SortedSet<ListableContainerProperties>, org.jclouds.blobstore.domain.ListResponse<? extends StorageMetadata>>() {
public org.jclouds.blobstore.domain.ListResponse<? extends StorageMetadata> apply(
SortedSet<ListableContainerProperties> from) {
return new ListResponseImpl<ResourceMetadata>(Iterables.transform(from,
return new ListResponseImpl<StorageMetadata>(Iterables.transform(from,
container2ResourceMd), null, null, false);
}
}, service);
}
public ListenableFuture<? extends ListContainerResponse<? extends ResourceMetadata>> list(
public ListenableFuture<? extends ListContainerResponse<? extends StorageMetadata>> list(
String container, ListContainerOptions... optionsList) {
ListBlobsOptions httpOptions = container2ContainerListOptions.apply(optionsList);
ListenableFuture<ListBlobsResponse> returnVal = async.listBlobs(container, httpOptions);

View File

@ -42,7 +42,7 @@ import org.jclouds.blobstore.domain.Blob;
import org.jclouds.blobstore.domain.BlobMetadata;
import org.jclouds.blobstore.domain.ListContainerResponse;
import org.jclouds.blobstore.domain.ListResponse;
import org.jclouds.blobstore.domain.ResourceMetadata;
import org.jclouds.blobstore.domain.StorageMetadata;
import org.jclouds.blobstore.domain.Blob.Factory;
import org.jclouds.blobstore.domain.internal.ListResponseImpl;
import org.jclouds.blobstore.functions.BlobToHttpGetOptions;
@ -86,7 +86,10 @@ public class AzureBlobStore extends BaseAzureBlobStore implements BlobStore {
clearContainerStrategy.execute(container, recursive());
}
public boolean createContainer(String container) {
/**
* Note that location is currently ignored.
*/
public boolean createContainerInLocation(String location, String container) {
return sync.createContainer(container);
}
@ -117,17 +120,17 @@ public class AzureBlobStore extends BaseAzureBlobStore implements BlobStore {
return object2Blob.apply(sync.getBlob(container, key, httpOptions));
}
public ListResponse<? extends ResourceMetadata> list() {
return new Function<SortedSet<ListableContainerProperties>, org.jclouds.blobstore.domain.ListResponse<? extends ResourceMetadata>>() {
public org.jclouds.blobstore.domain.ListResponse<? extends ResourceMetadata> apply(
public ListResponse<? extends StorageMetadata> list() {
return new Function<SortedSet<ListableContainerProperties>, org.jclouds.blobstore.domain.ListResponse<? extends StorageMetadata>>() {
public org.jclouds.blobstore.domain.ListResponse<? extends StorageMetadata> apply(
SortedSet<ListableContainerProperties> from) {
return new ListResponseImpl<ResourceMetadata>(Iterables.transform(from,
return new ListResponseImpl<StorageMetadata>(Iterables.transform(from,
container2ResourceMd), null, null, false);
}
}.apply(sync.listContainers());
}
public ListContainerResponse<? extends ResourceMetadata> list(String container,
public ListContainerResponse<? extends StorageMetadata> list(String container,
ListContainerOptions... optionsList) {
ListBlobsOptions httpOptions = container2ContainerListOptions.apply(optionsList);
return container2ResourceList.apply(sync.listBlobs(container, httpOptions));

View File

@ -20,10 +20,10 @@ package org.jclouds.azure.storage.blob.blobstore.functions;
import javax.inject.Singleton;
import org.jclouds.blobstore.domain.MutableResourceMetadata;
import org.jclouds.blobstore.domain.ResourceMetadata;
import org.jclouds.blobstore.domain.ResourceType;
import org.jclouds.blobstore.domain.internal.MutableResourceMetadataImpl;
import org.jclouds.blobstore.domain.MutableStorageMetadata;
import org.jclouds.blobstore.domain.StorageMetadata;
import org.jclouds.blobstore.domain.StorageType;
import org.jclouds.blobstore.domain.internal.MutableStorageMetadataImpl;
import com.google.common.base.Function;
import com.google.common.collect.Iterables;
@ -33,14 +33,14 @@ import com.google.common.collect.Iterables;
*/
@Singleton
public class CommonPrefixesToResourceMetadata implements
Function<Iterable<String>, Iterable<ResourceMetadata>> {
public Iterable<ResourceMetadata> apply(
Function<Iterable<String>, Iterable<StorageMetadata>> {
public Iterable<StorageMetadata> apply(
Iterable<String> prefixes) {
return Iterables.transform(prefixes, new Function<String, ResourceMetadata>() {
public ResourceMetadata apply(String from) {
MutableResourceMetadata returnVal = new MutableResourceMetadataImpl();
returnVal.setType(ResourceType.RELATIVE_PATH);
return Iterables.transform(prefixes, new Function<String, StorageMetadata>() {
public StorageMetadata apply(String from) {
MutableStorageMetadata returnVal = new MutableStorageMetadataImpl();
returnVal.setType(StorageType.RELATIVE_PATH);
returnVal.setName(from);
return returnVal;
}

View File

@ -21,10 +21,10 @@ package org.jclouds.azure.storage.blob.blobstore.functions;
import javax.inject.Singleton;
import org.jclouds.azure.storage.blob.domain.ListableContainerProperties;
import org.jclouds.blobstore.domain.MutableResourceMetadata;
import org.jclouds.blobstore.domain.ResourceMetadata;
import org.jclouds.blobstore.domain.ResourceType;
import org.jclouds.blobstore.domain.internal.MutableResourceMetadataImpl;
import org.jclouds.blobstore.domain.MutableStorageMetadata;
import org.jclouds.blobstore.domain.StorageMetadata;
import org.jclouds.blobstore.domain.StorageType;
import org.jclouds.blobstore.domain.internal.MutableStorageMetadataImpl;
import com.google.common.base.Function;
@ -32,14 +32,15 @@ import com.google.common.base.Function;
* @author Adrian Cole
*/
@Singleton
public class ContainerToResourceMetadata implements Function<ListableContainerProperties, ResourceMetadata> {
public ResourceMetadata apply(ListableContainerProperties from) {
MutableResourceMetadata to = new MutableResourceMetadataImpl();
public class ContainerToResourceMetadata implements
Function<ListableContainerProperties, StorageMetadata> {
public StorageMetadata apply(ListableContainerProperties from) {
MutableStorageMetadata to = new MutableStorageMetadataImpl();
to.setName(from.getName());
to.setETag(from.getETag());
to.setLastModified(from.getLastModified());
to.setLocation(from.getUrl());
to.setType(ResourceType.CONTAINER);
to.setUri(from.getUrl());
to.setType(StorageType.CONTAINER);
return to;
}
}

View File

@ -26,7 +26,7 @@ import javax.inject.Singleton;
import org.jclouds.azure.storage.blob.domain.ListBlobsResponse;
import org.jclouds.azure.storage.blob.domain.ListableBlobProperties;
import org.jclouds.blobstore.domain.ListContainerResponse;
import org.jclouds.blobstore.domain.ResourceMetadata;
import org.jclouds.blobstore.domain.StorageMetadata;
import org.jclouds.blobstore.domain.internal.ListContainerResponseImpl;
import com.google.common.base.Function;
@ -38,7 +38,7 @@ import com.google.common.collect.Sets;
*/
@Singleton
public class ListBlobsResponseToResourceList implements
Function<ListBlobsResponse, ListContainerResponse<? extends ResourceMetadata>> {
Function<ListBlobsResponse, ListContainerResponse<? extends StorageMetadata>> {
private final ListableBlobPropertiesToBlobMetadata<ListableBlobProperties> object2blobMd;
private final CommonPrefixesToResourceMetadata prefix2ResourceMd;
@ -50,10 +50,10 @@ public class ListBlobsResponseToResourceList implements
this.prefix2ResourceMd = prefix2ResourceMd;
}
public ListContainerResponse<? extends ResourceMetadata> apply(ListBlobsResponse from) {
SortedSet<ResourceMetadata> contents = Sets.newTreeSet(Iterables.concat(Iterables.transform(
public ListContainerResponse<? extends StorageMetadata> apply(ListBlobsResponse from) {
SortedSet<StorageMetadata> contents = Sets.newTreeSet(Iterables.concat(Iterables.transform(
from, object2blobMd), prefix2ResourceMd.apply(from.getBlobPrefixes())));
return new ListContainerResponseImpl<ResourceMetadata>(contents, from.getPrefix(), from.getMarker(),
return new ListContainerResponseImpl<StorageMetadata>(contents, from.getPrefix(), from.getMarker(),
from.getMaxResults(), from.size() == from.getMaxResults());
}

View File

@ -23,7 +23,7 @@ import javax.inject.Singleton;
import org.jclouds.azure.storage.blob.domain.ListableBlobProperties;
import org.jclouds.blobstore.domain.MutableBlobMetadata;
import org.jclouds.blobstore.domain.ResourceType;
import org.jclouds.blobstore.domain.StorageType;
import org.jclouds.blobstore.domain.internal.MutableBlobMetadataImpl;
import org.jclouds.blobstore.strategy.IsDirectoryStrategy;
@ -50,9 +50,9 @@ public class ListableBlobPropertiesToBlobMetadata<T extends ListableBlobProperti
to.setLastModified(from.getLastModified());
to.setName(from.getName());
to.setSize(from.getSize());
to.setType(ResourceType.BLOB);
to.setType(StorageType.BLOB);
if (isDirectoryStrategy.execute(to)) {
to.setType(ResourceType.RELATIVE_PATH);
to.setType(StorageType.RELATIVE_PATH);
}
return to;
}

View File

@ -29,8 +29,8 @@ import org.jclouds.azure.storage.blob.domain.MutableBlobProperties;
import org.jclouds.azure.storage.blob.domain.internal.TreeSetListBlobsResponse;
import org.jclouds.blobstore.domain.BlobMetadata;
import org.jclouds.blobstore.domain.ListContainerResponse;
import org.jclouds.blobstore.domain.ResourceMetadata;
import org.jclouds.blobstore.domain.ResourceType;
import org.jclouds.blobstore.domain.StorageMetadata;
import org.jclouds.blobstore.domain.StorageType;
import com.google.common.base.Function;
import com.google.common.base.Predicate;
@ -42,7 +42,7 @@ import com.google.common.collect.Sets;
*/
@Singleton
public class ResourceToListBlobsResponse implements
Function<ListContainerResponse<? extends ResourceMetadata>, ListBlobsResponse> {
Function<ListContainerResponse<? extends StorageMetadata>, ListBlobsResponse> {
private final BlobMetadataToBlobProperties blob2ObjectMd;
@Inject
@ -50,33 +50,33 @@ public class ResourceToListBlobsResponse implements
this.blob2ObjectMd = blob2ObjectMd;
}
public ListBlobsResponse apply(ListContainerResponse<? extends ResourceMetadata> list) {
public ListBlobsResponse apply(ListContainerResponse<? extends StorageMetadata> list) {
Iterable<ListableBlobProperties> contents = Iterables.transform(Iterables.filter(list,
new Predicate<ResourceMetadata>() {
new Predicate<StorageMetadata>() {
public boolean apply(ResourceMetadata input) {
return input.getType() == ResourceType.BLOB;
public boolean apply(StorageMetadata input) {
return input.getType() == StorageType.BLOB;
}
}), new Function<ResourceMetadata, ListableBlobProperties>() {
}), new Function<StorageMetadata, ListableBlobProperties>() {
public MutableBlobProperties apply(ResourceMetadata from) {
public MutableBlobProperties apply(StorageMetadata from) {
return blob2ObjectMd.apply((BlobMetadata) from);
}
});
SortedSet<String> commonPrefixes = Sets.newTreeSet(Iterables.transform(Iterables.filter(list,
new Predicate<ResourceMetadata>() {
new Predicate<StorageMetadata>() {
public boolean apply(ResourceMetadata input) {
return input.getType() == ResourceType.RELATIVE_PATH;
public boolean apply(StorageMetadata input) {
return input.getType() == StorageType.RELATIVE_PATH;
}
}), new Function<ResourceMetadata, String>() {
}), new Function<StorageMetadata, String>() {
public String apply(ResourceMetadata from) {
public String apply(StorageMetadata from) {
return from.getName();
}

View File

@ -96,7 +96,7 @@ public class StubAzureBlobAsyncClient implements AzureBlobAsyncClient {
public ListenableFuture<Boolean> createContainer(String container,
CreateContainerOptions... options) {
return blobStore.createContainer(container);
return blobStore.createContainerInLocation("default", container);
}
public ListenableFuture<Boolean> createRootContainer(CreateContainerOptions... options) {
@ -118,8 +118,7 @@ public class StubAzureBlobAsyncClient implements AzureBlobAsyncClient {
public ListenableFuture<AzureBlob> getBlob(String container, String key, GetOptions... options) {
org.jclouds.blobstore.options.GetOptions getOptions = httpGetOptionsConverter.apply(options);
return compose(blobStore.getBlob(container, key, getOptions),
blob2Object);
return compose(blobStore.getBlob(container, key, getOptions), blob2Object);
}
public ListenableFuture<BlobProperties> getBlobProperties(String container, String key) {

View File

@ -22,7 +22,7 @@ import org.jclouds.blobstore.domain.Blob;
import org.jclouds.blobstore.domain.BlobMetadata;
import org.jclouds.blobstore.domain.ListContainerResponse;
import org.jclouds.blobstore.domain.ListResponse;
import org.jclouds.blobstore.domain.ResourceMetadata;
import org.jclouds.blobstore.domain.StorageMetadata;
import org.jclouds.blobstore.options.GetOptions;
import org.jclouds.blobstore.options.ListContainerOptions;
@ -40,7 +40,7 @@ public interface AsyncBlobStore {
/**
* Lists all root-level resources available to the account.
*/
ListenableFuture<? extends ListResponse<? extends ResourceMetadata>> list();
ListenableFuture<? extends ListResponse<? extends StorageMetadata>> list();
/**
* Lists all resources available at the specified path. Note that path may be a container, or a
@ -49,14 +49,14 @@ public interface AsyncBlobStore {
* @param parent
* - base path to list; non-recursive
*/
ListenableFuture<? extends ListContainerResponse<? extends ResourceMetadata>> list(String container,
ListContainerOptions... options);
ListenableFuture<? extends ListContainerResponse<? extends StorageMetadata>> list(
String container, ListContainerOptions... options);
ListenableFuture<Boolean> containerExists(String container);
ListenableFuture<Boolean> directoryExists(String container, String directory);
ListenableFuture<Boolean> createContainer(String container);
ListenableFuture<Boolean> createContainerInLocation(String location, String container);
ListenableFuture<Void> createDirectory(String container, String directory);

View File

@ -22,7 +22,7 @@ import org.jclouds.blobstore.domain.Blob;
import org.jclouds.blobstore.domain.BlobMetadata;
import org.jclouds.blobstore.domain.ListContainerResponse;
import org.jclouds.blobstore.domain.ListResponse;
import org.jclouds.blobstore.domain.ResourceMetadata;
import org.jclouds.blobstore.domain.StorageMetadata;
import org.jclouds.blobstore.options.GetOptions;
import org.jclouds.blobstore.options.ListContainerOptions;
@ -38,7 +38,7 @@ public interface BlobStore {
/**
* Lists all root-level resources available to the account.
*/
ListResponse<? extends ResourceMetadata> list();
ListResponse<? extends StorageMetadata> list();
/**
* Lists all resources available at the specified path. Note that path may be a container, or a
@ -47,14 +47,14 @@ public interface BlobStore {
* @param parent
* - base path to list; non-recursive
*/
ListContainerResponse<? extends ResourceMetadata> list(String container,
ListContainerResponse<? extends StorageMetadata> list(String container,
ListContainerOptions... options);
boolean containerExists(String container);
boolean directoryExists(String container, String directory);
boolean createContainer(String container);
boolean createContainerInLocation(String location, String container);
void createDirectory(String container, String directory);

View File

@ -21,7 +21,7 @@ package org.jclouds.blobstore;
import java.util.Map;
import java.util.SortedSet;
import org.jclouds.blobstore.domain.ResourceMetadata;
import org.jclouds.blobstore.domain.StorageMetadata;
/**
* All Map views of {@link ContainerListing}s provide means to access the underlying Blob.
@ -35,6 +35,6 @@ public interface ListableMap<K, V> extends Map<K, V> {
*
* @return blob listing that this map represents
*/
SortedSet<? extends ResourceMetadata> list();
SortedSet<? extends StorageMetadata> list();
}

View File

@ -28,7 +28,7 @@ import com.google.inject.ImplementedBy;
* @author Adrian Cole
*/
@ImplementedBy(BlobMetadataImpl.class)
public interface BlobMetadata extends ResourceMetadata {
public interface BlobMetadata extends StorageMetadata {
/**
* A standard MIME type describing the format of the contents. If none is provided, the default

View File

@ -28,7 +28,7 @@ import com.google.inject.ImplementedBy;
* @author Adrian Cole
*/
@ImplementedBy(MutableBlobMetadataImpl.class)
public interface MutableBlobMetadata extends BlobMetadata, MutableResourceMetadata {
public interface MutableBlobMetadata extends BlobMetadata, MutableStorageMetadata {
/**
* A standard MIME type describing the format of the contents. If none is provided, the default

View File

@ -1,85 +0,0 @@
/**
*
* 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.
* ====================================================================
*/
package org.jclouds.blobstore.domain;
import java.net.URI;
import java.util.Date;
import java.util.Map;
import org.jclouds.blobstore.domain.internal.MutableResourceMetadataImpl;
import com.google.inject.ImplementedBy;
/**
* Identifies containers, files, etc.
*
* @author Adrian Cole
*/
@ImplementedBy(MutableResourceMetadataImpl.class)
public interface MutableResourceMetadata extends ResourceMetadata {
void setId(String id);
void setLocation(URI url);
/**
* Whether this resource is a container, file, etc.
*/
void setType(ResourceType type);
/**
* Name of this resource. Names are dictated by the user. For files, this may be the filename,
* ex. file.txt
*
*/
void setName(String name);
/**
* The eTag value stored in the Etag header returned by HTTP.
*
* @see org.jclouds.blobstore.attr.ContainerCapability#CONTAINER_ETAG
* @see org.jclouds.blobstore.attr.ContainerCapability#BLOB_ETAG
*/
void setETag(String eTag);
/**
* Size of the resource in bytes
*
* @see org.jclouds.blobstore.attr.ContainerCapability#CONTAINER_SIZE
* @see org.jclouds.blobstore.attr.ContainerCapability#BLOB_SIZE
*/
void setSize(long size);
/**
* Last modification time of the resource
*
* @see org.jclouds.blobstore.attr.ContainerCapability#CONTAINER_LAST_MODIFIED
* @see org.jclouds.blobstore.attr.ContainerCapability#BLOB_LAST_MODIFIED
* @see org.jclouds.blobstore.attr.ContainerCapability#MILLISECOND_PRECISION
*/
void setLastModified(Date lastModified);
/**
* Any key-value pairs associated with the resource.
*
* @see org.jclouds.blobstore.attr.ContainerCapability#CONTAINER_METADATA
* @see org.jclouds.blobstore.attr.ContainerCapability#BLOB_METADATA
*/
void setUserMetadata(Map<String, String> userMetadata);
}

View File

@ -0,0 +1,52 @@
/**
*
* 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.
* ====================================================================
*/
package org.jclouds.blobstore.domain;
import java.util.Date;
import org.jclouds.blobstore.domain.internal.MutableStorageMetadataImpl;
import org.jclouds.domain.MutableResourceMetadata;
import com.google.inject.ImplementedBy;
/**
* Used to construct new resources or modify existing ones.
*
* @author Adrian Cole
*/
@ImplementedBy(MutableStorageMetadataImpl.class)
public interface MutableStorageMetadata extends MutableResourceMetadata<StorageType>,
StorageMetadata {
/**
* @see #getETag
*/
void setETag(String eTag);
/**
* @see #getSize
*/
void setSize(long size);
/**
* @see #getLastModified
*/
void setLastModified(Date lastModified);
}

View File

@ -22,7 +22,8 @@ import java.net.URI;
import java.util.Date;
import java.util.Map;
import org.jclouds.blobstore.domain.internal.ResourceMetadataImpl;
import org.jclouds.blobstore.domain.internal.StorageMetadataImpl;
import org.jclouds.domain.ResourceMetadata;
import com.google.inject.ImplementedBy;
@ -31,13 +32,14 @@ import com.google.inject.ImplementedBy;
*
* @author Adrian Cole
*/
@ImplementedBy(ResourceMetadataImpl.class)
public interface ResourceMetadata extends Comparable<ResourceMetadata> {
@ImplementedBy(StorageMetadataImpl.class)
public interface StorageMetadata extends ResourceMetadata<StorageType> {
/**
* Whether this resource is a container, file, etc.
*/
ResourceType getType();
@Override
StorageType getType();
/**
* Unique identifier of this resource within its enclosing namespace. In some scenarios, this id
@ -46,6 +48,7 @@ public interface ResourceMetadata extends Comparable<ResourceMetadata> {
*
* @see org.jclouds.blobstore.attr.ContainerCapability#CONTAINER_METADATA
*/
@Override
String getId();
/**
@ -53,12 +56,32 @@ public interface ResourceMetadata extends Comparable<ResourceMetadata> {
* ex. file.txt
*
*/
@Override
String getName();
/**
* Physical location of the resource.
*
* ex. us-west-1
*
*/
@Override
String getLocation();
/**
* URI used to access this resource
*/
URI getLocation();
@Override
URI getUri();
/**
* Any key-value pairs associated with the resource.
*
* @see org.jclouds.blobstore.attr.ContainerCapability#CONTAINER_METADATA
* @see org.jclouds.blobstore.attr.ContainerCapability#BLOB_METADATA
*/
@Override
Map<String, String> getUserMetadata();
/**
* The eTag value stored in the Etag header returned by HTTP.
@ -85,12 +108,4 @@ public interface ResourceMetadata extends Comparable<ResourceMetadata> {
*/
Date getLastModified();
/**
* Any key-value pairs associated with the resource.
*
* @see org.jclouds.blobstore.attr.ContainerCapability#CONTAINER_METADATA
* @see org.jclouds.blobstore.attr.ContainerCapability#BLOB_METADATA
*/
Map<String, String> getUserMetadata();
}

View File

@ -18,7 +18,7 @@
*/
package org.jclouds.blobstore.domain;
public enum ResourceType {
public enum StorageType {
CONTAINER, BLOB, FOLDER,
/**

View File

@ -24,7 +24,7 @@ import javax.inject.Inject;
import org.jclouds.blobstore.domain.Blob;
import org.jclouds.blobstore.domain.MutableBlobMetadata;
import org.jclouds.blobstore.domain.ResourceMetadata;
import org.jclouds.blobstore.domain.StorageMetadata;
import org.jclouds.encryption.EncryptionService;
import org.jclouds.http.internal.BasePayloadEnclosingImpl;
@ -32,7 +32,7 @@ import com.google.common.collect.LinkedHashMultimap;
import com.google.common.collect.Multimap;
/**
* Value type for an HTTP Blob service. Blobs are stored in {@link ResourceMetadata containers} and consist
* Value type for an HTTP Blob service. Blobs are stored in {@link StorageMetadata containers} and consist
* of a {@link org.jclouds.blobstore.domain.Value#getContent() value}, a {@link Blob#getKey key and
*
* @link Blob.Metadata#getUserMetadata() metadata}

View File

@ -25,32 +25,42 @@ import java.util.Map;
import org.jclouds.blobstore.domain.Blob;
import org.jclouds.blobstore.domain.BlobMetadata;
import org.jclouds.blobstore.domain.ResourceType;
import org.jclouds.blobstore.domain.StorageType;
import com.google.inject.internal.Nullable;
/**
* System and user Metadata for the {@link Blob}.
*
* @author Adrian Cole
*/
public class BlobMetadataImpl extends ResourceMetadataImpl implements Serializable, BlobMetadata {
public class BlobMetadataImpl extends StorageMetadataImpl implements Serializable, BlobMetadata {
/** The serialVersionUID */
private static final long serialVersionUID = -5932618957134612231L;
private final String contentType;
private final byte[] contentMD5;
public BlobMetadataImpl(String id, String name, URI location, String eTag, Long size,
Date lastModified, Map<String, String> userMetadata, String contentType,
public BlobMetadataImpl(String id, String name, @Nullable String location, URI uri, String eTag,
Long size, Date lastModified, Map<String, String> userMetadata, String contentType,
byte[] contentMD5) {
super(ResourceType.BLOB, id, name, location, eTag, size, lastModified, userMetadata);
super(StorageType.BLOB, id, name, location, uri, eTag, size, lastModified, userMetadata);
this.contentType = contentType;
this.contentMD5 = contentMD5;
}
/**
* {@inheritDoc}
*/
@Override
public String getContentType() {
return contentType;
}
/**
* {@inheritDoc}
*/
@Override
public byte[] getContentMD5() {
if (contentMD5 != null) {
byte[] retval = new byte[contentMD5.length];
@ -61,9 +71,4 @@ public class BlobMetadataImpl extends ResourceMetadataImpl implements Serializab
}
}
public int compareTo(BlobMetadata o) {
if (getName() == null)
return -1;
return (this == o) ? 0 : getName().compareTo(o.getName());
}
}

View File

@ -25,14 +25,14 @@ import javax.ws.rs.core.MediaType;
import org.jclouds.blobstore.domain.Blob;
import org.jclouds.blobstore.domain.BlobMetadata;
import org.jclouds.blobstore.domain.MutableBlobMetadata;
import org.jclouds.blobstore.domain.ResourceType;
import org.jclouds.blobstore.domain.StorageType;
/**
* System and user Metadata for the {@link Blob}.
*
* @author Adrian Cole
*/
public class MutableBlobMetadataImpl extends MutableResourceMetadataImpl implements
public class MutableBlobMetadataImpl extends MutableStorageMetadataImpl implements
MutableBlobMetadata {
/** The serialVersionUID */
private static final long serialVersionUID = -5932618957134612231L;
@ -42,12 +42,12 @@ public class MutableBlobMetadataImpl extends MutableResourceMetadataImpl impleme
public MutableBlobMetadataImpl() {
super();
this.setType(ResourceType.BLOB);
this.setType(StorageType.BLOB);
}
public MutableBlobMetadataImpl(BlobMetadata from) {
super(from);
this.setType(ResourceType.BLOB);
this.setType(StorageType.BLOB);
this.contentType = from.getContentType();
this.contentMD5 = from.getContentMD5();
}

View File

@ -0,0 +1,140 @@
/**
*
* 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.
* ====================================================================
*/
package org.jclouds.blobstore.domain.internal;
import java.io.Serializable;
import java.util.Date;
import org.jclouds.blobstore.domain.MutableStorageMetadata;
import org.jclouds.blobstore.domain.StorageMetadata;
import org.jclouds.blobstore.domain.StorageType;
import org.jclouds.domain.internal.MutableResourceMetadataImpl;
/**
* Used to construct new resources or modify existing ones.
*
* @author Adrian Cole
*/
public class MutableStorageMetadataImpl extends MutableResourceMetadataImpl<StorageType> implements
MutableStorageMetadata, Serializable {
/** The serialVersionUID */
private static final long serialVersionUID = -280558162576368264L;
private String eTag;
private Long size;
private Date lastModified;
public MutableStorageMetadataImpl() {
super();
}
public MutableStorageMetadataImpl(StorageMetadata from) {
super(from);
this.eTag = from.getETag();
this.size = from.getSize();
this.lastModified = from.getLastModified();
}
/**
* {@inheritDoc}
*/
@Override
public String getETag() {
return eTag;
}
/**
* {@inheritDoc}
*/
@Override
public Long getSize() {
return size;
}
/**
* {@inheritDoc}
*/
@Override
public Date getLastModified() {
return lastModified;
}
/**
* {@inheritDoc}
*/
@Override
public void setLastModified(Date lastModified) {
this.lastModified = lastModified;
}
/**
* {@inheritDoc}
*/
@Override
public void setSize(long size) {
this.size = size;
}
/**
* {@inheritDoc}
*/
@Override
public void setETag(String eTag) {
this.eTag = eTag;
}
@Override
public int hashCode() {
final int prime = 31;
int result = super.hashCode();
result = prime * result + ((eTag == null) ? 0 : eTag.hashCode());
result = prime * result + ((lastModified == null) ? 0 : lastModified.hashCode());
result = prime * result + ((size == null) ? 0 : size.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;
MutableStorageMetadataImpl other = (MutableStorageMetadataImpl) obj;
if (eTag == null) {
if (other.eTag != null)
return false;
} else if (!eTag.equals(other.eTag))
return false;
if (lastModified == null) {
if (other.lastModified != null)
return false;
} else if (!lastModified.equals(other.lastModified))
return false;
if (size == null) {
if (other.size != null)
return false;
} else if (!size.equals(other.size))
return false;
return true;
}
}

View File

@ -0,0 +1,71 @@
/**
*
* 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.
* ====================================================================
*/
package org.jclouds.blobstore.domain.internal;
import java.io.Serializable;
import java.net.URI;
import java.util.Date;
import java.util.Map;
import org.jclouds.blobstore.domain.StorageMetadata;
import org.jclouds.blobstore.domain.StorageType;
import org.jclouds.domain.internal.ResourceMetadataImpl;
import com.google.inject.internal.Nullable;
/**
* Idpayload of the object
*
* @author Adrian Cole
*/
public class StorageMetadataImpl extends ResourceMetadataImpl<StorageType> implements
StorageMetadata, Serializable {
/** The serialVersionUID */
private static final long serialVersionUID = -280558162576368264L;
@Nullable
private final String eTag;
@Nullable
private final Long size;
@Nullable
private final Date lastModified;
public StorageMetadataImpl(StorageType type, @Nullable String id, @Nullable String name,
@Nullable String location, @Nullable URI uri, @Nullable String eTag,
@Nullable Long size, @Nullable Date lastModified, Map<String, String> userMetadata) {
super(type, id, name, location, uri, userMetadata);
this.eTag = eTag;
this.size = size;
this.lastModified = lastModified;
}
public String getETag() {
return eTag;
}
public Long getSize() {
return size;
}
public Date getLastModified() {
return lastModified;
}
}

View File

@ -20,25 +20,25 @@ package org.jclouds.blobstore.functions;
import javax.inject.Singleton;
import org.jclouds.blobstore.domain.ResourceMetadata;
import org.jclouds.blobstore.domain.ResourceType;
import org.jclouds.blobstore.domain.internal.ResourceMetadataImpl;
import org.jclouds.blobstore.domain.StorageMetadata;
import org.jclouds.blobstore.domain.StorageType;
import org.jclouds.blobstore.domain.internal.StorageMetadataImpl;
import org.jclouds.blobstore.reference.BlobStoreConstants;
import com.google.common.base.Function;
@Singleton
public class ResourceMetadataToRelativePathResourceMetadata implements
Function<ResourceMetadata, ResourceMetadata> {
Function<StorageMetadata, StorageMetadata> {
public ResourceMetadata apply(ResourceMetadata md) {
public StorageMetadata apply(StorageMetadata md) {
String name = md.getName();
for (String suffix : BlobStoreConstants.DIRECTORY_SUFFIXES) {
if (name.endsWith(suffix))
name = name.substring(0, name.length() - suffix.length());
}
return new ResourceMetadataImpl(ResourceType.RELATIVE_PATH, md.getId(), name, md
.getLocation(), md.getETag(), md.getSize(), md.getLastModified(), md
return new StorageMetadataImpl(StorageType.RELATIVE_PATH, md.getId(), name, md
.getLocation(), md.getUri(), md.getETag(), md.getSize(), md.getLastModified(), md
.getUserMetadata());
}

View File

@ -32,8 +32,8 @@ import org.jclouds.blobstore.domain.Blob;
import org.jclouds.blobstore.domain.BlobMetadata;
import org.jclouds.blobstore.domain.ListResponse;
import org.jclouds.blobstore.domain.MutableBlobMetadata;
import org.jclouds.blobstore.domain.ResourceMetadata;
import org.jclouds.blobstore.domain.ResourceType;
import org.jclouds.blobstore.domain.StorageMetadata;
import org.jclouds.blobstore.domain.StorageType;
import org.jclouds.blobstore.domain.internal.MutableBlobMetadataImpl;
import org.jclouds.blobstore.options.ListContainerOptions;
import org.jclouds.blobstore.reference.BlobStoreConstants;
@ -193,8 +193,8 @@ public abstract class BaseBlobMap<V> {
public Set<String> keySet() {
Set<String> keys = Sets.newHashSet();
for (ResourceMetadata object : getAllBlobMetadata.execute(containerName, options))
if (object.getType() == ResourceType.BLOB)
for (StorageMetadata object : getAllBlobMetadata.execute(containerName, options))
if (object.getType() == StorageType.BLOB)
keys.add(pathStripper.apply(object.getName()));
return keys;
}

View File

@ -19,7 +19,7 @@
package org.jclouds.blobstore.strategy;
import org.jclouds.blobstore.AsyncBlobStore;
import org.jclouds.blobstore.domain.ResourceMetadata;
import org.jclouds.blobstore.domain.StorageMetadata;
import org.jclouds.blobstore.strategy.internal.MarkersGetDirectoryStrategy;
import com.google.inject.ImplementedBy;
@ -32,5 +32,5 @@ import com.google.inject.ImplementedBy;
@ImplementedBy(MarkersGetDirectoryStrategy.class)
public interface GetDirectoryStrategy {
ResourceMetadata execute(AsyncBlobStore connection, String containerName, String directory);
StorageMetadata execute(AsyncBlobStore connection, String containerName, String directory);
}

View File

@ -18,7 +18,7 @@
*/
package org.jclouds.blobstore.strategy;
import org.jclouds.blobstore.domain.ResourceMetadata;
import org.jclouds.blobstore.domain.StorageMetadata;
import org.jclouds.blobstore.strategy.internal.MarkersIsDirectoryStrategy;
import com.google.inject.ImplementedBy;
@ -31,5 +31,5 @@ import com.google.inject.ImplementedBy;
@ImplementedBy(MarkersIsDirectoryStrategy.class)
public interface IsDirectoryStrategy {
boolean execute(ResourceMetadata metadata);
boolean execute(StorageMetadata metadata);
}

View File

@ -25,8 +25,8 @@ import javax.inject.Named;
import javax.inject.Singleton;
import org.jclouds.blobstore.AsyncBlobStore;
import org.jclouds.blobstore.domain.ResourceMetadata;
import org.jclouds.blobstore.domain.ResourceType;
import org.jclouds.blobstore.domain.StorageMetadata;
import org.jclouds.blobstore.domain.StorageType;
import org.jclouds.blobstore.internal.BlobRuntimeException;
import org.jclouds.blobstore.options.ListContainerOptions;
import org.jclouds.blobstore.reference.BlobStoreConstants;
@ -67,8 +67,8 @@ public class DeleteAllKeysInList implements ClearListStrategy, ClearContainerStr
public void execute(final String containerName, ListContainerOptions options) {
Set<ListenableFuture<Void>> deletes = Sets.newHashSet();
for (ResourceMetadata md : getAllBlobMetadata.execute(containerName, options)) {
if (md.getType() == ResourceType.BLOB)
for (StorageMetadata md : getAllBlobMetadata.execute(containerName, options)) {
if (md.getType() == StorageType.BLOB)
deletes.add(connection.removeBlob(containerName, md.getName()));
}
for (ListenableFuture<Void> isdeleted : deletes) {

View File

@ -27,8 +27,8 @@ import javax.inject.Singleton;
import org.jclouds.blobstore.AsyncBlobStore;
import org.jclouds.blobstore.domain.BlobMetadata;
import org.jclouds.blobstore.domain.ListResponse;
import org.jclouds.blobstore.domain.ResourceMetadata;
import org.jclouds.blobstore.domain.ResourceType;
import org.jclouds.blobstore.domain.StorageMetadata;
import org.jclouds.blobstore.domain.StorageType;
import org.jclouds.blobstore.internal.BlobRuntimeException;
import org.jclouds.blobstore.options.ListContainerOptions;
import org.jclouds.blobstore.reference.BlobStoreConstants;
@ -60,11 +60,11 @@ public class ListBlobMetadataInContainer implements ListBlobMetadataStrategy {
public SortedSet<? extends BlobMetadata> execute(String container, ListContainerOptions options) {
try {
ListResponse<? extends ResourceMetadata> resources = connection.list(container, options)
ListResponse<? extends StorageMetadata> resources = connection.list(container, options)
.get(requestTimeoutMilliseconds, TimeUnit.MILLISECONDS);
SortedSet<BlobMetadata> blobM = Sets.newTreeSet();
for (ResourceMetadata from : resources) {
if (from.getType() == ResourceType.BLOB)
for (StorageMetadata from : resources) {
if (from.getType() == StorageType.BLOB)
blobM.add((BlobMetadata) from);
}
return blobM;

View File

@ -25,7 +25,7 @@ import javax.inject.Singleton;
import org.jclouds.blobstore.AsyncBlobStore;
import org.jclouds.blobstore.KeyNotFoundException;
import org.jclouds.blobstore.domain.ResourceMetadata;
import org.jclouds.blobstore.domain.StorageMetadata;
import org.jclouds.blobstore.functions.ResourceMetadataToRelativePathResourceMetadata;
import org.jclouds.blobstore.internal.BlobRuntimeException;
import org.jclouds.blobstore.reference.BlobStoreConstants;
@ -69,7 +69,7 @@ public class MarkersGetDirectoryStrategy implements GetDirectoryStrategy {
this.resource2Directory = resource2Directory;
}
public ResourceMetadata execute(AsyncBlobStore connection, String containerName, String directory) {
public StorageMetadata execute(AsyncBlobStore connection, String containerName, String directory) {
for (String suffix : BlobStoreConstants.DIRECTORY_SUFFIXES) {
try {
return resource2Directory.apply(connection.blobMetadata(containerName,

View File

@ -21,7 +21,7 @@ package org.jclouds.blobstore.strategy.internal;
import javax.inject.Singleton;
import org.jclouds.blobstore.domain.BlobMetadata;
import org.jclouds.blobstore.domain.ResourceMetadata;
import org.jclouds.blobstore.domain.StorageMetadata;
import org.jclouds.blobstore.reference.BlobStoreConstants;
import org.jclouds.blobstore.strategy.IsDirectoryStrategy;
@ -32,7 +32,7 @@ import org.jclouds.blobstore.strategy.IsDirectoryStrategy;
@Singleton
public class MarkersIsDirectoryStrategy implements IsDirectoryStrategy {
public boolean execute(ResourceMetadata metadata) {
public boolean execute(StorageMetadata metadata) {
switch (metadata.getType()) {
case CONTAINER:
case FOLDER:

View File

@ -26,7 +26,7 @@ import java.io.InputStream;
import org.jclouds.blobstore.BlobStore;
import org.jclouds.blobstore.domain.Blob;
import org.jclouds.blobstore.domain.BlobMetadata;
import org.jclouds.blobstore.domain.ResourceMetadata;
import org.jclouds.blobstore.domain.StorageMetadata;
import org.jclouds.util.Utils;
/**
@ -36,7 +36,7 @@ import org.jclouds.util.Utils;
*/
public class BlobStoreUtils {
public static Blob newBlob(BlobStore blobStore, ResourceMetadata blobMeta) {
public static Blob newBlob(BlobStore blobStore, StorageMetadata blobMeta) {
Blob blob = blobStore.newBlob(blobMeta.getName());
if (blobMeta instanceof BlobMetadata) {
blob.getMetadata().setContentMD5(((BlobMetadata) blobMeta).getContentMD5());
@ -46,6 +46,7 @@ public class BlobStoreUtils {
blob.getMetadata().setId(blobMeta.getId());
blob.getMetadata().setLastModified(blobMeta.getLastModified());
blob.getMetadata().setLocation(blobMeta.getLocation());
blob.getMetadata().setUri(blobMeta.getUri());
blob.getMetadata().setUserMetadata(blobMeta.getUserMetadata());
return blob;
}

View File

@ -23,8 +23,8 @@ import static org.testng.Assert.assertEquals;
import javax.inject.Provider;
import org.jclouds.blobstore.domain.MutableBlobMetadata;
import org.jclouds.blobstore.domain.ResourceMetadata;
import org.jclouds.blobstore.domain.ResourceType;
import org.jclouds.blobstore.domain.StorageMetadata;
import org.jclouds.blobstore.domain.StorageType;
import org.jclouds.blobstore.domain.internal.MutableBlobMetadataImpl;
import org.testng.annotations.Test;
@ -45,10 +45,10 @@ public class BlobMetadataToRelativePathResourceMetadataTest {
MutableBlobMetadata md = blobMetadataProvider.get();
md.setName("dir/");
md.setId("dir/");
ResourceMetadata rd = parser.apply(md);
StorageMetadata rd = parser.apply(md);
assertEquals(rd.getName(), "dir");
assertEquals(rd.getId(), "dir/");
assertEquals(rd.getType(), ResourceType.RELATIVE_PATH);
assertEquals(rd.getType(), StorageType.RELATIVE_PATH);
}
@Test
@ -56,10 +56,10 @@ public class BlobMetadataToRelativePathResourceMetadataTest {
MutableBlobMetadata md = blobMetadataProvider.get();
md.setName("dir_$folder$");
md.setId("dir_$folder$");
ResourceMetadata rd = parser.apply(md);
StorageMetadata rd = parser.apply(md);
assertEquals(rd.getName(), "dir");
assertEquals(rd.getId(), "dir_$folder$");
assertEquals(rd.getType(), ResourceType.RELATIVE_PATH);
assertEquals(rd.getType(), StorageType.RELATIVE_PATH);
}
@Test
@ -67,9 +67,9 @@ public class BlobMetadataToRelativePathResourceMetadataTest {
MutableBlobMetadata md = blobMetadataProvider.get();
md.setName("dir");
md.setId("dir");
ResourceMetadata rd = parser.apply(md);
StorageMetadata rd = parser.apply(md);
assertEquals(rd.getName(), "dir");
assertEquals(rd.getId(), "dir");
assertEquals(rd.getType(), ResourceType.RELATIVE_PATH);
assertEquals(rd.getType(), StorageType.RELATIVE_PATH);
}
}

View File

@ -37,7 +37,7 @@ import java.util.SortedSet;
import org.jclouds.blobstore.ContainerNotFoundException;
import org.jclouds.blobstore.domain.Blob;
import org.jclouds.blobstore.domain.BlobMetadata;
import org.jclouds.blobstore.domain.ResourceMetadata;
import org.jclouds.blobstore.domain.StorageMetadata;
import org.jclouds.blobstore.util.BlobStoreUtils;
import org.jclouds.encryption.internal.JCEEncryptionService;
import org.jclouds.http.HttpResponseException;
@ -266,7 +266,7 @@ public class BaseBlobIntegrationTest<A, S> extends BaseBlobStoreIntegrationTest<
}
private void assertContainerEmptyDeleting(String containerName, String key) {
SortedSet<? extends ResourceMetadata> listing = context.getBlobStore().list(containerName);
SortedSet<? extends StorageMetadata> listing = context.getBlobStore().list(containerName);
assertEquals(listing.size(), 0, String.format(
"deleting %s, we still have %s left in container %s, using encoding %s", key,
listing.size(), containerName, LOCAL_ENCODING));

View File

@ -37,8 +37,8 @@ import java.util.concurrent.atomic.AtomicInteger;
import org.jclouds.blobstore.BlobStoreContext;
import org.jclouds.blobstore.attr.ConsistencyModels;
import org.jclouds.blobstore.domain.Blob;
import org.jclouds.blobstore.domain.ResourceMetadata;
import org.jclouds.blobstore.domain.ResourceType;
import org.jclouds.blobstore.domain.StorageMetadata;
import org.jclouds.blobstore.domain.StorageType;
import org.jclouds.blobstore.util.BlobStoreUtils;
import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule;
import org.testng.ITestContext;
@ -176,16 +176,16 @@ public class BaseBlobStoreIntegrationTest<A, S> {
protected static void deleteEverything(final BlobStoreContext<?, ?> context) throws Exception {
try {
for (int i = 0; i < 2; i++) {
Iterable<? extends ResourceMetadata> testContainers = Iterables.filter(context
.getBlobStore().list(), new Predicate<ResourceMetadata>() {
public boolean apply(ResourceMetadata input) {
return (input.getType() == ResourceType.CONTAINER || input.getType() == ResourceType.FOLDER)
Iterable<? extends StorageMetadata> testContainers = Iterables.filter(context
.getBlobStore().list(), new Predicate<StorageMetadata>() {
public boolean apply(StorageMetadata input) {
return (input.getType() == StorageType.CONTAINER || input.getType() == StorageType.FOLDER)
&& input.getName().startsWith(CONTAINER_PREFIX.toLowerCase());
}
});
if (testContainers.iterator().hasNext()) {
ExecutorService executor = Executors.newCachedThreadPool();
for (final ResourceMetadata metaDatum : testContainers) {
for (final StorageMetadata metaDatum : testContainers) {
executor.execute(new Runnable() {
public void run() {
deleteContainerOrWarnIfUnable(context, metaDatum.getName());
@ -239,7 +239,7 @@ public class BaseBlobStoreIntegrationTest<A, S> {
protected static void createContainerAndEnsureEmpty(BlobStoreContext<?, ?> context,
final String containerName) throws InterruptedException {
context.getBlobStore().createContainer(containerName);
context.getBlobStore().createContainerInLocation("default", containerName);
if (context.getConsistencyModel() == ConsistencyModels.EVENTUAL)
Thread.sleep(1000);
context.getBlobStore().clearContainer(containerName);
@ -287,13 +287,13 @@ public class BaseBlobStoreIntegrationTest<A, S> {
assertConsistencyAware(new Runnable() {
public void run() {
try {
SortedSet<? extends ResourceMetadata> list = context.getBlobStore().list(
SortedSet<? extends StorageMetadata> list = context.getBlobStore().list(
containerName);
assert list.size() == count : String.format("expected only %d values in %s: %s",
count, containerName, Sets.newHashSet(Iterables.transform(list,
new Function<ResourceMetadata, String>() {
new Function<StorageMetadata, String>() {
public String apply(ResourceMetadata from) {
public String apply(StorageMetadata from) {
return from.getName();
}
@ -335,8 +335,8 @@ public class BaseBlobStoreIntegrationTest<A, S> {
* *substantially* slow down tests on a real server over a network.
*/
if (SANITY_CHECK_RETURNED_BUCKET_NAME) {
if (!Iterables.any(context.getBlobStore().list(), new Predicate<ResourceMetadata>() {
public boolean apply(ResourceMetadata md) {
if (!Iterables.any(context.getBlobStore().list(), new Predicate<StorageMetadata>() {
public boolean apply(StorageMetadata md) {
return containerName.equals(md.getName());
}
})) {

View File

@ -31,7 +31,7 @@ import java.util.concurrent.TimeoutException;
import org.jclouds.blobstore.domain.Blob;
import org.jclouds.blobstore.domain.ListContainerResponse;
import org.jclouds.blobstore.domain.ListResponse;
import org.jclouds.blobstore.domain.ResourceMetadata;
import org.jclouds.blobstore.domain.StorageMetadata;
import org.testng.annotations.Test;
import com.google.common.base.Throwables;
@ -44,15 +44,16 @@ public class BaseContainerIntegrationTest<A, S> extends BaseBlobStoreIntegration
@Test(groups = { "integration", "live" })
public void containerDoesntExist() {
assert !context.getBlobStore().containerExists("forgetaboutit");
assert !context.getBlobStore().containerExists("bog.cloudcachestorefunctionalintegrationtest-first");
assert !context.getBlobStore().containerExists(
"bog.cloudcachestorefunctionalintegrationtest-first");
}
@Test(groups = { "integration", "live" })
public void testPutTwiceIsOk() throws InterruptedException {
String containerName = getContainerName();
try {
context.getBlobStore().createContainer(containerName);
context.getBlobStore().createContainer(containerName);
context.getBlobStore().createContainerInLocation("default", containerName);
context.getBlobStore().createContainerInLocation("default", containerName);
} finally {
returnContainer(containerName);
}
@ -74,7 +75,7 @@ public class BaseContainerIntegrationTest<A, S> extends BaseBlobStoreIntegration
String containerName = getContainerName();
try {
addAlphabetUnderRoot(containerName);
ListResponse<? extends ResourceMetadata> container = context.getBlobStore().list(
ListResponse<? extends StorageMetadata> container = context.getBlobStore().list(
containerName, afterMarker("y"));
assertEquals(container.getMarker(), "y");
assert !container.isTruncated();
@ -91,7 +92,7 @@ public class BaseContainerIntegrationTest<A, S> extends BaseBlobStoreIntegration
String prefix = "apps";
addTenObjectsUnderPrefix(containerName, prefix);
add15UnderRoot(containerName);
ListResponse<? extends ResourceMetadata> container = context.getBlobStore().list(
ListResponse<? extends StorageMetadata> container = context.getBlobStore().list(
containerName);
assert !container.isTruncated();
assertEquals(container.size(), 16);
@ -108,7 +109,7 @@ public class BaseContainerIntegrationTest<A, S> extends BaseBlobStoreIntegration
addTenObjectsUnderPrefix(containerName, prefix);
add15UnderRoot(containerName);
ListContainerResponse<? extends ResourceMetadata> container = context.getBlobStore().list(
ListContainerResponse<? extends StorageMetadata> container = context.getBlobStore().list(
containerName, inDirectory("apps/"));
assert !container.isTruncated();
assertEquals(container.size(), 10);
@ -124,7 +125,7 @@ public class BaseContainerIntegrationTest<A, S> extends BaseBlobStoreIntegration
String containerName = getContainerName();
try {
addAlphabetUnderRoot(containerName);
ListResponse<? extends ResourceMetadata> container = context.getBlobStore().list(
ListResponse<? extends StorageMetadata> container = context.getBlobStore().list(
containerName, maxResults(5));
assertEquals(container.getMaxResults(), 5);
assert container.isTruncated();
@ -172,8 +173,8 @@ public class BaseContainerIntegrationTest<A, S> extends BaseBlobStoreIntegration
assertConsistencyAware(new Runnable() {
public void run() {
try {
assert !context.getBlobStore().containerExists(containerName) : "container " + containerName
+ " still exists";
assert !context.getBlobStore().containerExists(containerName) : "container "
+ containerName + " still exists";
} catch (Exception e) {
Throwables.propagateIfPossible(e);
}
@ -187,8 +188,8 @@ public class BaseContainerIntegrationTest<A, S> extends BaseBlobStoreIntegration
String containerName = getContainerName();
try {
add15UnderRoot(containerName);
SortedSet<? extends ResourceMetadata> container = context.getBlobStore().list(
containerName);
SortedSet<? extends StorageMetadata> container = context.getBlobStore()
.list(containerName);
assertEquals(container.size(), 15);
} finally {
returnContainer(containerName);

View File

@ -20,8 +20,8 @@ package org.jclouds.blobstore.integration.internal;
import java.util.SortedSet;
import org.jclouds.blobstore.domain.ResourceMetadata;
import org.jclouds.blobstore.domain.internal.MutableResourceMetadataImpl;
import org.jclouds.blobstore.domain.StorageMetadata;
import org.jclouds.blobstore.domain.internal.MutableStorageMetadataImpl;
import org.testng.annotations.Test;
/**
@ -32,8 +32,8 @@ public class BaseServiceIntegrationTest<A, S> extends BaseBlobStoreIntegrationTe
@Test(groups = { "integration", "live" })
void containerDoesntExist() {
SortedSet<? extends ResourceMetadata> list = context.getBlobStore().list();
assert !list.contains(new MutableResourceMetadataImpl());
SortedSet<? extends StorageMetadata> list = context.getBlobStore().list();
assert !list.contains(new MutableStorageMetadataImpl());
}
}

View File

@ -20,7 +20,8 @@ package org.jclouds.blobstore.integration.internal;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.util.concurrent.Futures.immediateFailedFuture;
import static com.google.common.util.concurrent.Futures.*;
import static com.google.common.util.concurrent.Futures.immediateFuture;
import static com.google.common.util.concurrent.Futures.makeListenable;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
@ -58,12 +59,12 @@ import org.jclouds.blobstore.domain.BlobMetadata;
import org.jclouds.blobstore.domain.ListContainerResponse;
import org.jclouds.blobstore.domain.ListResponse;
import org.jclouds.blobstore.domain.MutableBlobMetadata;
import org.jclouds.blobstore.domain.MutableResourceMetadata;
import org.jclouds.blobstore.domain.ResourceMetadata;
import org.jclouds.blobstore.domain.ResourceType;
import org.jclouds.blobstore.domain.MutableStorageMetadata;
import org.jclouds.blobstore.domain.StorageMetadata;
import org.jclouds.blobstore.domain.StorageType;
import org.jclouds.blobstore.domain.internal.ListContainerResponseImpl;
import org.jclouds.blobstore.domain.internal.ListResponseImpl;
import org.jclouds.blobstore.domain.internal.MutableResourceMetadataImpl;
import org.jclouds.blobstore.domain.internal.MutableStorageMetadataImpl;
import org.jclouds.blobstore.functions.HttpGetOptionsListToGetOptions;
import org.jclouds.blobstore.options.GetOptions;
import org.jclouds.blobstore.options.ListContainerOptions;
@ -164,7 +165,7 @@ public class StubAsyncBlobStore implements AsyncBlobStore {
return immediateFuture(returnVal);
}
public ListenableFuture<? extends ListContainerResponse<? extends ResourceMetadata>> list(
public ListenableFuture<? extends ListContainerResponse<? extends StorageMetadata>> list(
final String name, ListContainerOptions... optionsList) {
final ListContainerOptions options = (optionsList.length == 0) ? new ListContainerOptions()
: optionsList[0];
@ -174,21 +175,21 @@ public class StubAsyncBlobStore implements AsyncBlobStore {
if (realContents == null)
return immediateFailedFuture(new ContainerNotFoundException(name));
SortedSet<ResourceMetadata> contents = Sets.newTreeSet(Iterables.transform(realContents
.keySet(), new Function<String, ResourceMetadata>() {
public ResourceMetadata apply(String key) {
SortedSet<StorageMetadata> contents = Sets.newTreeSet(Iterables.transform(realContents
.keySet(), new Function<String, StorageMetadata>() {
public StorageMetadata apply(String key) {
MutableBlobMetadata md = copy(realContents.get(key).getMetadata());
if (isDirectoryStrategy.execute(md))
md.setType(ResourceType.RELATIVE_PATH);
md.setType(StorageType.RELATIVE_PATH);
return md;
}
}));
if (options.getMarker() != null) {
final String finalMarker = options.getMarker();
ResourceMetadata lastMarkerMetadata = Iterables.find(contents,
new Predicate<ResourceMetadata>() {
public boolean apply(ResourceMetadata metadata) {
StorageMetadata lastMarkerMetadata = Iterables.find(contents,
new Predicate<StorageMetadata>() {
public boolean apply(StorageMetadata metadata) {
return metadata.getName().equals(finalMarker);
}
});
@ -198,8 +199,8 @@ public class StubAsyncBlobStore implements AsyncBlobStore {
final String prefix = options.getDir();
if (prefix != null) {
contents = Sets.newTreeSet(Iterables.filter(contents, new Predicate<ResourceMetadata>() {
public boolean apply(ResourceMetadata o) {
contents = Sets.newTreeSet(Iterables.filter(contents, new Predicate<StorageMetadata>() {
public boolean apply(StorageMetadata o) {
return (o != null && o.getName().startsWith(prefix));
}
}));
@ -209,7 +210,7 @@ public class StubAsyncBlobStore implements AsyncBlobStore {
boolean truncated = false;
String marker = null;
if (options.getMaxResults() != null && contents.size() > 0) {
SortedSet<ResourceMetadata> contentsSlice = firstSliceOfSize(contents, options
SortedSet<StorageMetadata> contentsSlice = firstSliceOfSize(contents, options
.getMaxResults().intValue());
maxResults = options.getMaxResults();
if (!contentsSlice.contains(contents.last())) {
@ -233,17 +234,17 @@ public class StubAsyncBlobStore implements AsyncBlobStore {
contents = Sets.newTreeSet(Iterables.filter(contents, new DelimiterFilter(
prefix != null ? prefix : null, delimiter)));
Iterables.<ResourceMetadata> addAll(contents, Iterables.transform(commonPrefixes,
new Function<String, ResourceMetadata>() {
public ResourceMetadata apply(String o) {
MutableResourceMetadata md = new MutableResourceMetadataImpl();
md.setType(ResourceType.RELATIVE_PATH);
Iterables.<StorageMetadata> addAll(contents, Iterables.transform(commonPrefixes,
new Function<String, StorageMetadata>() {
public StorageMetadata apply(String o) {
MutableStorageMetadata md = new MutableStorageMetadataImpl();
md.setType(StorageType.RELATIVE_PATH);
md.setName(o);
return md;
}
}));
}
return immediateFuture(new ListContainerResponseImpl<ResourceMetadata>(contents, prefix,
return immediateFuture(new ListContainerResponseImpl<StorageMetadata>(contents, prefix,
marker, maxResults, truncated));
}
@ -315,24 +316,25 @@ public class StubAsyncBlobStore implements AsyncBlobStore {
return immediateFuture(getContainerToBlobs().containsKey(container));
}
public ListenableFuture<? extends ListResponse<? extends ResourceMetadata>> list() {
return immediateFuture(new ListResponseImpl<ResourceMetadata>(Iterables.transform(
getContainerToBlobs().keySet(), new Function<String, ResourceMetadata>() {
public ResourceMetadata apply(String name) {
MutableResourceMetadata cmd = create();
public ListenableFuture<? extends ListResponse<? extends StorageMetadata>> list() {
return immediateFuture(new ListResponseImpl<StorageMetadata>(Iterables.transform(
getContainerToBlobs().keySet(), new Function<String, StorageMetadata>() {
public StorageMetadata apply(String name) {
MutableStorageMetadata cmd = create();
cmd.setName(name);
cmd.setType(ResourceType.CONTAINER);
cmd.setType(StorageType.CONTAINER);
return cmd;
}
}), null, null, false));
}
protected MutableResourceMetadata create() {
return new MutableResourceMetadataImpl();
protected MutableStorageMetadata create() {
return new MutableStorageMetadataImpl();
}
public ListenableFuture<Boolean> createContainer(final String name) {
public ListenableFuture<Boolean> createContainerInLocation(final String location,
final String name) {
if (!getContainerToBlobs().containsKey(name)) {
getContainerToBlobs().put(name, new ConcurrentHashMap<String, Blob>());
}
@ -346,7 +348,7 @@ public class StubAsyncBlobStore implements AsyncBlobStore {
return (values != null && values.size() >= 1) ? values.iterator().next() : null;
}
protected class DelimiterFilter implements Predicate<ResourceMetadata> {
protected class DelimiterFilter implements Predicate<StorageMetadata> {
private final String prefix;
private final String delimiter;
@ -355,7 +357,7 @@ public class StubAsyncBlobStore implements AsyncBlobStore {
this.delimiter = delimiter;
}
public boolean apply(ResourceMetadata metadata) {
public boolean apply(StorageMetadata metadata) {
if (prefix == null)
return metadata.getName().indexOf(delimiter) == -1;
if (metadata.getName().startsWith(prefix))
@ -364,7 +366,7 @@ public class StubAsyncBlobStore implements AsyncBlobStore {
}
}
protected class CommonPrefixes implements Function<ResourceMetadata, String> {
protected class CommonPrefixes implements Function<StorageMetadata, String> {
private final String prefix;
private final String delimiter;
public static final String NO_PREFIX = "NO_PREFIX";
@ -374,7 +376,7 @@ public class StubAsyncBlobStore implements AsyncBlobStore {
this.delimiter = delimiter;
}
public String apply(ResourceMetadata metadata) {
public String apply(StorageMetadata metadata) {
String working = metadata.getName();
if (prefix != null) {

View File

@ -67,7 +67,8 @@ public class RetryOnNotFoundGetAllBlobsStrategyTest {
Injector context = new StubBlobStoreContextBuilder().buildInjector();
GetAllBlobsInListAndRetryOnFailure map = context
.getInstance(GetAllBlobsInListAndRetryOnFailure.class);
context.getInstance(AsyncBlobStore.class).createContainer("container").get();
context.getInstance(AsyncBlobStore.class).createContainerInLocation("default", "container")
.get();
ListenableFuture<Blob> futureObject = createMock(ListenableFuture.class);
Blob object = blobProvider.create(null);
@ -93,7 +94,8 @@ public class RetryOnNotFoundGetAllBlobsStrategyTest {
Injector context = new StubBlobStoreContextBuilder().buildInjector();
GetAllBlobsInListAndRetryOnFailure map = context
.getInstance(GetAllBlobsInListAndRetryOnFailure.class);
context.getInstance(AsyncBlobStore.class).createContainer("container").get();
context.getInstance(AsyncBlobStore.class).createContainerInLocation("default", "container")
.get();
ListenableFuture<Blob> futureObject = createMock(ListenableFuture.class);
Blob object = createMock(Blob.class);

View File

@ -18,44 +18,49 @@
*/
package org.jclouds.compute;
import java.util.Map;
import java.util.Set;
import org.jclouds.compute.domain.ComputeMetadata;
import org.jclouds.compute.domain.CreateNodeResponse;
import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.NodeIdentity;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.Profile;
import org.jclouds.compute.domain.Size;
/**
* Provides portable access to launching compute instances.
*
* @author Ivan Meredith
* @author Adrian Cole
* @author Ivan Meredith
*/
public interface ComputeService {
/**
* List all sizes available to the current user
*/
Map<String, Size> getSizes();
/**
* List all nodes available to the current user
*/
Set<NodeIdentity> listNodes();
Set<ComputeMetadata> listNodes();
/**
* Find all nodes matching the specified name
*/
Set<NodeIdentity> getNodeByName(String name);
/**
* Create a new node given the name, profile, and Image
* Create a new node given the name, size, and Image
*
*/
CreateNodeResponse createNode(String name, Profile profile, Image image);
CreateNodeResponse startNodeInLocation(String location, String name, Profile size, Image image);
/**
* destroy the node.
*/
void destroyNode(String id);
void destroyNode(ComputeMetadata node);
/**
* Find a node by its id
*/
NodeMetadata getNodeMetadata(String id);
NodeMetadata getNodeMetadata(ComputeMetadata node);
}

View File

@ -18,7 +18,8 @@
*/
package org.jclouds.compute.domain;
import org.jclouds.compute.domain.internal.NodeIdentityImpl;
import org.jclouds.compute.domain.internal.ComputeMetadataImpl;
import org.jclouds.domain.ResourceMetadata;
import com.google.inject.ImplementedBy;
@ -26,19 +27,34 @@ import com.google.inject.ImplementedBy;
* @author Ivan Meredith
* @author Adrian Cole
*/
@ImplementedBy(NodeIdentityImpl.class)
public interface NodeIdentity extends Comparable<NodeIdentity> {
@ImplementedBy(ComputeMetadataImpl.class)
public interface ComputeMetadata extends ResourceMetadata<ComputeType> {
/**
* Type of the resource, ex node, image, size
*
*/
@Override
public ComputeType getType();
/**
* unique id of the server. potentially generated by the service.
*
*/
@Override
public String getId();
/**
* user defined name of the server.
*
*/
@Override
public String getName();
/**
* location where the node exists..
*
*/
@Override
public String getLocation();
}

View File

@ -0,0 +1,29 @@
/**
*
* 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.
* ====================================================================
*/
package org.jclouds.compute.domain;
/**
*
* @author Adrian Cole
*/
public enum ComputeType {
NODE, IMAGE, SIZE;
}

View File

@ -26,7 +26,7 @@ import java.util.SortedSet;
* @author Adrian Cole
* @author Ivan Meredith
*/
public interface NodeMetadata extends NodeIdentity {
public interface NodeMetadata extends ComputeMetadata {
NodeState getState();
SortedSet<InetAddress> getPublicAddresses();

View File

@ -27,7 +27,7 @@ import java.util.Map;
*/
public interface Size {
/**
* Unique ID provided by the provider (m1.small, etc)
* provider-specific identifier (m1.small, etc)
*
*/
String getId();

View File

@ -0,0 +1,43 @@
/**
*
* 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.
* ====================================================================
*/
package org.jclouds.compute.domain.internal;
import java.net.URI;
import java.util.Map;
import org.jclouds.compute.domain.ComputeMetadata;
import org.jclouds.compute.domain.ComputeType;
import org.jclouds.domain.internal.ResourceMetadataImpl;
/**
* @author Adrian Cole
* @author Ivan Meredith
*/
public class ComputeMetadataImpl extends ResourceMetadataImpl<ComputeType> implements
ComputeMetadata {
/** The serialVersionUID */
private static final long serialVersionUID = 7374704415964898694L;
public ComputeMetadataImpl(ComputeType type, String id, String name, String location, URI uri,
Map<String, String> userMetadata) {
super(type, id, name, location, uri, userMetadata);
}
}

View File

@ -19,6 +19,7 @@
package org.jclouds.compute.domain.internal;
import java.net.InetAddress;
import java.net.URI;
import java.util.Map;
import org.jclouds.compute.domain.CreateNodeResponse;
@ -32,12 +33,17 @@ import org.jclouds.domain.Credentials;
*/
public class CreateNodeResponseImpl extends NodeMetadataImpl implements CreateNodeResponse {
/** The serialVersionUID */
private static final long serialVersionUID = 3414239861247046054L;
private final Credentials credentials;
public CreateNodeResponseImpl(String id, String name, NodeState state,
public CreateNodeResponseImpl(String id, String name, String location, URI uri,
Map<String, String> userMetadata, NodeState state,
Iterable<InetAddress> publicAddresses, Iterable<InetAddress> privateAddresses,
int loginPort, LoginType loginType, Credentials credentials, Map<String, String> extra) {
super(id, name, state, publicAddresses, privateAddresses, loginPort, loginType, extra);
super(id, name, location, uri, userMetadata, state, publicAddresses, privateAddresses,
loginPort, loginType, extra);
this.credentials = credentials;
}

View File

@ -1,96 +0,0 @@
/**
*
* 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.
* ====================================================================
*/
package org.jclouds.compute.domain.internal;
import org.jclouds.compute.domain.NodeIdentity;
/**
* @author Adrian Cole
* @author Ivan Meredith
*/
public class NodeIdentityImpl implements NodeIdentity {
private final String id;
private final String name;
public NodeIdentityImpl(String id, String name) {
this.id = id;
this.name = name;
}
/**
* {@inheritDoc}
*/
public String getId() {
return id;
}
/**
* {@inheritDoc}
*/
public String getName() {
return name;
}
/**
* {@inheritDoc}
*/
public int compareTo(NodeIdentity o) {
if (getName() == null)
return -1;
return (this == o) ? 0 : getName().compareTo(o.getName());
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((id == null) ? 0 : id.hashCode());
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
NodeIdentityImpl other = (NodeIdentityImpl) obj;
if (id == null) {
if (other.id != null)
return false;
} else if (!id.equals(other.id))
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
@Override
public String toString() {
return "[id=" + id + ", name=" + name + "]";
}
}

View File

@ -19,10 +19,12 @@
package org.jclouds.compute.domain.internal;
import java.net.InetAddress;
import java.net.URI;
import java.util.Comparator;
import java.util.Map;
import java.util.SortedSet;
import org.jclouds.compute.domain.ComputeType;
import org.jclouds.compute.domain.LoginType;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.NodeState;
@ -35,7 +37,10 @@ import com.google.common.collect.Sets;
* @author Adrian Cole
* @author Ivan Meredith
*/
public class NodeMetadataImpl extends NodeIdentityImpl implements NodeMetadata {
public class NodeMetadataImpl extends ComputeMetadataImpl implements NodeMetadata {
/** The serialVersionUID */
private static final long serialVersionUID = 7924307572338157887L;
public static final Comparator<InetAddress> ADDRESS_COMPARATOR = new Comparator<InetAddress>() {
@Override
@ -51,17 +56,11 @@ public class NodeMetadataImpl extends NodeIdentityImpl implements NodeMetadata {
private final int loginPort;
private final LoginType loginType;
@Override
public String toString() {
return "[id=" + getId() + ", name=" + getName() + ", state=" + getState()
+ ", privateAddresses=" + privateAddresses + ", publicAddresses=" + publicAddresses
+ "]";
}
public NodeMetadataImpl(String id, String name, NodeState state,
public NodeMetadataImpl(String id, String name, String location, URI uri,
Map<String, String> userMetadata, NodeState state,
Iterable<InetAddress> publicAddresses, Iterable<InetAddress> privateAddresses,
int loginPort, LoginType loginType, Map<String, String> extra) {
super(id, name);
super(ComputeType.NODE, id, name, location, uri, userMetadata);
this.state = state;
Iterables.addAll(this.publicAddresses, publicAddresses);
Iterables.addAll(this.privateAddresses, privateAddresses);
@ -113,6 +112,14 @@ public class NodeMetadataImpl extends NodeIdentityImpl implements NodeMetadata {
return extra;
}
@Override
public String toString() {
return "[id=" + getId() + ", name=" + getName() + ", location=" + getLocation() + ", uri="
+ getUri() + ", userMetadata=" + getUserMetadata() + ", state=" + getState()
+ ", privateAddresses=" + privateAddresses + ", publicAddresses=" + publicAddresses
+ "]";
}
@Override
public int hashCode() {
final int prime = 31;

View File

@ -0,0 +1,41 @@
/**
*
* 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.
* ====================================================================
*/
package org.jclouds.compute.util;
import org.jclouds.compute.domain.ComputeMetadata;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
/**
*
* @author Adrian Cole
*/
public class ComputeUtils {
public static Iterable<ComputeMetadata> filterByName(Iterable<ComputeMetadata> nodes,
final String name) {
return Iterables.filter(nodes, new Predicate<ComputeMetadata>() {
@Override
public boolean apply(ComputeMetadata input) {
return input.getName().equalsIgnoreCase(name);
}
});
}
}

View File

@ -0,0 +1,48 @@
package org.jclouds.domain;
import java.net.URI;
import java.util.Map;
import org.jclouds.domain.internal.MutableResourceMetadataImpl;
import com.google.inject.ImplementedBy;
/**
* Used to construct new resources or modify existing ones.
*
* @author Adrian Cole
*/
@ImplementedBy(MutableResourceMetadataImpl.class)
public interface MutableResourceMetadata<T extends Enum<T>> extends ResourceMetadata<T> {
/**
* @see #getType
*/
void setType(T type);
/**
* @see #getId
*/
void setId(String id);
/**
* @see #getName
*/
void setName(String name);
/**
* @see #getLocation
*/
void setLocation(String location);
/**
* @see #getUri
*/
void setUri(URI url);
/**
* @see #getUserMetadata
*/
void setUserMetadata(Map<String, String> userMetadata);
}

View File

@ -0,0 +1,72 @@
/**
*
* 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.
* ====================================================================
*/
package org.jclouds.domain;
import java.net.URI;
import java.util.Map;
import com.google.inject.ImplementedBy;
/**
* Identifies containers, files, etc.
*
* @author Adrian Cole
*/
@ImplementedBy(ResourceMetadata.class)
public interface ResourceMetadata<T extends Enum<T>> extends Comparable<ResourceMetadata<T>> {
/**
* Whether this resource is a container, file, node, queue, etc.
*/
T getType();
/**
* Unique identifier of this resource within its enclosing namespace. In some scenarios, this id
* is not user assignable. For files, this may be an system generated key, or the full path to
* the resource. ex. /path/to/file.txt
*
*/
String getId();
/**
* Name of this resource. Names are dictated by the user. For files, this may be the filename,
* ex. file.txt
*
*/
String getName();
/**
* Physical location of the resource.
*
* ex. us-west-1
*
*/
String getLocation();
/**
* URI used to access this resource
*/
URI getUri();
/**
* Any key-value pairs associated with the resource.
*/
Map<String, String> getUserMetadata();
}

View File

@ -16,33 +16,34 @@
* limitations under the License.
* ====================================================================
*/
package org.jclouds.blobstore.domain.internal;
package org.jclouds.domain.internal;
import java.io.Serializable;
import java.net.URI;
import java.util.Date;
import java.util.Map;
import org.jclouds.blobstore.domain.MutableResourceMetadata;
import org.jclouds.blobstore.domain.ResourceMetadata;
import org.jclouds.blobstore.domain.ResourceType;
import org.jclouds.domain.MutableResourceMetadata;
import org.jclouds.domain.ResourceMetadata;
import com.google.common.collect.Maps;
/**
* Idpayload of the object
* Used to construct new resources or modify existing ones.
*
* @author Adrian Cole
*/
public class MutableResourceMetadataImpl implements MutableResourceMetadata, Serializable {
public class MutableResourceMetadataImpl<T extends Enum<T>> implements MutableResourceMetadata<T>,
Serializable {
/** The serialVersionUID */
private static final long serialVersionUID = -280558162576368264L;
private ResourceType type;
private T type;
private String id;
private String name;
private URI location;
private String location;
private URI uri;
private String eTag;
private Long size;
private Date lastModified;
@ -52,53 +53,125 @@ public class MutableResourceMetadataImpl implements MutableResourceMetadata, Ser
userMetadata = Maps.newHashMap();
}
public MutableResourceMetadataImpl(ResourceMetadata from) {
public MutableResourceMetadataImpl(ResourceMetadata<T> from) {
this.type = from.getType();
this.id = from.getId();
this.name = from.getName();
this.location = from.getLocation();
this.eTag = from.getETag();
this.size = from.getSize();
this.lastModified = from.getLastModified();
this.uri = from.getUri();
this.userMetadata = from.getUserMetadata();
}
public int compareTo(ResourceMetadata o) {
/**
* {@inheritDoc}
*/
@Override
public int compareTo(ResourceMetadata<T> o) {
if (getName() == null)
return -1;
return (this == o) ? 0 : getName().compareTo(o.getName());
}
public ResourceType getType() {
/**
* {@inheritDoc}
*/
@Override
public T getType() {
return type;
}
/**
* {@inheritDoc}
*/
@Override
public String getName() {
return name;
}
/**
* {@inheritDoc}
*/
@Override
public String getId() {
return id;
}
public URI getLocation() {
/**
* {@inheritDoc}
*/
@Override
public URI getUri() {
return uri;
}
/**
* {@inheritDoc}
*/
@Override
public Map<String, String> getUserMetadata() {
return userMetadata;
}
/**
* {@inheritDoc}
*/
@Override
public void setName(String name) {
this.name = name;
}
/**
* {@inheritDoc}
*/
@Override
public void setType(T type) {
this.type = type;
}
/**
* {@inheritDoc}
*/
@Override
public void setUserMetadata(Map<String, String> userMetadata) {
this.userMetadata = userMetadata;
}
/**
* {@inheritDoc}
*/
@Override
public void setId(String id) {
this.id = id;
}
/**
* {@inheritDoc}
*/
@Override
public void setUri(URI uri) {
this.uri = uri;
}
/**
* {@inheritDoc}
*/
@Override
public void setLocation(String location) {
this.location = location;
}
/**
* {@inheritDoc}
*/
@Override
public String getLocation() {
return location;
}
public String getETag() {
return eTag;
}
public Long getSize() {
return size;
}
public Date getLastModified() {
return lastModified;
}
public Map<String, String> getUserMetadata() {
return userMetadata;
@Override
public String toString() {
return "[type=" + type + ", id=" + id + ", name=" + name + ", location=" + location
+ ", uri=" + uri + ", userMetadata=" + userMetadata + "]";
}
@Override
@ -112,6 +185,7 @@ public class MutableResourceMetadataImpl implements MutableResourceMetadata, Ser
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + ((size == null) ? 0 : size.hashCode());
result = prime * result + ((type == null) ? 0 : type.hashCode());
result = prime * result + ((uri == null) ? 0 : uri.hashCode());
result = prime * result + ((userMetadata == null) ? 0 : userMetadata.hashCode());
return result;
}
@ -124,7 +198,7 @@ public class MutableResourceMetadataImpl implements MutableResourceMetadata, Ser
return false;
if (getClass() != obj.getClass())
return false;
MutableResourceMetadataImpl other = (MutableResourceMetadataImpl) obj;
MutableResourceMetadataImpl<?> other = (MutableResourceMetadataImpl<?>) obj;
if (eTag == null) {
if (other.eTag != null)
return false;
@ -160,6 +234,11 @@ public class MutableResourceMetadataImpl implements MutableResourceMetadata, Ser
return false;
} else if (!type.equals(other.type))
return false;
if (uri == null) {
if (other.uri != null)
return false;
} else if (!uri.equals(other.uri))
return false;
if (userMetadata == null) {
if (other.userMetadata != null)
return false;
@ -168,42 +247,4 @@ public class MutableResourceMetadataImpl implements MutableResourceMetadata, Ser
return true;
}
public void setLastModified(Date lastModified) {
this.lastModified = lastModified;
}
public void setName(String name) {
this.name = name;
}
public void setSize(long size) {
this.size = size;
}
public void setType(ResourceType type) {
this.type = type;
}
public void setUserMetadata(Map<String, String> userMetadata) {
this.userMetadata = userMetadata;
}
public void setETag(String eTag) {
this.eTag = eTag;
}
public void setId(String id) {
this.id = id;
}
public void setLocation(URI location) {
this.location = location;
}
@Override
public String toString() {
return "[type=" + type + ", id=" + id + ", name=" + name + ", size=" + size
+ ", lastModified=" + lastModified + "]";
}
}

View File

@ -16,18 +16,17 @@
* limitations under the License.
* ====================================================================
*/
package org.jclouds.blobstore.domain.internal;
package org.jclouds.domain.internal;
import static com.google.common.base.Preconditions.checkNotNull;
import java.io.Serializable;
import java.net.URI;
import java.util.Date;
import java.util.Map;
import org.jclouds.blobstore.domain.ResourceMetadata;
import org.jclouds.blobstore.domain.ResourceType;
import org.jclouds.domain.ResourceMetadata;
import com.google.common.collect.Maps;
import com.google.inject.internal.Nullable;
/**
@ -35,73 +34,86 @@ import com.google.inject.internal.Nullable;
*
* @author Adrian Cole
*/
public class ResourceMetadataImpl implements ResourceMetadata, Serializable {
public class ResourceMetadataImpl<T extends Enum<T>> implements ResourceMetadata<T>, Serializable {
/** The serialVersionUID */
private static final long serialVersionUID = -280558162576368264L;
private final ResourceType type;
private final @Nullable
String id;
private final @Nullable
String name;
private final @Nullable
URI location;
private final @Nullable
String eTag;
private final @Nullable
Long size;
private final @Nullable
Date lastModified;
private final Map<String, String> userMetadata;
private final T type;
@Nullable
private final String id;
@Nullable
private final String name;
@Nullable
private final String location;
@Nullable
private final URI uri;
private final Map<String, String> userMetadata = Maps.newLinkedHashMap();
public ResourceMetadataImpl(ResourceType type, @Nullable String id, @Nullable String name,
@Nullable URI location, @Nullable String eTag, @Nullable Long size,
@Nullable Date lastModified, Map<String, String> userMetadata) {
public ResourceMetadataImpl(T type, @Nullable String id, @Nullable String name,
@Nullable String location, @Nullable URI uri, Map<String, String> userMetadata) {
this.type = checkNotNull(type, "type");
this.id = id;
this.name = name;
this.location = location;
this.eTag = eTag;
this.size = size;
this.lastModified = lastModified;
this.userMetadata = checkNotNull(userMetadata, "userMetadata");
this.uri = uri;
this.userMetadata.putAll(checkNotNull(userMetadata, "userMetadata"));
}
public int compareTo(ResourceMetadata o) {
/**
* {@inheritDoc}
*/
@Override
public int compareTo(ResourceMetadata<T> o) {
if (getName() == null)
return -1;
return (this == o) ? 0 : getName().compareTo(o.getName());
}
public ResourceType getType() {
/**
* {@inheritDoc}
*/
@Override
public T getType() {
return type;
}
public String getName() {
return name;
}
/**
* {@inheritDoc}
*/
@Override
public String getId() {
return id;
}
public URI getLocation() {
/**
* {@inheritDoc}
*/
@Override
public String getName() {
return name;
}
/**
* {@inheritDoc}
*/
@Override
public String getLocation() {
return location;
}
public String getETag() {
return eTag;
}
public Long getSize() {
return size;
}
public Date getLastModified() {
return lastModified;
/**
* {@inheritDoc}
*/
@Override
public URI getUri() {
return uri;
}
/**
* {@inheritDoc}
*/
@Override
public Map<String, String> getUserMetadata() {
return userMetadata;
}
@ -110,13 +122,11 @@ public class ResourceMetadataImpl implements ResourceMetadata, Serializable {
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((eTag == null) ? 0 : eTag.hashCode());
result = prime * result + ((id == null) ? 0 : id.hashCode());
result = prime * result + ((lastModified == null) ? 0 : lastModified.hashCode());
result = prime * result + ((location == null) ? 0 : location.hashCode());
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + ((size == null) ? 0 : size.hashCode());
result = prime * result + ((type == null) ? 0 : type.hashCode());
result = prime * result + ((uri == null) ? 0 : uri.hashCode());
result = prime * result + ((userMetadata == null) ? 0 : userMetadata.hashCode());
return result;
}
@ -129,22 +139,12 @@ public class ResourceMetadataImpl implements ResourceMetadata, Serializable {
return false;
if (getClass() != obj.getClass())
return false;
ResourceMetadataImpl other = (ResourceMetadataImpl) obj;
if (eTag == null) {
if (other.eTag != null)
return false;
} else if (!eTag.equals(other.eTag))
return false;
ResourceMetadataImpl<?> other = (ResourceMetadataImpl<?>) obj;
if (id == null) {
if (other.id != null)
return false;
} else if (!id.equals(other.id))
return false;
if (lastModified == null) {
if (other.lastModified != null)
return false;
} else if (!lastModified.equals(other.lastModified))
return false;
if (location == null) {
if (other.location != null)
return false;
@ -155,16 +155,16 @@ public class ResourceMetadataImpl implements ResourceMetadata, Serializable {
return false;
} else if (!name.equals(other.name))
return false;
if (size == null) {
if (other.size != null)
return false;
} else if (!size.equals(other.size))
return false;
if (type == null) {
if (other.type != null)
return false;
} else if (!type.equals(other.type))
return false;
if (uri == null) {
if (other.uri != null)
return false;
} else if (!uri.equals(other.uri))
return false;
if (userMetadata == null) {
if (other.userMetadata != null)
return false;
@ -173,4 +173,10 @@ public class ResourceMetadataImpl implements ResourceMetadata, Serializable {
return true;
}
@Override
public String toString() {
return "[type=" + type + ", id=" + id + ", name=" + name + ", location=" + location
+ ", uri=" + uri + ", userMetadata=" + userMetadata + "]";
}
}

View File

@ -18,7 +18,6 @@
*/
package org.jclouds.http;
import java.net.URI;
import java.util.Map;
import java.util.concurrent.TimeUnit;

View File

@ -142,7 +142,7 @@ public class WireLiveTest {
}
@Test(groups = "live")
public void testRemoteInputInputStream() throws Exception {
public void testRemoteInputStream() throws Exception {
URL url = new URL(checkNotNull(sysHttpStreamUrl, "sysHttpStreamUrl"));
URLConnection connection = url.openConnection();
HttpWire wire = setUp();
@ -154,8 +154,8 @@ public class WireLiveTest {
assertEquals(((BufferLogger) wire.getWireLog()).buff.toString().getBytes().length, 3331484);
}
@Test(groups = "live")
public void testCopyRemoteInputInputStream() throws Exception {
@Test(groups = "live", enabled = false)
public void testCopyRemoteInputStream() throws Exception {
URL url = new URL(checkNotNull(sysHttpStreamUrl, "sysHttpStreamUrl"));
URLConnection connection = url.openConnection();
Callable<Void> callable = new ConnectionTester(connection.getInputStream());
@ -165,7 +165,7 @@ public class WireLiveTest {
}
@Test(groups = "live")
public void testRemoteInputInputStreamSynch() throws Exception {
public void testRemoteInputStreamSynch() throws Exception {
URL url = new URL(checkNotNull(sysHttpStreamUrl, "sysHttpStreamUrl"));
URLConnection connection = url.openConnection();
HttpWire wire = setUpSynch();

View File

@ -31,7 +31,7 @@
<artifact:localRepository id="local.repository" path="${user.home}/.m2/repository" />
<artifact:remoteRepository id="jclouds-snapshot.repository" url="http://jclouds.rimuhosting.com/maven2/snapshots" />
<artifact:remoteRepository id="shrinkwrap.repository" url="http://repository.jboss.org/maven2" />
<!-- Setup maven so that we can get latest version of jclouds, shrinkwrap, and jruby -->
<artifact:dependencies pathId="shrinkwrap.classpath">
@ -41,6 +41,7 @@
<dependency groupId="org.jclouds" artifactId="jclouds-atmos" version="1.0-SNAPSHOT" />
<dependency groupId="org.jclouds" artifactId="jclouds-azure" version="1.0-SNAPSHOT" />
<dependency groupId="org.jclouds" artifactId="jclouds-rackspace" version="1.0-SNAPSHOT" />
<remoteRepository refid="shrinkwrap.repository" />
<remoteRepository refid="jclouds-snapshot.repository" />
<localRepository refid="local.repository" />
</artifact:dependencies>
@ -76,6 +77,8 @@
addproperty="key"
/>
<property name="location" value="default" />
<property name="urltoparse" value="blobstore://${account}:${key}@${service}/${container}" />
<target name="export">
@ -120,7 +123,7 @@ class ShrinkBlob < Task
# array thing is a weird hack since jruby doesn't understand varargs
context = BlobStoreContextFactory.new().createContext(destination)
context.getBlobStore().createContainer(@container)
context.getBlobStore().createContainerInLocation(@location, @container)
print "uploading to ",destination.getHost(),"/",@container,"/",@zip,"\n"
context.createInputStreamMap(@container).put(@zip,zipStream);

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