mirror of https://github.com/apache/jclouds.git
Issue 271 updated to support google storage
This commit is contained in:
parent
cba3f660fb
commit
518b453c6d
|
@ -27,8 +27,8 @@ import com.google.common.collect.ImmutableSet;
|
||||||
* Regions used for all aws commands.
|
* Regions used for all aws commands.
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
* @see <a href=
|
* @see <a href="http://docs.amazonwebservices.com/AmazonS3/latest/dev/index.html?LocationSelection.html"
|
||||||
* "http://docs.amazonwebservices.com/AmazonS3/latest/dev/index.html?LocationSelection.html" />
|
* />
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class Region {
|
public class Region {
|
||||||
|
@ -37,8 +37,9 @@ public class Region {
|
||||||
* <p/>
|
* <p/>
|
||||||
* <h3>S3</h3>
|
* <h3>S3</h3>
|
||||||
* <p/>
|
* <p/>
|
||||||
* In Amazon S3, the EU (Ireland) Region provides read-after-write consistency for PUTS of new
|
* In Amazon S3, the EU (Ireland) Region provides read-after-write
|
||||||
* objects in your Amazon S3 bucket and eventual consistency for overwrite PUTS and DELETES.
|
* consistency for PUTS of new objects in your Amazon S3 bucket and eventual
|
||||||
|
* consistency for overwrite PUTS and DELETES.
|
||||||
*/
|
*/
|
||||||
public static final String EU_WEST_1 = "eu-west-1";
|
public static final String EU_WEST_1 = "eu-west-1";
|
||||||
|
|
||||||
|
@ -48,11 +49,13 @@ public class Region {
|
||||||
* <p/>
|
* <p/>
|
||||||
* <h3>S3</h3>
|
* <h3>S3</h3>
|
||||||
* <p/>
|
* <p/>
|
||||||
* This is the default Region. All requests sent to s3.amazonaws.com go to this Region unless you
|
* This is the default Region. All requests sent to s3.amazonaws.com go to
|
||||||
* specify a LocationConstraint on a bucket. The US Standard Region automatically places your
|
* this Region unless you specify a LocationConstraint on a bucket. The US
|
||||||
* data in either Amazon's east or west coast data centers depending on what will provide you
|
* Standard Region automatically places your data in either Amazon's east or
|
||||||
* with the lowest latency. To use this region, do not set the LocationConstraint bucket
|
* west coast data centers depending on what will provide you with the lowest
|
||||||
* parameter. The US Standard Region provides eventual consistency for all requests.
|
* latency. To use this region, do not set the LocationConstraint bucket
|
||||||
|
* parameter. The US Standard Region provides eventual consistency for all
|
||||||
|
* requests.
|
||||||
*/
|
*/
|
||||||
public static final String US_STANDARD = "us-standard";
|
public static final String US_STANDARD = "us-standard";
|
||||||
|
|
||||||
|
@ -62,25 +65,27 @@ public class Region {
|
||||||
public static final String US_EAST_1 = "us-east-1";
|
public static final String US_EAST_1 = "us-east-1";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* US-West (Northern California) <h3>S3</h3> Uses Amazon S3 servers in Northern California
|
* US-West (Northern California) <h3>S3</h3> Uses Amazon S3 servers in
|
||||||
|
* Northern California
|
||||||
* <p/>
|
* <p/>
|
||||||
* Optionally, use the endpoint s3-us-west-1.amazonaws.com on all requests to this bucket to
|
* Optionally, use the endpoint s3-us-west-1.amazonaws.com on all requests to
|
||||||
* reduce the latency you might experience after the first hour of creating a bucket in this
|
* this bucket to reduce the latency you might experience after the first
|
||||||
* Region.
|
* hour of creating a bucket in this Region.
|
||||||
* <p/>
|
* <p/>
|
||||||
* In Amazon S3, the US-West (Northern California) Region provides read-after-write consistency
|
* In Amazon S3, the US-West (Northern California) Region provides
|
||||||
* for PUTS of new objects in your Amazon S3 bucket and eventual consistency for overwrite PUTS
|
* read-after-write consistency for PUTS of new objects in your Amazon S3
|
||||||
* and DELETES.
|
* bucket and eventual consistency for overwrite PUTS and DELETES.
|
||||||
*/
|
*/
|
||||||
public static final String US_WEST_1 = "us-west-1";
|
public static final String US_WEST_1 = "us-west-1";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Region in Singapore, launched April 28, 2010. This region improves latency for Asia-based
|
* Region in Singapore, launched April 28, 2010. This region improves latency
|
||||||
* users
|
* for Asia-based users
|
||||||
*/
|
*/
|
||||||
public static final String AP_SOUTHEAST_1 = "ap-southeast-1";
|
public static final String AP_SOUTHEAST_1 = "ap-southeast-1";
|
||||||
|
|
||||||
public static Set<String> ALL = ImmutableSet.of(EU_WEST_1, US_STANDARD, US_EAST_1, US_WEST_1,
|
public static Set<String> ALL_S3 = ImmutableSet.of("EU", US_STANDARD,
|
||||||
AP_SOUTHEAST_1);
|
US_EAST_1, US_WEST_1, AP_SOUTHEAST_1);
|
||||||
|
public static Set<String> ALL_SQS = ImmutableSet.of(EU_WEST_1, US_STANDARD,
|
||||||
|
US_EAST_1, US_WEST_1, AP_SOUTHEAST_1);
|
||||||
}
|
}
|
|
@ -41,7 +41,8 @@ import com.google.common.collect.Iterables;
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
@Singleton
|
@Singleton
|
||||||
public class CreateSecurityGroupIfNeeded implements Function<RegionNameAndIngressRules, String> {
|
public class CreateSecurityGroupIfNeeded implements
|
||||||
|
Function<RegionNameAndIngressRules, String> {
|
||||||
@Resource
|
@Resource
|
||||||
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
||||||
protected Logger logger = Logger.NULL;
|
protected Logger logger = Logger.NULL;
|
||||||
|
@ -54,16 +55,20 @@ public class CreateSecurityGroupIfNeeded implements Function<RegionNameAndIngres
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String apply(RegionNameAndIngressRules from) {
|
public String apply(RegionNameAndIngressRules from) {
|
||||||
createSecurityGroupInRegion(from.getRegion(), from.getName(), from.getPorts());
|
createSecurityGroupInRegion(from.getRegion(), from.getName(), from
|
||||||
|
.getPorts());
|
||||||
return from.getName();
|
return from.getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createSecurityGroupInRegion(String region, String name, int... ports) {
|
private void createSecurityGroupInRegion(String region, String name,
|
||||||
|
int... ports) {
|
||||||
checkNotNull(region, "region");
|
checkNotNull(region, "region");
|
||||||
checkNotNull(name, "name");
|
checkNotNull(name, "name");
|
||||||
logger.debug(">> creating securityGroup region(%s) name(%s)", region, name);
|
logger.debug(">> creating securityGroup region(%s) name(%s)", region,
|
||||||
|
name);
|
||||||
try {
|
try {
|
||||||
ec2Client.getSecurityGroupServices().createSecurityGroupInRegion(region, name, name);
|
ec2Client.getSecurityGroupServices().createSecurityGroupInRegion(
|
||||||
|
region, name, name);
|
||||||
logger.debug("<< created securityGroup(%s)", name);
|
logger.debug("<< created securityGroup(%s)", name);
|
||||||
for (int port : ports) {
|
for (int port : ports) {
|
||||||
createIngressRuleForTCPPort(region, name, port);
|
createIngressRuleForTCPPort(region, name, port);
|
||||||
|
@ -72,7 +77,8 @@ public class CreateSecurityGroupIfNeeded implements Function<RegionNameAndIngres
|
||||||
authorizeGroupToItself(region, name);
|
authorizeGroupToItself(region, name);
|
||||||
}
|
}
|
||||||
} catch (AWSResponseException e) {
|
} catch (AWSResponseException e) {
|
||||||
if (e.getError().getCode().equals("InvalidGroup.Duplicate")) {
|
if (e.getError().getCode().equals("InvalidGroup.Duplicate")
|
||||||
|
|| e.getError().getMessage().endsWith("already exists")) {
|
||||||
logger.debug("<< reused securityGroup(%s)", name);
|
logger.debug("<< reused securityGroup(%s)", name);
|
||||||
} else {
|
} else {
|
||||||
throw e;
|
throw e;
|
||||||
|
@ -81,20 +87,25 @@ public class CreateSecurityGroupIfNeeded implements Function<RegionNameAndIngres
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createIngressRuleForTCPPort(String region, String name, int port) {
|
private void createIngressRuleForTCPPort(String region, String name, int port) {
|
||||||
logger.debug(">> authorizing securityGroup region(%s) name(%s) port(%s)", region, name, port);
|
logger.debug(">> authorizing securityGroup region(%s) name(%s) port(%s)",
|
||||||
ec2Client.getSecurityGroupServices().authorizeSecurityGroupIngressInRegion(region, name,
|
region, name, port);
|
||||||
IpProtocol.TCP, port, port, "0.0.0.0/0");
|
ec2Client.getSecurityGroupServices()
|
||||||
|
.authorizeSecurityGroupIngressInRegion(region, name,
|
||||||
|
IpProtocol.TCP, port, port, "0.0.0.0/0");
|
||||||
logger.debug("<< authorized securityGroup(%s)", name);
|
logger.debug("<< authorized securityGroup(%s)", name);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void authorizeGroupToItself(String region, String name) {
|
private void authorizeGroupToItself(String region, String name) {
|
||||||
logger.debug(">> authorizing securityGroup region(%s) name(%s) permission to itself", region,
|
logger
|
||||||
name);
|
.debug(
|
||||||
|
">> authorizing securityGroup region(%s) name(%s) permission to itself",
|
||||||
|
region, name);
|
||||||
String myOwnerId = Iterables.get(
|
String myOwnerId = Iterables.get(
|
||||||
ec2Client.getSecurityGroupServices().describeSecurityGroupsInRegion(region), 0)
|
ec2Client.getSecurityGroupServices()
|
||||||
.getOwnerId();
|
.describeSecurityGroupsInRegion(region), 0).getOwnerId();
|
||||||
ec2Client.getSecurityGroupServices().authorizeSecurityGroupIngressInRegion(region, name,
|
ec2Client.getSecurityGroupServices()
|
||||||
new UserIdGroupPair(myOwnerId, name));
|
.authorizeSecurityGroupIngressInRegion(region, name,
|
||||||
|
new UserIdGroupPair(myOwnerId, name));
|
||||||
logger.debug("<< authorized securityGroup(%s)", name);
|
logger.debug("<< authorized securityGroup(%s)", name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
package org.jclouds.aws.s3;
|
||||||
|
|
||||||
|
import static org.jclouds.aws.s3.reference.S3Constants.PROPERTY_S3_AUTH_TAG;
|
||||||
|
import static org.jclouds.aws.s3.reference.S3Constants.PROPERTY_S3_DEFAULT_REGIONS;
|
||||||
|
import static org.jclouds.aws.s3.reference.S3Constants.PROPERTY_S3_ENDPOINT;
|
||||||
|
import static org.jclouds.aws.s3.reference.S3Constants.PROPERTY_S3_HEADER_TAG;
|
||||||
|
import static org.jclouds.aws.s3.reference.S3Constants.PROPERTY_S3_REGIONS;
|
||||||
|
import static org.jclouds.aws.s3.reference.S3Constants.PROPERTY_S3_SERVICE_EXPR;
|
||||||
|
import static org.jclouds.blobstore.reference.BlobStoreConstants.PROPERTY_USER_METADATA_PREFIX;
|
||||||
|
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builds properties used in Walrus Clients
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
public class GoogleStoragePropertiesBuilder extends S3PropertiesBuilder {
|
||||||
|
@Override
|
||||||
|
protected Properties defaultProperties() {
|
||||||
|
Properties properties = super.defaultProperties();
|
||||||
|
properties.setProperty(PROPERTY_USER_METADATA_PREFIX, "x-goog-meta-");
|
||||||
|
properties.setProperty(PROPERTY_S3_AUTH_TAG, "GOOG1");
|
||||||
|
properties.setProperty(PROPERTY_S3_HEADER_TAG, "goog");
|
||||||
|
properties.setProperty(PROPERTY_S3_SERVICE_EXPR,
|
||||||
|
"\\.commondatastorage\\.googleapis\\.com");
|
||||||
|
return properties;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Properties addEndpoints(Properties properties) {
|
||||||
|
properties.setProperty(PROPERTY_S3_REGIONS, "GoogleStorage");
|
||||||
|
properties.setProperty(PROPERTY_S3_DEFAULT_REGIONS, "GoogleStorage");
|
||||||
|
properties.setProperty(PROPERTY_S3_ENDPOINT,
|
||||||
|
"https://commondatastorage.googleapis.com");
|
||||||
|
properties.setProperty(PROPERTY_S3_ENDPOINT + ".GoogleStorage",
|
||||||
|
"https://commondatastorage.googleapis.com");
|
||||||
|
return properties;
|
||||||
|
}
|
||||||
|
|
||||||
|
public GoogleStoragePropertiesBuilder(Properties properties) {
|
||||||
|
super(properties);
|
||||||
|
}
|
||||||
|
|
||||||
|
public GoogleStoragePropertiesBuilder(String id, String secret) {
|
||||||
|
super(id, secret);
|
||||||
|
}
|
||||||
|
}
|
|
@ -22,8 +22,12 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
import static org.jclouds.Constants.PROPERTY_RELAX_HOSTNAME;
|
import static org.jclouds.Constants.PROPERTY_RELAX_HOSTNAME;
|
||||||
import static org.jclouds.aws.reference.AWSConstants.PROPERTY_AWS_ACCESSKEYID;
|
import static org.jclouds.aws.reference.AWSConstants.PROPERTY_AWS_ACCESSKEYID;
|
||||||
import static org.jclouds.aws.reference.AWSConstants.PROPERTY_AWS_SECRETACCESSKEY;
|
import static org.jclouds.aws.reference.AWSConstants.PROPERTY_AWS_SECRETACCESSKEY;
|
||||||
|
import static org.jclouds.aws.s3.reference.S3Constants.PROPERTY_S3_AUTH_TAG;
|
||||||
|
import static org.jclouds.aws.s3.reference.S3Constants.PROPERTY_S3_DEFAULT_REGIONS;
|
||||||
import static org.jclouds.aws.s3.reference.S3Constants.PROPERTY_S3_ENDPOINT;
|
import static org.jclouds.aws.s3.reference.S3Constants.PROPERTY_S3_ENDPOINT;
|
||||||
|
import static org.jclouds.aws.s3.reference.S3Constants.PROPERTY_S3_HEADER_TAG;
|
||||||
import static org.jclouds.aws.s3.reference.S3Constants.PROPERTY_S3_REGIONS;
|
import static org.jclouds.aws.s3.reference.S3Constants.PROPERTY_S3_REGIONS;
|
||||||
|
import static org.jclouds.aws.s3.reference.S3Constants.PROPERTY_S3_SERVICE_EXPR;
|
||||||
import static org.jclouds.aws.s3.reference.S3Constants.PROPERTY_S3_SESSIONINTERVAL;
|
import static org.jclouds.aws.s3.reference.S3Constants.PROPERTY_S3_SESSIONINTERVAL;
|
||||||
import static org.jclouds.blobstore.reference.BlobStoreConstants.DIRECTORY_SUFFIX_FOLDER;
|
import static org.jclouds.blobstore.reference.BlobStoreConstants.DIRECTORY_SUFFIX_FOLDER;
|
||||||
import static org.jclouds.blobstore.reference.BlobStoreConstants.PROPERTY_BLOBSTORE_DIRECTORY_SUFFIX;
|
import static org.jclouds.blobstore.reference.BlobStoreConstants.PROPERTY_BLOBSTORE_DIRECTORY_SUFFIX;
|
||||||
|
@ -47,26 +51,34 @@ public class S3PropertiesBuilder extends PropertiesBuilder {
|
||||||
@Override
|
@Override
|
||||||
protected Properties defaultProperties() {
|
protected Properties defaultProperties() {
|
||||||
Properties properties = super.defaultProperties();
|
Properties properties = super.defaultProperties();
|
||||||
properties.setProperty(PROPERTY_RELAX_HOSTNAME, "true");
|
|
||||||
properties.setProperty(PROPERTY_USER_METADATA_PREFIX, "x-amz-meta-");
|
properties.setProperty(PROPERTY_USER_METADATA_PREFIX, "x-amz-meta-");
|
||||||
addEndpointProperties(properties);
|
properties.setProperty(PROPERTY_S3_AUTH_TAG, "AWS");
|
||||||
|
properties.setProperty(PROPERTY_S3_HEADER_TAG, "aws");
|
||||||
|
properties.setProperty(PROPERTY_S3_SERVICE_EXPR,
|
||||||
|
"\\.s3[^.]*\\.amazonaws\\.com");
|
||||||
|
properties.setProperty(PROPERTY_RELAX_HOSTNAME, "true");
|
||||||
|
addEndpoints(properties);
|
||||||
properties.setProperty(PROPERTY_S3_SESSIONINTERVAL, "60");
|
properties.setProperty(PROPERTY_S3_SESSIONINTERVAL, "60");
|
||||||
properties.setProperty(PROPERTY_BLOBSTORE_DIRECTORY_SUFFIX,
|
properties.setProperty(PROPERTY_BLOBSTORE_DIRECTORY_SUFFIX,
|
||||||
DIRECTORY_SUFFIX_FOLDER);
|
DIRECTORY_SUFFIX_FOLDER);
|
||||||
|
|
||||||
return properties;
|
return properties;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Properties addEndpointProperties(Properties properties) {
|
protected Properties addEndpoints(Properties properties) {
|
||||||
properties.setProperty(PROPERTY_S3_REGIONS, Joiner.on(',').join(
|
properties.setProperty(PROPERTY_S3_REGIONS, Joiner.on(',').join(
|
||||||
Region.US_STANDARD, Region.US_WEST_1, Region.EU_WEST_1,
|
Region.US_STANDARD, Region.US_EAST_1, Region.US_WEST_1, "EU",
|
||||||
Region.AP_SOUTHEAST_1));
|
Region.AP_SOUTHEAST_1));
|
||||||
|
properties.setProperty(PROPERTY_S3_DEFAULT_REGIONS, Joiner.on(',').join(
|
||||||
|
Region.US_STANDARD, Region.US_EAST_1));
|
||||||
properties.setProperty(PROPERTY_S3_ENDPOINT, "https://s3.amazonaws.com");
|
properties.setProperty(PROPERTY_S3_ENDPOINT, "https://s3.amazonaws.com");
|
||||||
properties.setProperty(PROPERTY_S3_ENDPOINT + "." + Region.US_STANDARD,
|
properties.setProperty(PROPERTY_S3_ENDPOINT + "." + Region.US_STANDARD,
|
||||||
"https://s3.amazonaws.com");
|
"https://s3.amazonaws.com");
|
||||||
|
properties.setProperty(PROPERTY_S3_ENDPOINT + "." + Region.US_EAST_1,
|
||||||
|
"https://s3.amazonaws.com");
|
||||||
properties.setProperty(PROPERTY_S3_ENDPOINT + "." + Region.US_WEST_1,
|
properties.setProperty(PROPERTY_S3_ENDPOINT + "." + Region.US_WEST_1,
|
||||||
"https://s3-us-west-1.amazonaws.com");
|
"https://s3-us-west-1.amazonaws.com");
|
||||||
properties.setProperty(PROPERTY_S3_ENDPOINT + "." + Region.EU_WEST_1,
|
properties.setProperty(PROPERTY_S3_ENDPOINT + "." + "EU",
|
||||||
"https://s3-eu-west-1.amazonaws.com");
|
"https://s3-eu-west-1.amazonaws.com");
|
||||||
properties.setProperty(
|
properties.setProperty(
|
||||||
PROPERTY_S3_ENDPOINT + "." + Region.AP_SOUTHEAST_1,
|
PROPERTY_S3_ENDPOINT + "." + Region.AP_SOUTHEAST_1,
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package org.jclouds.aws.s3;
|
package org.jclouds.aws.s3;
|
||||||
|
|
||||||
|
import static org.jclouds.aws.s3.reference.S3Constants.PROPERTY_S3_DEFAULT_REGIONS;
|
||||||
import static org.jclouds.aws.s3.reference.S3Constants.PROPERTY_S3_ENDPOINT;
|
import static org.jclouds.aws.s3.reference.S3Constants.PROPERTY_S3_ENDPOINT;
|
||||||
import static org.jclouds.aws.s3.reference.S3Constants.PROPERTY_S3_REGIONS;
|
import static org.jclouds.aws.s3.reference.S3Constants.PROPERTY_S3_REGIONS;
|
||||||
|
|
||||||
|
@ -12,8 +13,9 @@ import java.util.Properties;
|
||||||
*/
|
*/
|
||||||
public class WalrusPropertiesBuilder extends S3PropertiesBuilder {
|
public class WalrusPropertiesBuilder extends S3PropertiesBuilder {
|
||||||
@Override
|
@Override
|
||||||
protected Properties addEndpointProperties(Properties properties) {
|
protected Properties addEndpoints(Properties properties) {
|
||||||
properties.setProperty(PROPERTY_S3_REGIONS, "Walrus");
|
properties.setProperty(PROPERTY_S3_REGIONS, "Walrus");
|
||||||
|
properties.setProperty(PROPERTY_S3_DEFAULT_REGIONS, "Walrus");
|
||||||
properties.setProperty(PROPERTY_S3_ENDPOINT,
|
properties.setProperty(PROPERTY_S3_ENDPOINT,
|
||||||
"http://173.205.188.130:8773/services/Walrus");
|
"http://173.205.188.130:8773/services/Walrus");
|
||||||
properties.setProperty(PROPERTY_S3_ENDPOINT + ".Walrus",
|
properties.setProperty(PROPERTY_S3_ENDPOINT + ".Walrus",
|
||||||
|
|
|
@ -43,8 +43,10 @@ import com.google.common.collect.Iterables;
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
@Singleton
|
@Singleton
|
||||||
public class BucketToResourceMetadata implements Function<BucketMetadata, StorageMetadata> {
|
public class BucketToResourceMetadata implements
|
||||||
|
Function<BucketMetadata, StorageMetadata> {
|
||||||
private final S3Client client;
|
private final S3Client client;
|
||||||
|
private final Location onlyLocation;
|
||||||
private final Set<? extends Location> locations;
|
private final Set<? extends Location> locations;
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
|
@ -53,6 +55,8 @@ public class BucketToResourceMetadata implements Function<BucketMetadata, Storag
|
||||||
@Inject
|
@Inject
|
||||||
BucketToResourceMetadata(S3Client client, Set<? extends Location> locations) {
|
BucketToResourceMetadata(S3Client client, Set<? extends Location> locations) {
|
||||||
this.client = client;
|
this.client = client;
|
||||||
|
this.onlyLocation = locations.size() == 1 ? Iterables.get(locations, 0)
|
||||||
|
: null;
|
||||||
this.locations = locations;
|
this.locations = locations;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,29 +64,37 @@ public class BucketToResourceMetadata implements Function<BucketMetadata, Storag
|
||||||
MutableStorageMetadata to = new MutableStorageMetadataImpl();
|
MutableStorageMetadata to = new MutableStorageMetadataImpl();
|
||||||
to.setName(from.getName());
|
to.setName(from.getName());
|
||||||
to.setType(StorageType.CONTAINER);
|
to.setType(StorageType.CONTAINER);
|
||||||
|
to.setLocation(onlyLocation != null ? onlyLocation : getLocation(from));
|
||||||
|
return to;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Location getLocation(BucketMetadata from) {
|
||||||
try {
|
try {
|
||||||
final String region = client.getBucketLocation(from.getName());
|
final String region = client.getBucketLocation(from.getName());
|
||||||
if (region != null) {
|
if (region != null) {
|
||||||
try {
|
try {
|
||||||
to.setLocation(Iterables.find(locations, new Predicate<Location>() {
|
return Iterables.find(locations, new Predicate<Location>() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(Location input) {
|
public boolean apply(Location input) {
|
||||||
return input.getId().equals(region.toString());
|
return input.getId().equals(region.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
}));
|
});
|
||||||
} catch (NoSuchElementException e) {
|
} catch (NoSuchElementException e) {
|
||||||
logger.error("could not get location for region %s in %s", region, locations);
|
logger.error("could not get location for region %s in %s",
|
||||||
|
region, locations);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
logger.error("could not get region for %s", from.getName());
|
logger.error("could not get region for %s", from.getName());
|
||||||
}
|
}
|
||||||
} catch (ContainerNotFoundException e) {
|
} catch (ContainerNotFoundException e) {
|
||||||
logger.error(e,
|
logger
|
||||||
"could not get region for %s, as service suggests the bucket doesn't exist", from
|
.error(
|
||||||
.getName());
|
e,
|
||||||
|
"could not get region for %s, as service suggests the bucket doesn't exist",
|
||||||
|
from.getName());
|
||||||
}
|
}
|
||||||
return to;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -21,6 +21,7 @@ package org.jclouds.aws.s3.config;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.Map.Entry;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import javax.inject.Named;
|
import javax.inject.Named;
|
||||||
|
@ -47,9 +48,10 @@ import org.jclouds.rest.ConfiguresRestClient;
|
||||||
import org.jclouds.rest.RequestSigner;
|
import org.jclouds.rest.RequestSigner;
|
||||||
import org.jclouds.rest.config.RestClientModule;
|
import org.jclouds.rest.config.RestClientModule;
|
||||||
|
|
||||||
|
import com.google.common.base.Predicate;
|
||||||
import com.google.common.base.Splitter;
|
import com.google.common.base.Splitter;
|
||||||
import com.google.common.base.Supplier;
|
import com.google.common.base.Supplier;
|
||||||
import com.google.common.collect.ImmutableBiMap;
|
import com.google.common.collect.Iterables;
|
||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
import com.google.inject.Injector;
|
import com.google.inject.Injector;
|
||||||
import com.google.inject.Key;
|
import com.google.inject.Key;
|
||||||
|
@ -137,9 +139,16 @@ public class S3RestClientModule extends
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
@S3
|
@S3
|
||||||
String getDefaultRegion(@S3 URI uri, @S3 Map<String, URI> map) {
|
String getDefaultRegion(@S3 final URI uri, @S3 Map<String, URI> map) {
|
||||||
return ImmutableBiMap.<String, URI> builder().putAll(map).build()
|
return Iterables.find(map.entrySet(),
|
||||||
.inverse().get(uri);
|
new Predicate<Entry<String, URI>>() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean apply(Entry<String, URI> input) {
|
||||||
|
return input.getValue().equals(uri);
|
||||||
|
}
|
||||||
|
|
||||||
|
}).getKey();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -52,17 +52,20 @@ import com.google.common.collect.ImmutableSet;
|
||||||
/**
|
/**
|
||||||
* Signs the S3 request.
|
* Signs the S3 request.
|
||||||
*
|
*
|
||||||
* @see <a href= "http://docs.amazonwebservices.com/AmazonS3/latest/RESTAuthentication.html" />
|
* @see <a href=
|
||||||
|
* "http://docs.amazonwebservices.com/AmazonS3/latest/RESTAuthentication.html"
|
||||||
|
* />
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@Singleton
|
@Singleton
|
||||||
public class RequestAuthorizeSignature implements HttpRequestFilter, RequestSigner {
|
public class RequestAuthorizeSignature implements HttpRequestFilter,
|
||||||
|
RequestSigner {
|
||||||
private final String[] firstHeadersToSign = new String[] { "Content-MD5",
|
private final String[] firstHeadersToSign = new String[] { "Content-MD5",
|
||||||
HttpHeaders.CONTENT_TYPE, HttpHeaders.DATE };
|
HttpHeaders.CONTENT_TYPE, HttpHeaders.DATE };
|
||||||
|
|
||||||
public static Set<String> SPECIAL_QUERIES = ImmutableSet.of("acl", "torrent", "logging",
|
public static Set<String> SPECIAL_QUERIES = ImmutableSet.of("acl",
|
||||||
"location", "requestPayment");
|
"torrent", "logging", "location", "requestPayment");
|
||||||
private final SignatureWire signatureWire;
|
private final SignatureWire signatureWire;
|
||||||
private final String accessKey;
|
private final String accessKey;
|
||||||
private final String secretKey;
|
private final String secretKey;
|
||||||
|
@ -73,11 +76,22 @@ public class RequestAuthorizeSignature implements HttpRequestFilter, RequestSign
|
||||||
@Named(Constants.LOGGER_SIGNATURE)
|
@Named(Constants.LOGGER_SIGNATURE)
|
||||||
Logger signatureLog = Logger.NULL;
|
Logger signatureLog = Logger.NULL;
|
||||||
|
|
||||||
|
private final String authTag;
|
||||||
|
private final String headerTag;
|
||||||
|
private final String srvExpr;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public RequestAuthorizeSignature(SignatureWire signatureWire,
|
public RequestAuthorizeSignature(SignatureWire signatureWire,
|
||||||
@Named(S3Constants.PROPERTY_AWS_ACCESSKEYID) String accessKey,
|
@Named(S3Constants.PROPERTY_S3_AUTH_TAG) String authTag,
|
||||||
@Named(S3Constants.PROPERTY_AWS_SECRETACCESSKEY) String secretKey,
|
@Named(S3Constants.PROPERTY_S3_SERVICE_EXPR) String srvExpr,
|
||||||
@TimeStamp Provider<String> timeStampProvider, EncryptionService encryptionService) {
|
@Named(S3Constants.PROPERTY_S3_HEADER_TAG) String headerTag,
|
||||||
|
@Named(S3Constants.PROPERTY_AWS_ACCESSKEYID) String accessKey,
|
||||||
|
@Named(S3Constants.PROPERTY_AWS_SECRETACCESSKEY) String secretKey,
|
||||||
|
@TimeStamp Provider<String> timeStampProvider,
|
||||||
|
EncryptionService encryptionService) {
|
||||||
|
this.srvExpr = srvExpr;
|
||||||
|
this.headerTag = headerTag;
|
||||||
|
this.authTag = authTag;
|
||||||
this.signatureWire = signatureWire;
|
this.signatureWire = signatureWire;
|
||||||
this.accessKey = accessKey;
|
this.accessKey = accessKey;
|
||||||
this.secretKey = secretKey;
|
this.secretKey = secretKey;
|
||||||
|
@ -107,18 +121,21 @@ public class RequestAuthorizeSignature implements HttpRequestFilter, RequestSign
|
||||||
}
|
}
|
||||||
|
|
||||||
private void calculateAndReplaceAuthHeader(HttpRequest request, String toSign)
|
private void calculateAndReplaceAuthHeader(HttpRequest request, String toSign)
|
||||||
throws HttpException {
|
throws HttpException {
|
||||||
String signature = sign(toSign);
|
String signature = sign(toSign);
|
||||||
if (signatureWire.enabled())
|
if (signatureWire.enabled())
|
||||||
signatureWire.input(Utils.toInputStream(signature));
|
signatureWire.input(Utils.toInputStream(signature));
|
||||||
request.getHeaders().replaceValues(HttpHeaders.AUTHORIZATION,
|
request.getHeaders().replaceValues(
|
||||||
Collections.singletonList("AWS " + accessKey + ":" + signature));
|
HttpHeaders.AUTHORIZATION,
|
||||||
|
Collections.singletonList(authTag + " " + accessKey + ":"
|
||||||
|
+ signature));
|
||||||
}
|
}
|
||||||
|
|
||||||
public String sign(String toSign) {
|
public String sign(String toSign) {
|
||||||
String signature;
|
String signature;
|
||||||
try {
|
try {
|
||||||
signature = encryptionService.hmacSha1Base64(toSign, secretKey.getBytes());
|
signature = encryptionService.hmacSha1Base64(toSign, secretKey
|
||||||
|
.getBytes());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new HttpException("error signing request", e);
|
throw new HttpException("error signing request", e);
|
||||||
}
|
}
|
||||||
|
@ -131,16 +148,17 @@ public class RequestAuthorizeSignature implements HttpRequestFilter, RequestSign
|
||||||
|
|
||||||
private void replaceDateHeader(HttpRequest request) {
|
private void replaceDateHeader(HttpRequest request) {
|
||||||
request.getHeaders().replaceValues(HttpHeaders.DATE,
|
request.getHeaders().replaceValues(HttpHeaders.DATE,
|
||||||
Collections.singletonList(timeStampProvider.get()));
|
Collections.singletonList(timeStampProvider.get()));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void appendAmzHeaders(HttpRequest request, StringBuilder toSign) {
|
private void appendAmzHeaders(HttpRequest request, StringBuilder toSign) {
|
||||||
Set<String> headers = new TreeSet<String>(request.getHeaders().keySet());
|
Set<String> headers = new TreeSet<String>(request.getHeaders().keySet());
|
||||||
for (String header : headers) {
|
for (String header : headers) {
|
||||||
if (header.startsWith("x-amz-")) {
|
if (header.startsWith("x-" + headerTag + "-")) {
|
||||||
toSign.append(header.toLowerCase()).append(":");
|
toSign.append(header.toLowerCase()).append(":");
|
||||||
for (String value : request.getHeaders().get(header)) {
|
for (String value : request.getHeaders().get(header)) {
|
||||||
toSign.append(Utils.replaceAll(value, NEWLINE_PATTERN, "")).append(",");
|
toSign.append(Utils.replaceAll(value, NEWLINE_PATTERN, ""))
|
||||||
|
.append(",");
|
||||||
}
|
}
|
||||||
toSign.deleteCharAt(toSign.lastIndexOf(","));
|
toSign.deleteCharAt(toSign.lastIndexOf(","));
|
||||||
toSign.append("\n");
|
toSign.append("\n");
|
||||||
|
@ -150,7 +168,8 @@ public class RequestAuthorizeSignature implements HttpRequestFilter, RequestSign
|
||||||
|
|
||||||
private void appendHttpHeaders(HttpRequest request, StringBuilder toSign) {
|
private void appendHttpHeaders(HttpRequest request, StringBuilder toSign) {
|
||||||
for (String header : firstHeadersToSign)
|
for (String header : firstHeadersToSign)
|
||||||
toSign.append(valueOrEmpty(request.getHeaders().get(header))).append("\n");
|
toSign.append(valueOrEmpty(request.getHeaders().get(header))).append(
|
||||||
|
"\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
|
@ -158,9 +177,9 @@ public class RequestAuthorizeSignature implements HttpRequestFilter, RequestSign
|
||||||
String hostHeader = request.getFirstHeaderOrNull(HttpHeaders.HOST);
|
String hostHeader = request.getFirstHeaderOrNull(HttpHeaders.HOST);
|
||||||
if (hostHeader == null)
|
if (hostHeader == null)
|
||||||
hostHeader = checkNotNull(request.getEndpoint().getHost(),
|
hostHeader = checkNotNull(request.getEndpoint().getHost(),
|
||||||
"request.getEndPoint().getHost()");
|
"request.getEndPoint().getHost()");
|
||||||
if (hostHeader.endsWith(".amazonaws.com") && !hostHeader.equals("s3.amazonaws.com"))
|
if (hostHeader.matches(".*" + srvExpr))
|
||||||
toSign.append("/").append(hostHeader.substring(0, hostHeader.lastIndexOf(".s3")));
|
toSign.append("/").append(hostHeader.replaceAll(srvExpr, ""));
|
||||||
}
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
|
@ -168,7 +187,8 @@ public class RequestAuthorizeSignature implements HttpRequestFilter, RequestSign
|
||||||
|
|
||||||
toSign.append(request.getEndpoint().getRawPath());
|
toSign.append(request.getEndpoint().getRawPath());
|
||||||
|
|
||||||
// ...however, there are a few exceptions that must be included in the signed URI.
|
// ...however, there are a few exceptions that must be included in the
|
||||||
|
// signed URI.
|
||||||
if (request.getEndpoint().getQuery() != null) {
|
if (request.getEndpoint().getQuery() != null) {
|
||||||
StringBuilder paramsToSign = new StringBuilder("?");
|
StringBuilder paramsToSign = new StringBuilder("?");
|
||||||
|
|
||||||
|
@ -188,6 +208,7 @@ public class RequestAuthorizeSignature implements HttpRequestFilter, RequestSign
|
||||||
}
|
}
|
||||||
|
|
||||||
private String valueOrEmpty(Collection<String> collection) {
|
private String valueOrEmpty(Collection<String> collection) {
|
||||||
return (collection != null && collection.size() >= 1) ? collection.iterator().next() : "";
|
return (collection != null && collection.size() >= 1) ? collection
|
||||||
|
.iterator().next() : "";
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -20,19 +20,23 @@
|
||||||
package org.jclouds.aws.s3.functions;
|
package org.jclouds.aws.s3.functions;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkArgument;
|
import static com.google.common.base.Preconditions.checkArgument;
|
||||||
|
import static org.jclouds.aws.s3.reference.S3Constants.PROPERTY_S3_DEFAULT_REGIONS;
|
||||||
|
import static org.jclouds.aws.s3.reference.S3Constants.PROPERTY_S3_REGIONS;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Named;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
import org.jclouds.aws.domain.Region;
|
|
||||||
import org.jclouds.aws.s3.S3;
|
|
||||||
import org.jclouds.http.HttpRequest;
|
import org.jclouds.http.HttpRequest;
|
||||||
import org.jclouds.rest.binders.BindToStringPayload;
|
import org.jclouds.rest.binders.BindToStringPayload;
|
||||||
|
|
||||||
|
import com.google.common.base.Splitter;
|
||||||
|
import com.google.common.collect.Iterables;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Depending on your latency and legal requirements, you can specify a location constraint that will
|
* Depending on your latency and legal requirements, you can specify a location
|
||||||
* affect where your data physically resides.
|
* constraint that will affect where your data physically resides.
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*
|
*
|
||||||
|
@ -40,35 +44,36 @@ import org.jclouds.rest.binders.BindToStringPayload;
|
||||||
@Singleton
|
@Singleton
|
||||||
public class BindRegionToXmlPayload extends BindToStringPayload {
|
public class BindRegionToXmlPayload extends BindToStringPayload {
|
||||||
|
|
||||||
private final String defaultRegion;
|
private final Iterable<String> defaultRegions;
|
||||||
|
private final Iterable<String> regions;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
BindRegionToXmlPayload(@S3 String defaultRegion) {
|
BindRegionToXmlPayload(
|
||||||
this.defaultRegion = defaultRegion;
|
@Named(PROPERTY_S3_DEFAULT_REGIONS) String defaultRegions,
|
||||||
|
@Named(PROPERTY_S3_REGIONS) String regions) {
|
||||||
|
this.defaultRegions = Splitter.on(',').split(defaultRegions);
|
||||||
|
this.regions = Splitter.on(',').split(regions);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void bindToRequest(HttpRequest request, Object input) {
|
public void bindToRequest(HttpRequest request, Object input) {
|
||||||
input = input == null ? defaultRegion : input;
|
input = input == null ? Iterables.get(defaultRegions, 0) : input;
|
||||||
checkArgument(input instanceof String, "this binder is only valid for Region!");
|
checkArgument(input instanceof String,
|
||||||
|
"this binder is only valid for Region!");
|
||||||
String constraint = (String) input;
|
String constraint = (String) input;
|
||||||
String value = null;
|
String value = null;
|
||||||
if (Region.US_STANDARD.equals(constraint) || Region.US_EAST_1.equals(constraint)) {
|
if (Iterables.contains(defaultRegions, constraint)) {
|
||||||
// nothing to bind as this is default.
|
// nothing to bind as this is default.
|
||||||
return;
|
return;
|
||||||
} else if (Region.EU_WEST_1.equals(constraint))
|
} else if (Iterables.contains(regions, constraint)) {
|
||||||
value = "EU";
|
value = constraint;
|
||||||
else if (Region.US_WEST_1.equals(constraint))
|
} else {
|
||||||
value = "us-west-1";
|
throw new IllegalStateException("unimplemented location: " + constraint);
|
||||||
else if (Region.AP_SOUTHEAST_1.equals(constraint))
|
|
||||||
value = "ap-southeast-1";
|
|
||||||
else {
|
|
||||||
throw new IllegalStateException("unimplemented location: " + this);
|
|
||||||
}
|
}
|
||||||
String payload = String
|
String payload = String
|
||||||
.format(
|
.format(
|
||||||
"<CreateBucketConfiguration><LocationConstraint>%s</LocationConstraint></CreateBucketConfiguration>",
|
"<CreateBucketConfiguration><LocationConstraint>%s</LocationConstraint></CreateBucketConfiguration>",
|
||||||
value);
|
value);
|
||||||
super.bindToRequest(request, payload);
|
super.bindToRequest(request, payload);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,9 +37,14 @@ public interface S3Constants extends AWSConstants, S3Headers {
|
||||||
public static final String DELIMITER = "delimiter";
|
public static final String DELIMITER = "delimiter";
|
||||||
public static final String PROPERTY_S3_ENDPOINT = "jclouds.s3.endpoint";
|
public static final String PROPERTY_S3_ENDPOINT = "jclouds.s3.endpoint";
|
||||||
public static final String PROPERTY_S3_REGIONS = "jclouds.s3.regions";
|
public static final String PROPERTY_S3_REGIONS = "jclouds.s3.regions";
|
||||||
|
public static final String PROPERTY_S3_DEFAULT_REGIONS = "jclouds.s3.default-regions";
|
||||||
|
|
||||||
|
public static final String PROPERTY_S3_SERVICE_EXPR = "jclouds.service.expr";
|
||||||
/**
|
/**
|
||||||
* how long do we wait before obtaining a new timestamp for requests.
|
* how long do we wait before obtaining a new timestamp for requests.
|
||||||
*/
|
*/
|
||||||
public static final String PROPERTY_S3_SESSIONINTERVAL = "jclouds.s3.sessioninterval";
|
public static final String PROPERTY_S3_SESSIONINTERVAL = "jclouds.s3.sessioninterval";
|
||||||
|
public static final String PROPERTY_S3_AUTH_TAG = "jclouds.s3.auth.tag";
|
||||||
|
public static final String PROPERTY_S3_HEADER_TAG = "jclouds.s3.header.tag";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,7 +52,7 @@ public class EC2ComputeServiceLiveTest extends BaseComputeServiceLiveTest {
|
||||||
@BeforeClass
|
@BeforeClass
|
||||||
@Override
|
@Override
|
||||||
public void setServiceDefaults() {
|
public void setServiceDefaults() {
|
||||||
service = "ec2";
|
service = "eucalyptus";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -90,7 +90,7 @@ public class S3AsyncClientTest extends RestClientTest<S3AsyncClient> {
|
||||||
public void testAllRegions() throws SecurityException, NoSuchMethodException, IOException {
|
public void testAllRegions() throws SecurityException, NoSuchMethodException, IOException {
|
||||||
Method method = S3AsyncClient.class.getMethod("putBucketInRegion", String.class,
|
Method method = S3AsyncClient.class.getMethod("putBucketInRegion", String.class,
|
||||||
String.class, Array.newInstance(PutBucketOptions.class, 0).getClass());
|
String.class, Array.newInstance(PutBucketOptions.class, 0).getClass());
|
||||||
for (String region : Region.ALL) {
|
for (String region : Region.ALL_S3) {
|
||||||
processor.createRequest(method, region, "bucket-name");
|
processor.createRequest(method, region, "bucket-name");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -416,7 +416,7 @@ public class S3AsyncClientTest extends RestClientTest<S3AsyncClient> {
|
||||||
Method method = S3AsyncClient.class.getMethod("putBucketInRegion", String.class,
|
Method method = S3AsyncClient.class.getMethod("putBucketInRegion", String.class,
|
||||||
String.class, Array.newInstance(PutBucketOptions.class, 0).getClass());
|
String.class, Array.newInstance(PutBucketOptions.class, 0).getClass());
|
||||||
GeneratedHttpRequest<S3AsyncClient> httpMethod = processor.createRequest(method,
|
GeneratedHttpRequest<S3AsyncClient> httpMethod = processor.createRequest(method,
|
||||||
Region.EU_WEST_1, "bucket");
|
"EU", "bucket");
|
||||||
|
|
||||||
assertRequestLineEquals(httpMethod, "PUT https://bucket.s3.amazonaws.com/ HTTP/1.1");
|
assertRequestLineEquals(httpMethod, "PUT https://bucket.s3.amazonaws.com/ HTTP/1.1");
|
||||||
assertHeadersEqual(httpMethod,
|
assertHeadersEqual(httpMethod,
|
||||||
|
|
|
@ -53,7 +53,7 @@ public class S3StubClientModule extends RestClientModule<S3Client, S3AsyncClient
|
||||||
bind(URI.class).annotatedWith(S3.class).toInstance(URI.create("https://localhost/s3stub"));
|
bind(URI.class).annotatedWith(S3.class).toInstance(URI.create("https://localhost/s3stub"));
|
||||||
bind(String.class).annotatedWith(S3.class).toInstance(Region.US_STANDARD);
|
bind(String.class).annotatedWith(S3.class).toInstance(Region.US_STANDARD);
|
||||||
bind(new TypeLiteral<Set<String>>() {
|
bind(new TypeLiteral<Set<String>>() {
|
||||||
}).annotatedWith(S3.class).toInstance(Region.ALL);
|
}).annotatedWith(S3.class).toInstance(Region.ALL_S3);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -57,91 +57,111 @@ import com.google.inject.TypeLiteral;
|
||||||
@Test(groups = "unit", testName = "sqs.SQSAsyncClientTest")
|
@Test(groups = "unit", testName = "sqs.SQSAsyncClientTest")
|
||||||
public class SQSAsyncClientTest extends RestClientTest<SQSAsyncClient> {
|
public class SQSAsyncClientTest extends RestClientTest<SQSAsyncClient> {
|
||||||
|
|
||||||
public void testListQueuesInRegion() throws SecurityException, NoSuchMethodException,
|
public void testListQueuesInRegion() throws SecurityException,
|
||||||
IOException {
|
NoSuchMethodException, IOException {
|
||||||
Method method = SQSAsyncClient.class.getMethod("listQueuesInRegion", String.class, Array
|
Method method = SQSAsyncClient.class.getMethod("listQueuesInRegion",
|
||||||
.newInstance(ListQueuesOptions.class, 0).getClass());
|
String.class, Array.newInstance(ListQueuesOptions.class, 0)
|
||||||
GeneratedHttpRequest<SQSAsyncClient> httpMethod = processor.createRequest(method,
|
.getClass());
|
||||||
(String) null);
|
GeneratedHttpRequest<SQSAsyncClient> httpMethod = processor
|
||||||
|
.createRequest(method, (String) null);
|
||||||
|
|
||||||
assertRequestLineEquals(httpMethod, "POST https://sqs.us-east-1.amazonaws.com/ HTTP/1.1");
|
assertRequestLineEquals(httpMethod,
|
||||||
|
"POST https://sqs.us-east-1.amazonaws.com/ HTTP/1.1");
|
||||||
assertHeadersEqual(
|
assertHeadersEqual(
|
||||||
httpMethod,
|
httpMethod,
|
||||||
"Content-Length: 36\nContent-Type: application/x-www-form-urlencoded\nHost: sqs.us-east-1.amazonaws.com\n");
|
"Content-Length: 36\nContent-Type: application/x-www-form-urlencoded\nHost: sqs.us-east-1.amazonaws.com\n");
|
||||||
assertPayloadEquals(httpMethod, "Version=2009-02-01&Action=ListQueues");
|
assertPayloadEquals(httpMethod, "Version=2009-02-01&Action=ListQueues");
|
||||||
|
|
||||||
assertResponseParserClassEquals(method, httpMethod, RegexListQueuesResponseHandler.class);
|
assertResponseParserClassEquals(method, httpMethod,
|
||||||
|
RegexListQueuesResponseHandler.class);
|
||||||
assertSaxResponseParserClassEquals(method, null);
|
assertSaxResponseParserClassEquals(method, null);
|
||||||
assertExceptionParserClassEquals(method, null);
|
assertExceptionParserClassEquals(method, null);
|
||||||
|
|
||||||
checkFilters(httpMethod);
|
checkFilters(httpMethod);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testListQueuesInRegionOptions() throws SecurityException, NoSuchMethodException,
|
public void testListQueuesInRegionOptions() throws SecurityException,
|
||||||
IOException {
|
NoSuchMethodException, IOException {
|
||||||
Method method = SQSAsyncClient.class.getMethod("listQueuesInRegion", String.class, Array
|
Method method = SQSAsyncClient.class.getMethod("listQueuesInRegion",
|
||||||
.newInstance(ListQueuesOptions.class, 0).getClass());
|
String.class, Array.newInstance(ListQueuesOptions.class, 0)
|
||||||
GeneratedHttpRequest<SQSAsyncClient> httpMethod = processor.createRequest(method, null,
|
.getClass());
|
||||||
ListQueuesOptions.Builder.queuePrefix("prefix"));
|
GeneratedHttpRequest<SQSAsyncClient> httpMethod = processor
|
||||||
|
.createRequest(method, null, ListQueuesOptions.Builder
|
||||||
|
.queuePrefix("prefix"));
|
||||||
|
|
||||||
assertRequestLineEquals(httpMethod, "POST https://sqs.us-east-1.amazonaws.com/ HTTP/1.1");
|
assertRequestLineEquals(httpMethod,
|
||||||
|
"POST https://sqs.us-east-1.amazonaws.com/ HTTP/1.1");
|
||||||
assertHeadersEqual(
|
assertHeadersEqual(
|
||||||
httpMethod,
|
httpMethod,
|
||||||
"Content-Length: 59\nContent-Type: application/x-www-form-urlencoded\nHost: sqs.us-east-1.amazonaws.com\n");
|
"Content-Length: 59\nContent-Type: application/x-www-form-urlencoded\nHost: sqs.us-east-1.amazonaws.com\n");
|
||||||
assertPayloadEquals(httpMethod, "Version=2009-02-01&Action=ListQueues&QueueNamePrefix=prefix");
|
|
||||||
|
|
||||||
assertResponseParserClassEquals(method, httpMethod, RegexListQueuesResponseHandler.class);
|
|
||||||
assertSaxResponseParserClassEquals(method, null);
|
|
||||||
assertExceptionParserClassEquals(method, null);
|
|
||||||
|
|
||||||
checkFilters(httpMethod);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testCreateQueueInRegion() throws SecurityException, NoSuchMethodException,
|
|
||||||
IOException {
|
|
||||||
Method method = SQSAsyncClient.class.getMethod("createQueueInRegion", String.class,
|
|
||||||
String.class, Array.newInstance(CreateQueueOptions.class, 0).getClass());
|
|
||||||
GeneratedHttpRequest<SQSAsyncClient> httpMethod = processor.createRequest(method, null,
|
|
||||||
"queueName");
|
|
||||||
|
|
||||||
assertRequestLineEquals(httpMethod, "POST https://sqs.us-east-1.amazonaws.com/ HTTP/1.1");
|
|
||||||
assertHeadersEqual(
|
|
||||||
httpMethod,
|
|
||||||
"Content-Length: 57\nContent-Type: application/x-www-form-urlencoded\nHost: sqs.us-east-1.amazonaws.com\n");
|
|
||||||
assertPayloadEquals(httpMethod, "Version=2009-02-01&Action=CreateQueue&QueueName=queueName");
|
|
||||||
|
|
||||||
assertResponseParserClassEquals(method, httpMethod, RegexQueueHandler.class);
|
|
||||||
assertSaxResponseParserClassEquals(method, null);
|
|
||||||
assertExceptionParserClassEquals(method, null);
|
|
||||||
|
|
||||||
checkFilters(httpMethod);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testCreateQueueInRegionOptions() throws SecurityException, NoSuchMethodException,
|
|
||||||
IOException {
|
|
||||||
Method method = SQSAsyncClient.class.getMethod("createQueueInRegion", String.class,
|
|
||||||
String.class, Array.newInstance(CreateQueueOptions.class, 0).getClass());
|
|
||||||
GeneratedHttpRequest<SQSAsyncClient> httpMethod = processor.createRequest(method, null,
|
|
||||||
"queueName", CreateQueueOptions.Builder.defaultVisibilityTimeout(45));
|
|
||||||
|
|
||||||
assertRequestLineEquals(httpMethod, "POST https://sqs.us-east-1.amazonaws.com/ HTTP/1.1");
|
|
||||||
assertHeadersEqual(
|
|
||||||
httpMethod,
|
|
||||||
"Content-Length: 85\nContent-Type: application/x-www-form-urlencoded\nHost: sqs.us-east-1.amazonaws.com\n");
|
|
||||||
assertPayloadEquals(httpMethod,
|
assertPayloadEquals(httpMethod,
|
||||||
"Version=2009-02-01&Action=CreateQueue&QueueName=queueName&DefaultVisibilityTimeout=45");
|
"Version=2009-02-01&Action=ListQueues&QueueNamePrefix=prefix");
|
||||||
|
|
||||||
assertResponseParserClassEquals(method, httpMethod, RegexQueueHandler.class);
|
assertResponseParserClassEquals(method, httpMethod,
|
||||||
|
RegexListQueuesResponseHandler.class);
|
||||||
assertSaxResponseParserClassEquals(method, null);
|
assertSaxResponseParserClassEquals(method, null);
|
||||||
assertExceptionParserClassEquals(method, null);
|
assertExceptionParserClassEquals(method, null);
|
||||||
|
|
||||||
checkFilters(httpMethod);
|
checkFilters(httpMethod);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testAllRegions() throws SecurityException, NoSuchMethodException, IOException {
|
public void testCreateQueueInRegion() throws SecurityException,
|
||||||
Method method = SQSAsyncClient.class.getMethod("createQueueInRegion", String.class,
|
NoSuchMethodException, IOException {
|
||||||
String.class, Array.newInstance(CreateQueueOptions.class, 0).getClass());
|
Method method = SQSAsyncClient.class.getMethod("createQueueInRegion",
|
||||||
for (String region : Iterables.filter(Region.ALL, not(equalTo("us-standard")))) {
|
String.class, String.class, Array.newInstance(
|
||||||
|
CreateQueueOptions.class, 0).getClass());
|
||||||
|
GeneratedHttpRequest<SQSAsyncClient> httpMethod = processor
|
||||||
|
.createRequest(method, null, "queueName");
|
||||||
|
|
||||||
|
assertRequestLineEquals(httpMethod,
|
||||||
|
"POST https://sqs.us-east-1.amazonaws.com/ HTTP/1.1");
|
||||||
|
assertHeadersEqual(
|
||||||
|
httpMethod,
|
||||||
|
"Content-Length: 57\nContent-Type: application/x-www-form-urlencoded\nHost: sqs.us-east-1.amazonaws.com\n");
|
||||||
|
assertPayloadEquals(httpMethod,
|
||||||
|
"Version=2009-02-01&Action=CreateQueue&QueueName=queueName");
|
||||||
|
|
||||||
|
assertResponseParserClassEquals(method, httpMethod,
|
||||||
|
RegexQueueHandler.class);
|
||||||
|
assertSaxResponseParserClassEquals(method, null);
|
||||||
|
assertExceptionParserClassEquals(method, null);
|
||||||
|
|
||||||
|
checkFilters(httpMethod);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testCreateQueueInRegionOptions() throws SecurityException,
|
||||||
|
NoSuchMethodException, IOException {
|
||||||
|
Method method = SQSAsyncClient.class.getMethod("createQueueInRegion",
|
||||||
|
String.class, String.class, Array.newInstance(
|
||||||
|
CreateQueueOptions.class, 0).getClass());
|
||||||
|
GeneratedHttpRequest<SQSAsyncClient> httpMethod = processor
|
||||||
|
.createRequest(method, null, "queueName",
|
||||||
|
CreateQueueOptions.Builder.defaultVisibilityTimeout(45));
|
||||||
|
|
||||||
|
assertRequestLineEquals(httpMethod,
|
||||||
|
"POST https://sqs.us-east-1.amazonaws.com/ HTTP/1.1");
|
||||||
|
assertHeadersEqual(
|
||||||
|
httpMethod,
|
||||||
|
"Content-Length: 85\nContent-Type: application/x-www-form-urlencoded\nHost: sqs.us-east-1.amazonaws.com\n");
|
||||||
|
assertPayloadEquals(
|
||||||
|
httpMethod,
|
||||||
|
"Version=2009-02-01&Action=CreateQueue&QueueName=queueName&DefaultVisibilityTimeout=45");
|
||||||
|
|
||||||
|
assertResponseParserClassEquals(method, httpMethod,
|
||||||
|
RegexQueueHandler.class);
|
||||||
|
assertSaxResponseParserClassEquals(method, null);
|
||||||
|
assertExceptionParserClassEquals(method, null);
|
||||||
|
|
||||||
|
checkFilters(httpMethod);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllRegions() throws SecurityException,
|
||||||
|
NoSuchMethodException, IOException {
|
||||||
|
Method method = SQSAsyncClient.class.getMethod("createQueueInRegion",
|
||||||
|
String.class, String.class, Array.newInstance(
|
||||||
|
CreateQueueOptions.class, 0).getClass());
|
||||||
|
for (String region : Iterables.filter(Region.ALL_SQS,
|
||||||
|
not(equalTo("us-standard")))) {
|
||||||
processor.createRequest(method, region, "queueName");
|
processor.createRequest(method, region, "queueName");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -163,15 +183,16 @@ public class SQSAsyncClientTest extends RestClientTest<SQSAsyncClient> {
|
||||||
return new SQSRestClientModule() {
|
return new SQSRestClientModule() {
|
||||||
@Override
|
@Override
|
||||||
protected void configure() {
|
protected void configure() {
|
||||||
Names.bindProperties(binder(), new SQSPropertiesBuilder(new Properties())
|
Names.bindProperties(binder(), new SQSPropertiesBuilder(
|
||||||
.withCredentials("user", "key").build());
|
new Properties()).withCredentials("user", "key").build());
|
||||||
install(new NullLoggingModule());
|
install(new NullLoggingModule());
|
||||||
super.configure();
|
super.configure();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected String provideTimeStamp(final DateService dateService,
|
protected String provideTimeStamp(
|
||||||
@Named(SQSConstants.PROPERTY_AWS_EXPIREINTERVAL) final int expiration) {
|
final DateService dateService,
|
||||||
|
@Named(SQSConstants.PROPERTY_AWS_EXPIREINTERVAL) final int expiration) {
|
||||||
return "2009-11-08T15:54:08.897Z";
|
return "2009-11-08T15:54:08.897Z";
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -29,5 +29,7 @@ s3.contextbuilder=org.jclouds.aws.s3.S3ContextBuilder
|
||||||
s3.propertiesbuilder=org.jclouds.aws.s3.S3PropertiesBuilder
|
s3.propertiesbuilder=org.jclouds.aws.s3.S3PropertiesBuilder
|
||||||
walrus.contextbuilder=org.jclouds.aws.s3.S3ContextBuilder
|
walrus.contextbuilder=org.jclouds.aws.s3.S3ContextBuilder
|
||||||
walrus.propertiesbuilder=org.jclouds.aws.s3.WalrusPropertiesBuilder
|
walrus.propertiesbuilder=org.jclouds.aws.s3.WalrusPropertiesBuilder
|
||||||
|
googlestorage.contextbuilder=org.jclouds.aws.s3.S3ContextBuilder
|
||||||
|
googlestorage.propertiesbuilder=org.jclouds.aws.s3.GoogleStoragePropertiesBuilder
|
||||||
transient.contextbuilder=org.jclouds.blobstore.TransientBlobStoreContextBuilder
|
transient.contextbuilder=org.jclouds.blobstore.TransientBlobStoreContextBuilder
|
||||||
transient.propertiesbuilder=org.jclouds.blobstore.TransientBlobStorePropertiesBuilder
|
transient.propertiesbuilder=org.jclouds.blobstore.TransientBlobStorePropertiesBuilder
|
||||||
|
|
Loading…
Reference in New Issue