mirror of https://github.com/apache/jclouds.git
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:
parent
0f71237ba8
commit
dff7756acb
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
|
|
@ -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 Standard—Uses 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) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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,
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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>
|
||||
|
|
Loading…
Reference in New Issue