Issue 23, 142: added bucket location and northern california region

git-svn-id: http://jclouds.googlecode.com/svn/trunk@2543 3d8758e0-26b5-11de-8745-db77d3ebf521
This commit is contained in:
adrian.f.cole 2009-12-30 18:50:33 +00:00
parent 0f71237ba8
commit dff7756acb
13 changed files with 644 additions and 322 deletions

View File

@ -43,6 +43,7 @@ import org.jclouds.aws.s3.domain.BucketMetadata;
import org.jclouds.aws.s3.domain.ListBucketResponse;
import org.jclouds.aws.s3.domain.ObjectMetadata;
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.ObjectKey;
import org.jclouds.aws.s3.functions.ParseObjectFromHeadersAndHttpContent;
@ -57,6 +58,7 @@ import org.jclouds.aws.s3.xml.AccessControlListHandler;
import org.jclouds.aws.s3.xml.CopyObjectHandler;
import org.jclouds.aws.s3.xml.ListAllMyBucketsHandler;
import org.jclouds.aws.s3.xml.ListBucketHandler;
import org.jclouds.aws.s3.xml.LocationConstraintHandler;
import org.jclouds.blobstore.attr.BlobScope;
import org.jclouds.blobstore.attr.ConsistencyModel;
import org.jclouds.blobstore.attr.ConsistencyModels;
@ -168,6 +170,15 @@ public interface S3AsyncClient {
@ExceptionParser(ReturnFalseOn404.class)
Future<Boolean> bucketExists(@HostPrefixParam String bucketName);
/**
* @see S3Client#getBucketLocation
*/
@GET
@QueryParams(keys = "location")
@Path("/")
@XMLResponseParser(LocationConstraintHandler.class)
Future<LocationConstraint> getBucketLocation(@HostPrefixParam String bucketName);
/**
* @see S3Client#listBucket
*/

View File

@ -33,6 +33,7 @@ import org.jclouds.aws.s3.domain.BucketMetadata;
import org.jclouds.aws.s3.domain.ListBucketResponse;
import org.jclouds.aws.s3.domain.ObjectMetadata;
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;
@ -330,4 +331,21 @@ public interface S3Client {
*/
boolean putObjectACL(String bucketName, String key, AccessControlList acl);
/**
* A GET location request operation using a bucket URI lists the location constraint of the
* bucket.
* <p/>
* To view the location constraint of a bucket, you must be the bucket owner.
*
* @param bucket
* the bucket you wish to know where exists
*
* @return location of the bucket
*
* @see <a href=
* "http://docs.amazonwebservices.com/AmazonS3/latest/index.html?RESTBucketLocationGET.html"
* />
*/
LocationConstraint getBucketLocation(String bucketName);
}

View File

@ -43,9 +43,76 @@ public class BucketMetadata implements Comparable<BucketMetadata> {
* @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 {
EU
/**
*
* 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) {

View File

@ -51,6 +51,7 @@ import org.jclouds.logging.Logger;
import org.jclouds.util.Utils;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.ImmutableSet;
/**
* Signs the S3 request.
@ -64,6 +65,8 @@ public class RequestAuthorizeSignature implements HttpRequestFilter, RequestSign
private final String[] firstHeadersToSign = new String[] { "Content-MD5",
HttpHeaders.CONTENT_TYPE, HttpHeaders.DATE };
public static Set<String> SPECIAL_QUERIES = ImmutableSet.of("acl", "torrent", "logging",
"location", "requestPayment");
private final SignatureWire signatureWire;
private final String accessKey;
private final String secretKey;
@ -176,10 +179,9 @@ public class RequestAuthorizeSignature implements HttpRequestFilter, RequestSign
for (String param : params) {
String[] paramNameAndValue = param.split("=");
if ("acl".equals(paramNameAndValue[0])) {
paramsToSign.append("acl");
if (SPECIAL_QUERIES.contains(paramNameAndValue[0])) {
paramsToSign.append(paramNameAndValue[0]);
}
// TODO: Other special cases not yet handled: torrent, logging, location, requestPayment
}
if (paramsToSign.length() > 1) {

View File

@ -32,9 +32,9 @@ import org.jclouds.http.options.BaseHttpRequestOptions;
/**
* Contains options supported in the REST API for the PUT bucket operation. <h2>
* Usage</h2> The recommended way to instantiate a PutBucketOptions object is to
* statically import PutBucketOptions.Builder.* and invoke a static creation
* method followed by an instance mutator (if needed):
* Usage</h2> The recommended way to instantiate a PutBucketOptions object is to statically import
* PutBucketOptions.Builder.* and invoke a static creation method followed by an instance mutator
* (if needed):
* <p/>
* <code>
* import static org.jclouds.aws.s3.commands.options.PutBucketOptions.Builder.*
@ -44,71 +44,70 @@ import org.jclouds.http.options.BaseHttpRequestOptions;
* S3Client connection = // get connection
* Future<Boolean> createdInEu = connection.putBucketIfNotExists("bucketName",createIn(EU));
* <code>
*
*
* @author Adrian Cole
* @see <a href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?RESTBucketPUT.html?"
* @see <a
* href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?RESTBucketPUT.html?"
* />
*/
public class PutBucketOptions extends BaseHttpRequestOptions {
public static final PutBucketOptions NONE = new PutBucketOptions();
private CannedAccessPolicy acl = CannedAccessPolicy.PRIVATE;
private LocationConstraint constraint;
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.
* You can currently specify a Europe (EU) location constraint.
*/
public PutBucketOptions createIn(LocationConstraint constraint) {
this.constraint = checkNotNull(constraint, "constraint");
this.payload = String
.format(
"<CreateBucketConfiguration><LocationConstraint>%1$s</LocationConstraint></CreateBucketConfiguration>",
constraint.toString());
return this;
}
/**
* 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.
*
* @see CannedAccessPolicy
*/
public PutBucketOptions withBucketAcl(CannedAccessPolicy acl) {
this.acl = checkNotNull(acl, "acl");
if (!acl.equals(CannedAccessPolicy.PRIVATE))
this.replaceHeader(S3Headers.CANNED_ACL, acl.toString());
return this;
}
/**
* Override the default ACL (private) with the specified one.
*
* @see CannedAccessPolicy
*/
public PutBucketOptions withBucketAcl(CannedAccessPolicy acl) {
this.acl = checkNotNull(acl, "acl");
if (!acl.equals(CannedAccessPolicy.PRIVATE))
this.replaceHeader(S3Headers.CANNED_ACL, acl.toString());
return this;
}
/**
* @see PutBucketOptions#withBucketAcl(CannedAccessPolicy)
*/
public CannedAccessPolicy getAcl() {
return acl;
}
/**
* @see PutBucketOptions#withBucketAcl(CannedAccessPolicy)
*/
public CannedAccessPolicy getAcl() {
return acl;
}
/**
* @see PutBucketOptions#createIn(org.jclouds.aws.s3.domain.BucketMetadata.LocationConstraint)
*/
public LocationConstraint getLocationConstraint() {
return constraint;
}
/**
* @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);
}
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)
*/
public static PutBucketOptions withBucketAcl(CannedAccessPolicy acl) {
PutBucketOptions options = new PutBucketOptions();
return options.withBucketAcl(acl);
}
}
/**
* @see PutBucketOptions#withBucketAcl(CannedAccessPolicy)
*/
public static PutBucketOptions withBucketAcl(CannedAccessPolicy acl) {
PutBucketOptions options = new PutBucketOptions();
return options.withBucketAcl(acl);
}
}
}

View File

@ -0,0 +1,52 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*/
package org.jclouds.aws.s3.xml;
import org.jclouds.aws.s3.domain.BucketMetadata.LocationConstraint;
import org.jclouds.http.functions.ParseSax;
/**
* Parses the response from Amazon S3 GET Bucket Location
* <p/>
* LocationConstraint 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> {
private StringBuilder currentText = new StringBuilder();
private LocationConstraint constraint;
public LocationConstraint getResult() {
return constraint;
}
public void endElement(String uri, String name, String qName) {
constraint = LocationConstraint.fromValue(currentText.toString().trim());
}
public void characters(char ch[], int start, int length) {
currentText.append(ch, start, length);
}
}

View File

@ -24,7 +24,7 @@
package org.jclouds.aws.ec2;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.jclouds.aws.ec2.options.RunInstancesOptions.Builder.withKeyName;
import static org.jclouds.aws.ec2.options.RunInstancesOptions.Builder.asType;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertNotNull;
@ -68,7 +68,7 @@ import com.google.inject.Injector;
*
* @author Adrian Cole
*/
@Test(groups = "live", enabled = true, sequential = true, testName = "ec2.CloudApplicationArchitecturesEC2ClientLiveTest")
@Test(groups = "live", enabled = false, sequential = true, testName = "ec2.CloudApplicationArchitecturesEC2ClientLiveTest")
public class CloudApplicationArchitecturesEC2ClientLiveTest {
private EC2Client client;
@ -94,7 +94,7 @@ public class CloudApplicationArchitecturesEC2ClientLiveTest {
injector.injectMembers(socketOpen); // add logger
}
@Test(enabled = true)
@Test(enabled = false)
void testCreateSecurityGroupIngressCidr() throws InterruptedException, ExecutionException,
TimeoutException {
securityGroupName = serverPrefix + "ingress";
@ -107,15 +107,13 @@ public class CloudApplicationArchitecturesEC2ClientLiveTest {
client.getSecurityGroupServices().createSecurityGroupInRegion(Region.DEFAULT,
securityGroupName, securityGroupName);
client.getSecurityGroupServices().authorizeSecurityGroupIngressInRegion(Region.DEFAULT,
securityGroupName, IpProtocol.TCP, 80, 80, "0.0.0.0/0");
client.getSecurityGroupServices().authorizeSecurityGroupIngressInRegion(Region.DEFAULT,
securityGroupName, IpProtocol.TCP, 443, 443, "0.0.0.0/0");
client.getSecurityGroupServices().authorizeSecurityGroupIngressInRegion(Region.DEFAULT,
securityGroupName, IpProtocol.TCP, 22, 22, "0.0.0.0/0");
for (int port : new int[] { 80, 443, 22 }) {
client.getSecurityGroupServices().authorizeSecurityGroupIngressInRegion(Region.DEFAULT,
securityGroupName, IpProtocol.TCP, port, port, "0.0.0.0/0");
}
}
@Test(enabled = true)
@Test(enabled = false)
void testCreateKeyPair() throws InterruptedException, ExecutionException, TimeoutException {
String keyName = serverPrefix + "1";
try {
@ -132,23 +130,22 @@ public class CloudApplicationArchitecturesEC2ClientLiveTest {
assertEquals(keyPair.getKeyName(), keyName);
}
@Test(enabled = true, dependsOnMethods = { "testCreateKeyPair",
@Test(enabled = false, dependsOnMethods = { "testCreateKeyPair",
"testCreateSecurityGroupIngressCidr" })
public void testCreateRunningInstance() throws Exception {
String imageId = "ami-1fd73376";
RunningInstance server = null;
while (server == null) {
try {
System.out.printf("%d: running instance%n", System.currentTimeMillis());
server = client.getInstanceServices().runInstancesInRegion(
Region.DEFAULT,
null,
imageId,
1,
1,
withKeyName(keyPair.getKeyName()).asType(InstanceType.M1_SMALL)
.withSecurityGroup(securityGroupName)).getRunningInstances()
.iterator().next();
Reservation reservation = client.getInstanceServices().runInstancesInRegion(
Region.DEFAULT, null, // allow ec2 to chose an availability zone
"ami-7e28ca17", // the ami I want
1, // minimum instances
1, // maximum instances
asType(InstanceType.M1_SMALL) // smallest instance size
.withKeyName(keyPair.getKeyName()) // key I created above
.withSecurityGroup(securityGroupName)); // group I created above
server = Iterables.getOnlyElement(reservation.getRunningInstances());
} catch (HttpResponseException htpe) {
if (htpe.getResponse().getStatusCode() == 400)
continue;
@ -165,7 +162,7 @@ public class CloudApplicationArchitecturesEC2ClientLiveTest {
}
@Test(enabled = true, dependsOnMethods = "testCreateRunningInstance")
@Test(enabled = false, dependsOnMethods = "testCreateRunningInstance")
void testElasticIpAddress() throws InterruptedException, ExecutionException, TimeoutException,
IOException {
address = client.getElasticIPAddressServices().allocateAddressInRegion(Region.DEFAULT);
@ -244,8 +241,8 @@ public class CloudApplicationArchitecturesEC2ClientLiveTest {
throws InterruptedException, ExecutionException, TimeoutException {
RunningInstance currentDetails = null;
for (currentDetails = getRunningInstance(serverId); currentDetails.getInstanceState() != InstanceState.RUNNING; currentDetails = getRunningInstance(serverId)) {
System.out.printf("%s blocking on status active: currently: %s%n", currentDetails
.getId(), currentDetails.getInstanceState());
System.out.printf("%s blocking on status active: currently: %s%n", currentDetails.getId(),
currentDetails.getInstanceState());
Thread.sleep(5 * 1000);
}

View File

@ -35,6 +35,7 @@ import java.io.ByteArrayInputStream;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.UnknownHostException;
import java.util.Set;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
@ -47,6 +48,7 @@ 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.Region;
import org.jclouds.aws.ec2.domain.Reservation;
import org.jclouds.aws.ec2.domain.RootDeviceType;
import org.jclouds.aws.ec2.domain.RunningInstance;
import org.jclouds.aws.ec2.domain.Snapshot;
@ -88,7 +90,7 @@ import com.google.inject.internal.ImmutableMap;
*
* @author Adrian Cole
*/
@Test(groups = "live", sequential = true, testName = "ec2.EBSBootEC2ClientLiveTest")
@Test(groups = "live", enabled = false, sequential = true, testName = "ec2.EBSBootEC2ClientLiveTest")
public class EBSBootEC2ClientLiveTest {
// don't need a lot of space. 2GB should be more than enough for testing
private static final int VOLUME_SIZE = 2;
@ -137,9 +139,8 @@ public class EBSBootEC2ClientLiveTest {
VolumeAttached volumeAttached = injector.getInstance(VolumeAttached.class);
attachTester = new RetryablePredicate<Attachment>(volumeAttached, 60, 1, TimeUnit.SECONDS);
InstanceStateRunning instanceStateRunning = injector.getInstance(InstanceStateRunning.class);
runningTester = new RetryablePredicate<RunningInstance>(instanceStateRunning, 180, 5,
TimeUnit.SECONDS);
runningTester = new RetryablePredicate<RunningInstance>(new InstanceStateRunning(client
.getInstanceServices()), 180, 5, TimeUnit.SECONDS);
InstanceStateStopped instanceStateStopped = injector.getInstance(InstanceStateStopped.class);
stoppedTester = new RetryablePredicate<RunningInstance>(instanceStateStopped, 60, 1,
@ -153,7 +154,7 @@ public class EBSBootEC2ClientLiveTest {
injector.injectMembers(socketOpen); // add logger
}
@Test(enabled = true)
@Test(enabled = false)
void testCreateSecurityGroupIngressCidr() throws InterruptedException, ExecutionException,
TimeoutException {
securityGroupName = INSTANCE_PREFIX + "ingress";
@ -174,7 +175,7 @@ public class EBSBootEC2ClientLiveTest {
securityGroupName, IpProtocol.TCP, 22, 22, "0.0.0.0/0");
}
@Test(enabled = true)
@Test(enabled = false)
void testCreateKeyPair() {
String keyName = INSTANCE_PREFIX + "1";
try {
@ -190,7 +191,7 @@ public class EBSBootEC2ClientLiveTest {
assertEquals(keyPair.getKeyName(), keyName);
}
@Test(dependsOnMethods = { "testCreateKeyPair", "testCreateSecurityGroupIngressCidr" })
@Test(enabled = false, dependsOnMethods = { "testCreateKeyPair", "testCreateSecurityGroupIngressCidr" })
public void testCreateRunningInstance() throws Exception {
instance = createInstance(IMAGE_ID);
}
@ -221,7 +222,7 @@ public class EBSBootEC2ClientLiveTest {
return instance;
}
@Test(dependsOnMethods = "testCreateRunningInstance")
@Test(enabled = false, dependsOnMethods = "testCreateRunningInstance")
void testCreateAndAttachVolume() {
volume = client.getElasticBlockStoreServices().createVolumeInAvailabilityZone(
instance.getAvailabilityZone(), VOLUME_SIZE);
@ -267,10 +268,10 @@ public class EBSBootEC2ClientLiveTest {
"umount {varl}EBS_MOUNT_POINT{varr}", "echo " + SCRIPT_END).build(OsFamily.UNIX);
}
@Test(dependsOnMethods = "testCreateAndAttachVolume")
@Test(enabled = false, dependsOnMethods = "testCreateAndAttachVolume")
void testBundleInstance() {
SshClient ssh = sshFactory.create(new InetSocketAddress(instance.getIpAddress(), 22), "ubuntu",
keyPair.getKeyMaterial().getBytes());
SshClient ssh = sshFactory.create(new InetSocketAddress(instance.getIpAddress(), 22),
"ubuntu", keyPair.getKeyMaterial().getBytes());
try {
ssh.connect();
} catch (SshException e) {// try twice in case there is a network timeout
@ -290,7 +291,7 @@ public class EBSBootEC2ClientLiveTest {
.getId());
ssh.exec("chmod 755 " + script);
ssh.exec(script + " init");
ExecResponse output = ssh.exec("sudo "+script + " start");
ExecResponse output = ssh.exec("sudo " + script + " start");
System.out.println(output);
output = ssh.exec(script + " status");
@ -336,7 +337,7 @@ public class EBSBootEC2ClientLiveTest {
}
@Test(dependsOnMethods = "testBundleInstance")
@Test(enabled = false, dependsOnMethods = "testBundleInstance")
void testAMIFromBundle() {
volume = Iterables.getOnlyElement(client.getElasticBlockStoreServices()
.describeVolumesInRegion(volume.getRegion(), volume.getId()));
@ -384,7 +385,7 @@ public class EBSBootEC2ClientLiveTest {
verifyImage();
}
@Test(dependsOnMethods = { "testAMIFromBundle" })
@Test(enabled = false, dependsOnMethods = { "testAMIFromBundle" })
public void testInstanceFromEBS() throws Exception {
System.out.printf("%d: %s creating instance from ebs-backed ami%n", System
.currentTimeMillis(), ebsImage.getId());
@ -453,9 +454,13 @@ public class EBSBootEC2ClientLiveTest {
System.out.printf("%d: %s awaiting instance to run %n", System.currentTimeMillis(), instance
.getId());
assert runningTester.apply(instance);
instance = Iterables.getOnlyElement(Iterables.getOnlyElement(
client.getInstanceServices().describeInstancesInRegion(instance.getRegion(),
instance.getId())).getRunningInstances());
// search my account for the instance I just created
Set<Reservation> reservations = client.getInstanceServices().describeInstancesInRegion(
instance.getRegion(), instance.getId()); // last parameter (ids) narrows the search
instance = Iterables.getOnlyElement(Iterables.getOnlyElement(reservations)
.getRunningInstances());
System.out.printf("%d: %s awaiting ssh service to start%n", System.currentTimeMillis(),
instance.getIpAddress());

View File

@ -49,6 +49,7 @@ import org.jclouds.aws.s3.xml.AccessControlListHandler;
import org.jclouds.aws.s3.xml.CopyObjectHandler;
import org.jclouds.aws.s3.xml.ListAllMyBucketsHandler;
import org.jclouds.aws.s3.xml.ListBucketHandler;
import org.jclouds.aws.s3.xml.LocationConstraintHandler;
import org.jclouds.blobstore.binders.BindBlobToMultipartFormTest;
import org.jclouds.blobstore.config.BlobStoreObjectModule;
import org.jclouds.blobstore.functions.ReturnVoidOnNotFoundOr404;
@ -82,7 +83,22 @@ import com.google.inject.TypeLiteral;
* @author Adrian Cole
*/
@Test(groups = "unit", testName = "s3.S3ClientTest")
public class S3ClientTest extends RestClientTest<S3AsyncClient> {
public class S3AsyncClientTest extends RestClientTest<S3AsyncClient> {
public void testGetBucketLocation() throws SecurityException, NoSuchMethodException, IOException {
Method method = S3AsyncClient.class.getMethod("getBucketLocation", String.class);
GeneratedHttpRequest<S3AsyncClient> httpMethod = processor.createRequest(method, "bucket");
assertRequestLineEquals(httpMethod, "GET http://bucket.stub:8080/?location HTTP/1.1");
assertHeadersEqual(httpMethod, "Host: bucket.stub\n");
assertPayloadEquals(httpMethod, null);
assertResponseParserClassEquals(method, httpMethod, ParseSax.class);
assertSaxResponseParserClassEquals(method, LocationConstraintHandler.class);
assertExceptionParserClassEquals(method, null);
checkFilters(httpMethod);
}
public void testListBucket() throws SecurityException, NoSuchMethodException, IOException {
Method method = S3AsyncClient.class.getMethod("listBucket", String.class, Array.newInstance(
@ -120,8 +136,8 @@ public class S3ClientTest extends RestClientTest<S3AsyncClient> {
Method method = S3AsyncClient.class
.getMethod("copyObject", String.class, String.class, String.class, String.class,
Array.newInstance(CopyObjectOptions.class, 0).getClass());
GeneratedHttpRequest<S3AsyncClient> httpMethod = processor.createRequest(method, "sourceBucket",
"sourceObject", "destinationBucket", "destinationObject");
GeneratedHttpRequest<S3AsyncClient> httpMethod = processor.createRequest(method,
"sourceBucket", "sourceObject", "destinationBucket", "destinationObject");
assertRequestLineEquals(httpMethod,
"PUT http://destinationBucket.stub:8080/destinationObject HTTP/1.1");
@ -297,8 +313,8 @@ public class S3ClientTest extends RestClientTest<S3AsyncClient> {
public void testPutObject() throws ArrayIndexOutOfBoundsException, SecurityException,
IllegalArgumentException, NoSuchMethodException, IOException {
Method method = S3AsyncClient.class.getMethod("putObject", String.class, S3Object.class, Array
.newInstance(PutObjectOptions.class, 0).getClass());
Method method = S3AsyncClient.class.getMethod("putObject", String.class, S3Object.class,
Array.newInstance(PutObjectOptions.class, 0).getClass());
GeneratedHttpRequest<S3AsyncClient> httpMethod = processor.createRequest(method, "bucket",
blobToS3Object.apply(BindBlobToMultipartFormTest.TEST_BLOB));
@ -317,8 +333,8 @@ public class S3ClientTest extends RestClientTest<S3AsyncClient> {
public void testPutObjectACL() throws SecurityException, NoSuchMethodException, IOException {
Method method = S3AsyncClient.class.getMethod("putObjectACL", String.class, String.class,
AccessControlList.class);
GeneratedHttpRequest<S3AsyncClient> httpMethod = processor.createRequest(method, "bucket", "key",
AccessControlList.fromCannedAccessPolicy(CannedAccessPolicy.PRIVATE, "1234"));
GeneratedHttpRequest<S3AsyncClient> httpMethod = processor.createRequest(method, "bucket",
"key", AccessControlList.fromCannedAccessPolicy(CannedAccessPolicy.PRIVATE, "1234"));
assertRequestLineEquals(httpMethod, "PUT http://bucket.stub:8080/key?acl HTTP/1.1");
assertHeadersEqual(httpMethod,

View File

@ -31,37 +31,26 @@ import static org.jclouds.aws.s3.options.CopyObjectOptions.Builder.ifSourceModif
import static org.jclouds.aws.s3.options.CopyObjectOptions.Builder.ifSourceUnmodifiedSince;
import static org.jclouds.aws.s3.options.CopyObjectOptions.Builder.overrideAcl;
import static org.jclouds.aws.s3.options.CopyObjectOptions.Builder.overrideMetadataWith;
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.jclouds.aws.s3.options.PutObjectOptions.Builder.withAcl;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertTrue;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.util.Date;
import java.util.Map;
import java.util.SortedSet;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeoutException;
import org.jclouds.aws.s3.domain.AccessControlList;
import org.jclouds.aws.s3.domain.BucketMetadata;
import org.jclouds.aws.s3.domain.CannedAccessPolicy;
import org.jclouds.aws.s3.domain.ListBucketResponse;
import org.jclouds.aws.s3.domain.ObjectMetadata;
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.GroupGranteeURI;
import org.jclouds.aws.s3.domain.AccessControlList.Permission;
import org.jclouds.aws.s3.domain.BucketMetadata.LocationConstraint;
import org.jclouds.aws.s3.options.PutObjectOptions;
import org.jclouds.blobstore.integration.internal.BaseBlobStoreIntegrationTest;
import org.jclouds.http.HttpResponseException;
@ -488,44 +477,6 @@ public class S3ClientLiveTest extends BaseBlobStoreIntegrationTest<S3AsyncClient
}
}
public void testPrivateAclIsDefaultForContainer() throws InterruptedException,
ExecutionException, TimeoutException, IOException {
String containerName = getContainerName();
try {
AccessControlList acl = context.getApi().getBucketACL(containerName);
assertEquals(acl.getGrants().size(), 1);
assertTrue(acl.getOwner() != null);
String ownerId = acl.getOwner().getId();
assertTrue(acl.hasPermission(ownerId, Permission.FULL_CONTROL));
} finally {
returnContainer(containerName);
}
}
public void testUpdateContainerACL() throws InterruptedException, ExecutionException,
TimeoutException, IOException, Exception {
String containerName = getContainerName();
try {
// Confirm the container is private
AccessControlList acl = context.getApi().getBucketACL(containerName);
String ownerId = acl.getOwner().getId();
assertEquals(acl.getGrants().size(), 1);
assertTrue(acl.hasPermission(ownerId, Permission.FULL_CONTROL));
addGrantsToACL(acl);
assertEquals(acl.getGrants().size(), 4);
assertTrue(context.getApi().putBucketACL(containerName, acl));
// Confirm that the updated ACL has stuck.
acl = context.getApi().getBucketACL(containerName);
checkGrants(acl);
} finally {
destroyContainer(containerName);
}
}
private void checkGrants(AccessControlList acl) {
String ownerId = acl.getOwner().getId();
@ -545,165 +496,4 @@ public class S3ClientLiveTest extends BaseBlobStoreIntegrationTest<S3AsyncClient
acl.addPermission(new CanonicalUserGrantee(ownerId), Permission.WRITE_ACP);
}
public void testPublicReadAccessPolicy() throws Exception {
String containerName = getScratchContainerName();
try {
context.getApi().putBucketIfNotExists(containerName,
withBucketAcl(CannedAccessPolicy.PUBLIC_READ));
AccessControlList acl = context.getApi().getBucketACL(containerName);
assertTrue(acl.hasPermission(GroupGranteeURI.ALL_USERS, Permission.READ), acl.toString());
// 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", containerName));
// Utils.toStringAndClose(url.openStream());
} finally {
destroyContainer(containerName);
}
}
@Test(expectedExceptions = IOException.class)
public void testDefaultAccessPolicy() throws Exception {
String containerName = getContainerName();
try {
URL url = new URL(String.format("https://%s.s3.amazonaws.com", containerName));
Utils.toStringAndClose(url.openStream());
} finally {
returnContainer(containerName);
}
}
/**
* using scratch containerName as we are changing location
*/
public void testEu() throws Exception {
final String containerName = getScratchContainerName();
try {
context.getApi().putBucketIfNotExists(containerName + "eu",
createIn(LocationConstraint.EU).withBucketAcl(CannedAccessPolicy.PUBLIC_READ));
assertConsistencyAware(new Runnable() {
public void run() {
try {
AccessControlList acl = context.getApi().getBucketACL(containerName + "eu");
assertTrue(acl.hasPermission(GroupGranteeURI.ALL_USERS, Permission.READ), acl
.toString());
} catch (Exception e) {
Utils.<RuntimeException> rethrowIfRuntimeOrSameType(e);
}
}
});
// 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", containerName));
// Utils.toStringAndClose(url.openStream());
} finally {
destroyContainer(containerName + "eu");
}
}
void containerExists() throws Exception {
String containerName = getContainerName();
try {
SortedSet<BucketMetadata> list = context.getApi().listOwnedBuckets();
BucketMetadata firstContainer = list.first();
BucketMetadata toMatch = new BucketMetadata(containerName, new Date(), firstContainer
.getOwner());
assert list.contains(toMatch);
} finally {
returnContainer(containerName);
}
}
protected void addAlphabetUnderRoot(String containerName) {
for (char letter = 'a'; letter <= 'z'; letter++) {
S3Object blob = context.getApi().newS3Object();
blob.getMetadata().setKey(letter + "");
blob.setPayload(letter + "content");
context.getApi().putObject(containerName, blob);
}
}
public void testListContainerMarker() throws InterruptedException, ExecutionException,
TimeoutException {
String containerName = getContainerName();
try {
addAlphabetUnderRoot(containerName);
ListBucketResponse container = context.getApi()
.listBucket(containerName, afterMarker("y"));
assertEquals(container.getMarker(), "y");
assert !container.isTruncated();
assertEquals(container.size(), 1);
} finally {
returnContainer(containerName);
}
}
public void testListContainerDelimiter() throws InterruptedException, ExecutionException,
TimeoutException, UnsupportedEncodingException {
String containerName = getContainerName();
try {
String prefix = "apps";
addTenObjectsUnderPrefix(containerName, prefix);
add15UnderRoot(containerName);
ListBucketResponse container = context.getApi().listBucket(containerName, delimiter("/"));
assertEquals(container.getDelimiter(), "/");
assert !container.isTruncated();
assertEquals(container.size(), 15);
assertEquals(container.getCommonPrefixes().size(), 1);
} finally {
returnContainer(containerName);
}
}
public void testListContainerPrefix() throws InterruptedException, ExecutionException,
TimeoutException, UnsupportedEncodingException {
String containerName = getContainerName();
try {
String prefix = "apps";
addTenObjectsUnderPrefix(containerName, prefix);
add15UnderRoot(containerName);
ListBucketResponse container = context.getApi().listBucket(containerName,
withPrefix("apps/"));
assert !container.isTruncated();
assertEquals(container.size(), 10);
assertEquals(container.getPrefix(), "apps/");
} finally {
returnContainer(containerName);
}
}
public void testListContainerMaxResults() throws InterruptedException, ExecutionException,
TimeoutException, UnsupportedEncodingException {
String containerName = getContainerName();
try {
addAlphabetUnderRoot(containerName);
ListBucketResponse container = context.getApi().listBucket(containerName, maxResults(5));
assertEquals(container.getMaxKeys(), 5);
assert container.isTruncated();
assertEquals(container.size(), 5);
} finally {
returnContainer(containerName);
}
}
protected void add15UnderRoot(String containerName) {
for (int i = 0; i < 15; i++) {
S3Object blob = context.getApi().newS3Object();
blob.getMetadata().setKey(i + "");
blob.setPayload(i + "content");
context.getApi().putObject(containerName, blob);
}
}
protected void addTenObjectsUnderPrefix(String containerName, String prefix) {
for (int i = 0; i < 10; i++) {
S3Object blob = context.getApi().newS3Object();
blob.getMetadata().setKey(prefix + "/" + i);
blob.setPayload(i + "content");
context.getApi().putObject(containerName, blob);
}
}
}

View File

@ -51,6 +51,7 @@ 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;
@ -334,4 +335,13 @@ public class StubS3AsyncClient implements S3AsyncClient {
return objectProvider.create(null);
}
@Override
public Future<LocationConstraint> getBucketLocation(String bucketName) {
return new FutureBase<LocationConstraint>() {
public LocationConstraint get() throws InterruptedException, ExecutionException {
return LocationConstraint.US_STANDARD;
}
};
}
}

View File

@ -0,0 +1,348 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*/
package org.jclouds.aws.s3.services;
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.assertTrue;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.util.Date;
import java.util.SortedSet;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeoutException;
import org.jclouds.aws.s3.S3AsyncClient;
import org.jclouds.aws.s3.S3Client;
import org.jclouds.aws.s3.domain.AccessControlList;
import org.jclouds.aws.s3.domain.BucketMetadata;
import org.jclouds.aws.s3.domain.CannedAccessPolicy;
import org.jclouds.aws.s3.domain.ListBucketResponse;
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.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;
import org.testng.annotations.Test;
/**
*
* @author James Murty
* @author Adrian Cole
*/
@Test(groups = { "integration", "live" }, testName = "s3.S3ClientLiveTest")
public class BucketsLiveTest extends BaseBlobStoreIntegrationTest<S3AsyncClient, S3Client> {
/**
* this method overrides bucketName to ensure it isn't found
*/
@Test(groups = { "integration", "live" })
public void deleteBucketIfEmptyNotFound() throws Exception {
assert context.getApi().deleteBucketIfEmpty("dbienf");
}
@Test(groups = { "integration", "live" })
public void deleteBucketIfEmptyButHasContents() throws Exception {
String bucketName = getContainerName();
try {
addBlobToContainer(bucketName, "test");
assert !context.getApi().deleteBucketIfEmpty(bucketName);
} finally {
returnContainer(bucketName);
}
}
public void testPrivateAclIsDefaultForBucket() throws InterruptedException, ExecutionException,
TimeoutException, IOException {
String bucketName = getContainerName();
try {
AccessControlList acl = context.getApi().getBucketACL(bucketName);
assertEquals(acl.getGrants().size(), 1);
assertTrue(acl.getOwner() != null);
String ownerId = acl.getOwner().getId();
assertTrue(acl.hasPermission(ownerId, Permission.FULL_CONTROL));
} finally {
returnContainer(bucketName);
}
}
public void testUpdateBucketACL() throws InterruptedException, ExecutionException,
TimeoutException, IOException, Exception {
String bucketName = getContainerName();
try {
// Confirm the bucket is private
AccessControlList acl = context.getApi().getBucketACL(bucketName);
String ownerId = acl.getOwner().getId();
assertEquals(acl.getGrants().size(), 1);
assertTrue(acl.hasPermission(ownerId, Permission.FULL_CONTROL));
addGrantsToACL(acl);
assertEquals(acl.getGrants().size(), 4);
assertTrue(context.getApi().putBucketACL(bucketName, acl));
// Confirm that the updated ACL has stuck.
acl = context.getApi().getBucketACL(bucketName);
checkGrants(acl);
} finally {
destroyContainer(bucketName);
}
}
private void checkGrants(AccessControlList acl) {
String ownerId = acl.getOwner().getId();
assertEquals(acl.getGrants().size(), 4, acl.toString());
assertTrue(acl.hasPermission(ownerId, Permission.FULL_CONTROL), acl.toString());
assertTrue(acl.hasPermission(GroupGranteeURI.ALL_USERS, Permission.READ), acl.toString());
assertTrue(acl.hasPermission(ownerId, Permission.WRITE_ACP), acl.toString());
// EmailAddressGrantee is replaced by a CanonicalUserGrantee, so we cannot test by email addr
assertTrue(acl.hasPermission(StubS3AsyncClient.TEST_ACL_ID, Permission.READ_ACP), acl
.toString());
}
private void addGrantsToACL(AccessControlList acl) {
String ownerId = acl.getOwner().getId();
acl.addPermission(GroupGranteeURI.ALL_USERS, Permission.READ);
acl.addPermission(new EmailAddressGrantee(StubS3AsyncClient.TEST_ACL_EMAIL),
Permission.READ_ACP);
acl.addPermission(new CanonicalUserGrantee(ownerId), Permission.WRITE_ACP);
}
public void testPublicReadAccessPolicy() throws Exception {
String bucketName = getScratchContainerName();
try {
context.getApi().putBucketIfNotExists(bucketName,
withBucketAcl(CannedAccessPolicy.PUBLIC_READ));
AccessControlList acl = context.getApi().getBucketACL(bucketName);
assertTrue(acl.hasPermission(GroupGranteeURI.ALL_USERS, Permission.READ), acl.toString());
// 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));
// Utils.toStringAndClose(url.openStream());
} finally {
destroyContainer(bucketName);
}
}
@Test(expectedExceptions = IOException.class)
public void testDefaultAccessPolicy() throws Exception {
String bucketName = getContainerName();
try {
URL url = new URL(String.format("https://%s.s3.amazonaws.com", bucketName));
Utils.toStringAndClose(url.openStream());
} finally {
returnContainer(bucketName);
}
}
public void testDefaultBucketLocation() throws Exception {
String bucketName = getContainerName();
try {
assertEquals(LocationConstraint.US_STANDARD, context.getApi()
.getBucketLocation(bucketName));
} finally {
returnContainer(bucketName);
}
}
/**
* using scratch bucketName as we are changing location
*/
public void testEu() throws Exception {
final String bucketName = getScratchContainerName();
try {
context.getApi().putBucketIfNotExists(bucketName + "eu",
createIn(LocationConstraint.EU).withBucketAcl(CannedAccessPolicy.PUBLIC_READ));
assertConsistencyAware(new Runnable() {
public void run() {
try {
AccessControlList acl = context.getApi().getBucketACL(bucketName + "eu");
assertTrue(acl.hasPermission(GroupGranteeURI.ALL_USERS, Permission.READ), acl
.toString());
} catch (Exception e) {
Utils.<RuntimeException> rethrowIfRuntimeOrSameType(e);
}
}
});
assertEquals(LocationConstraint.EU, 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));
// Utils.toStringAndClose(url.openStream());
} finally {
destroyContainer(bucketName + "eu");
}
}
/**
* using scratch bucketName as we are changing location
*/
public void testNorthernCalifornia() throws Exception {
final String bucketName = getScratchContainerName();
try {
context.getApi().putBucketIfNotExists(
bucketName + "cali",
createIn(LocationConstraint.US_WEST)
.withBucketAcl(CannedAccessPolicy.PUBLIC_READ));
assertConsistencyAware(new Runnable() {
public void run() {
try {
AccessControlList acl = context.getApi().getBucketACL(bucketName + "cali");
assertTrue(acl.hasPermission(GroupGranteeURI.ALL_USERS, Permission.READ), acl
.toString());
} catch (Exception e) {
Utils.<RuntimeException> rethrowIfRuntimeOrSameType(e);
}
}
});
assertEquals(LocationConstraint.US_WEST, 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));
// Utils.toStringAndClose(url.openStream());
} finally {
destroyContainer(bucketName + "cali");
}
}
void bucketExists() throws Exception {
String bucketName = getContainerName();
try {
SortedSet<BucketMetadata> list = context.getApi().listOwnedBuckets();
BucketMetadata firstBucket = list.first();
BucketMetadata toMatch = new BucketMetadata(bucketName, new Date(), firstBucket.getOwner());
assert list.contains(toMatch);
} finally {
returnContainer(bucketName);
}
}
protected void addAlphabetUnderRoot(String bucketName) {
for (char letter = 'a'; letter <= 'z'; letter++) {
S3Object blob = context.getApi().newS3Object();
blob.getMetadata().setKey(letter + "");
blob.setPayload(letter + "content");
context.getApi().putObject(bucketName, blob);
}
}
public void testListBucketMarker() throws InterruptedException, ExecutionException,
TimeoutException {
String bucketName = getContainerName();
try {
addAlphabetUnderRoot(bucketName);
ListBucketResponse bucket = context.getApi().listBucket(bucketName, afterMarker("y"));
assertEquals(bucket.getMarker(), "y");
assert !bucket.isTruncated();
assertEquals(bucket.size(), 1);
} finally {
returnContainer(bucketName);
}
}
public void testListBucketDelimiter() throws InterruptedException, ExecutionException,
TimeoutException, UnsupportedEncodingException {
String bucketName = getContainerName();
try {
String prefix = "apps";
addTenObjectsUnderPrefix(bucketName, prefix);
add15UnderRoot(bucketName);
ListBucketResponse bucket = context.getApi().listBucket(bucketName, delimiter("/"));
assertEquals(bucket.getDelimiter(), "/");
assert !bucket.isTruncated();
assertEquals(bucket.size(), 15);
assertEquals(bucket.getCommonPrefixes().size(), 1);
} finally {
returnContainer(bucketName);
}
}
public void testListBucketPrefix() throws InterruptedException, ExecutionException,
TimeoutException, UnsupportedEncodingException {
String bucketName = getContainerName();
try {
String prefix = "apps";
addTenObjectsUnderPrefix(bucketName, prefix);
add15UnderRoot(bucketName);
ListBucketResponse bucket = context.getApi().listBucket(bucketName, withPrefix("apps/"));
assert !bucket.isTruncated();
assertEquals(bucket.size(), 10);
assertEquals(bucket.getPrefix(), "apps/");
} finally {
returnContainer(bucketName);
}
}
public void testListBucketMaxResults() throws InterruptedException, ExecutionException,
TimeoutException, UnsupportedEncodingException {
String bucketName = getContainerName();
try {
addAlphabetUnderRoot(bucketName);
ListBucketResponse bucket = context.getApi().listBucket(bucketName, maxResults(5));
assertEquals(bucket.getMaxKeys(), 5);
assert bucket.isTruncated();
assertEquals(bucket.size(), 5);
} finally {
returnContainer(bucketName);
}
}
protected void add15UnderRoot(String bucketName) {
for (int i = 0; i < 15; i++) {
S3Object blob = context.getApi().newS3Object();
blob.getMetadata().setKey(i + "");
blob.setPayload(i + "content");
context.getApi().putObject(bucketName, blob);
}
}
protected void addTenObjectsUnderPrefix(String bucketName, String prefix) {
for (int i = 0; i < 10; i++) {
S3Object blob = context.getApi().newS3Object();
blob.getMetadata().setKey(prefix + "/" + i);
blob.setPayload(i + "content");
context.getApi().putObject(bucketName, blob);
}
}
}

View File

@ -52,5 +52,12 @@
<type>test-jar</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>jclouds-aws</artifactId>
<version>${project.version}</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
</dependencies>
</project>