reorg of svn

git-svn-id: http://jclouds.googlecode.com/svn/trunk@816 3d8758e0-26b5-11de-8745-db77d3ebf521
This commit is contained in:
adrian.f.cole 2009-05-20 22:31:18 +00:00
parent 538b56972a
commit 0ad7ca2138
70 changed files with 4338 additions and 3992 deletions

View File

@ -23,87 +23,73 @@
*/
package org.jclouds.aws.s3;
import org.jclouds.aws.s3.commands.options.*;
import org.jclouds.aws.s3.domain.S3Bucket;
import org.jclouds.aws.s3.domain.S3Object;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import org.jclouds.aws.s3.commands.options.CopyObjectOptions;
import org.jclouds.aws.s3.commands.options.GetObjectOptions;
import org.jclouds.aws.s3.commands.options.ListBucketOptions;
import org.jclouds.aws.s3.commands.options.PutBucketOptions;
import org.jclouds.aws.s3.commands.options.PutObjectOptions;
import org.jclouds.aws.s3.domain.S3Bucket;
import org.jclouds.aws.s3.domain.S3Object;
/**
* Provides access to S3 via their REST API.
*
* <p/>
* All commands return a Future of the result from S3. Any exceptions incurred
* during processing will be wrapped in an {@link ExecutionException} as
* documented in {@link Future#get()}.
*
* @see <a href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/RESTAPI.html" />
*
*
* @author Adrian Cole
* @see <a href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/RESTAPI.html" />
*/
public interface S3Connection {
/**
* Retrieve a complete <code>S3Object</code>.
*
* @see GetObject
* @param bucketName
* namespace of the object you are retrieving
*
* @param key
* unique key in the s3Bucket identifying the object
*
* @param bucketName namespace of the object you are retrieving
* @param key unique key in the s3Bucket identifying the object
* @return Future reference to a fully populated S3Object including data
* stored in S3 or {@link S3Object#NOT_FOUND} if not present.
* @see org.jclouds.aws.s3.commands.GetObject
*/
Future<S3Object> getObject(String bucketName, String key);
/**
* Like {@link #getObject(String, String)} except you can use
* {@link GetObjectOptions} to control delivery.
*
* @see #getObject(String, String)
* @see GetObjectOptions
*
* @return S3Object containing data relevant to the
* <code>options</options> specified or {@link S3Object#NOT_FOUND} if not present.
*
* @throws HttpResponseException
* if the conditions requested set were not satisfied by the
* object on the server.
* @throws org.jclouds.http.HttpResponseException
* if the conditions requested set were not satisfied by the
* object on the server.
* @see #getObject(String, String)
* @see GetObjectOptions
*/
Future<S3Object> getObject(String bucketName, String key,
GetObjectOptions options);
GetObjectOptions options);
/**
* Retrieves the {@link S3Object.Metadata metadata} of the object associated
* Retrieves the {@link org.jclouds.aws.s3.domain.S3Object.Metadata metadata} of the object associated
* with the key.
*
* @see HeadObject
* @param bucketName
* namespace of the metadata you are retrieving
*
* @param key
* unique key in the s3Bucket identifying the object
*
* @param bucketName namespace of the metadata you are retrieving
* @param key unique key in the s3Bucket identifying the object
* @return metadata associated with the key or
* {@link S3Object.Metadata#NOT_FOUND} if not present;
* {@link org.jclouds.aws.s3.domain.S3Object.Metadata#NOT_FOUND} if not present;
* @see org.jclouds.aws.s3.commands.HeadObject
*/
Future<S3Object.Metadata> headObject(String bucketName, String key);
/**
* Removes the object and metadata associated with the key.
*
* @see DeleteObject
* @param bucketName
* namespace of the object you are deleting
* @param key
* unique key in the s3Bucket identifying the object
*
* @param bucketName namespace of the object you are deleting
* @param key unique key in the s3Bucket identifying the object
* @return true if deleted
* @throws HttpResponseException
* if the bucket is not available
* @throws org.jclouds.http.HttpResponseException
* if the bucket is not available
* @see org.jclouds.aws.s3.commands.DeleteObject
*/
Future<Boolean> deleteObject(String bucketName, String key);
@ -112,126 +98,117 @@ public interface S3Connection {
* <p/>
* This method will store the object with the default <code>private</code>
* acl.
*
* @see CannedAccessPolicy#PRIVATE
* @see PutObject
* @param bucketName
* namespace of the object you are storing
* @param object
* contains the data and metadata to create or overwrite
*
* @param bucketName namespace of the object you are storing
* @param object contains the data and metadata to create or overwrite
* @return MD5 hash of the content uploaded
* @see org.jclouds.aws.s3.domain.acl.CannedAccessPolicy#PRIVATE
* @see org.jclouds.aws.s3.commands.PutObject
*/
Future<byte[]> putObject(String bucketName, S3Object object);
/**
* Like {@link #putObject(String, S3Object)} except you can use
* {@link CopyObjectOptions} to specify an alternate
* {@link CannedAccessPolicy acl}, override
* {@link S3Object.Metadata#getUserMetadata() userMetadata}, or specify
* {@link org.jclouds.aws.s3.domain.acl.CannedAccessPolicy acl}, override
* {@link org.jclouds.aws.s3.domain.S3Object.Metadata#getUserMetadata() userMetadata}, or specify
* conditions for copying the object.
*
*
* @param options options for creating the object
* @throws org.jclouds.http.HttpResponseException
* if the conditions requested set are not satisfied by the
* object on the server.
* @see S3Connection#putObject(String, S3Object)
* @see PutObjectOptions
* @param options
* options for creating the object
* @throws HttpResponseException
* if the conditions requested set are not satisfied by the
* object on the server.
*/
Future<byte[]> putObject(String bucketName, S3Object object,
PutObjectOptions options);
PutObjectOptions options);
/**
* Create and name your own bucket in which to store your objects.
*
* @see PutBucket
*
* @return true, if the bucket was created or already exists
* @see org.jclouds.aws.s3.commands.PutBucket
*/
Future<Boolean> putBucketIfNotExists(String name);
/**
* Like {@link #putBucketIfNotExists(String)} except that you can use
* {@link PutBucketOptions} to create the bucket in EU. Create and name your
*
*
* @param options for creating your bucket
* @see PutBucketOptions
* @param options
* for creating your bucket
*/
Future<Boolean> putBucketIfNotExists(String name, PutBucketOptions options);
/**
* Deletes the bucket, if it is empty.
*
* @see DeleteBucket
* @param s3Bucket
* what to delete
*
* @param s3Bucket what to delete
* @return false, if the bucket was not empty and therefore not deleted
* @see org.jclouds.aws.s3.commands.DeleteBucket
*/
Future<Boolean> deleteBucketIfEmpty(String s3Bucket);
/**
* Copies one object to another bucket, retaining UserMetadata from the
* source. The destination will have a private acl.
*
* @see CopyObject
*
* @return metadata populated with lastModified and md5 of the new object
* @see org.jclouds.aws.s3.commands.CopyObject
*/
Future<S3Object.Metadata> copyObject(String sourceBucket,
String sourceObject, String destinationBucket,
String destinationObject);
String sourceObject, String destinationBucket,
String destinationObject);
/**
* Like {@link #putObject(String, S3Object)} except you can use
* {@link PutObjectOptions} to specify an alternate
* {@link CannedAccessPolicy acl}.
*
* {@link org.jclouds.aws.s3.domain.acl.CannedAccessPolicy acl}.
*
* @param options options for creating the object
* @throws org.jclouds.http.HttpResponseException
* if the conditions requested set are not satisfied by the
* object on the server.
* @see S3Connection#putObject(String, S3Object)
* @see PutObjectOptions
* @param options
* options for creating the object
* @throws HttpResponseException
* if the conditions requested set are not satisfied by the
* object on the server.
*/
Future<S3Object.Metadata> copyObject(String sourceBucket,
String sourceObject, String destinationBucket,
String destinationObject, CopyObjectOptions options);
String sourceObject, String destinationBucket,
String destinationObject, CopyObjectOptions options);
/**
* @see HeadBucket
* @see org.jclouds.aws.s3.commands.BucketExists
*/
Future<Boolean> bucketExists(String name);
/**
* Retrieve a complete <code>S3Bucket</code> listing.
*
* @see ListBucket
* @param bucketName
* namespace of the objects you wish to list
*
*
* @param bucketName namespace of the objects you wish to list
* @return Future reference to a fully populated S3Bucket including metadata
* of the S3Objects it contains or {@link S3Bucket#NOT_FOUND} if not
* present.
* @see org.jclouds.aws.s3.commands.ListBucket
*/
Future<S3Bucket> listBucket(String bucketName);
/**
* Like {@link #listBucket(String)} except you can use
* {@link ListObjectOptions} to control the amount of S3Objects to return.
*
* @see #listBucket(String)
* @see ListBucketOptions
* @return S3Bucket containing a subset of {@link S3Object.Metadata}
* {@link ListBucketOptions} to control the amount of S3Objects to return.
*
* @return S3Bucket containing a subset of {@link org.jclouds.aws.s3.domain.S3Object.Metadata}
* depending on
* <code>options</options> specified or {@link S3Bucket#NOT_FOUND} if not present.
*
* @see #listBucket(String)
* @see ListBucketOptions
*/
Future<S3Bucket> listBucket(String name, ListBucketOptions options);
/**
* @see ListOwnedBuckets
* @return list of all of the buckets owned by the authenticated sender of
* the request.
* @see org.jclouds.aws.s3.commands.ListOwnedBuckets
*/
Future<List<S3Bucket.Metadata>> listOwnedBuckets();
}

View File

@ -50,7 +50,6 @@ public interface S3Context {
* bucket.
*
* @param bucket
* @return
*/
S3InputStreamMap createInputStreamMap(String bucket);
@ -58,7 +57,6 @@ public interface S3Context {
* Creates a <code>Map<String,S3Object></code> view of the specified bucket.
*
* @param bucket
* @return
*/
S3ObjectMap createS3ObjectMap(String bucket);

View File

@ -23,28 +23,8 @@
*/
package org.jclouds.aws.s3;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.jclouds.aws.s3.reference.S3Constants.PROPERTY_AWS_ACCESSKEYID;
import static org.jclouds.aws.s3.reference.S3Constants.PROPERTY_AWS_SECRETACCESSKEY;
import static org.jclouds.command.pool.PoolConstants.PROPERTY_POOL_IO_WORKER_THREADS;
import static org.jclouds.command.pool.PoolConstants.PROPERTY_POOL_MAX_CONNECTIONS;
import static org.jclouds.command.pool.PoolConstants.PROPERTY_POOL_MAX_CONNECTION_REUSE;
import static org.jclouds.command.pool.PoolConstants.PROPERTY_POOL_MAX_SESSION_FAILURES;
import static org.jclouds.command.pool.PoolConstants.PROPERTY_POOL_REQUEST_INVOKER_THREADS;
import static org.jclouds.http.HttpConstants.PROPERTY_HTTP_ADDRESS;
import static org.jclouds.http.HttpConstants.PROPERTY_HTTP_PORT;
import static org.jclouds.http.HttpConstants.PROPERTY_HTTP_SECURE;
import java.util.List;
import java.util.Properties;
import org.jclouds.aws.s3.config.S3ContextModule;
import org.jclouds.http.config.HttpFutureCommandClientModule;
import org.jclouds.http.config.JavaUrlHttpFutureCommandClientModule;
import org.jclouds.logging.config.LoggingModule;
import org.jclouds.logging.jdk.config.JDKLoggingModule;
import com.google.common.annotations.VisibleForTesting;
import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.collect.Iterables;
@ -54,6 +34,21 @@ import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Module;
import com.google.inject.name.Names;
import org.jclouds.aws.s3.config.LiveS3ConnectionModule;
import org.jclouds.aws.s3.config.S3ConnectionModule;
import org.jclouds.aws.s3.config.S3ContextModule;
import static org.jclouds.aws.s3.reference.S3Constants.PROPERTY_AWS_ACCESSKEYID;
import static org.jclouds.aws.s3.reference.S3Constants.PROPERTY_AWS_SECRETACCESSKEY;
import org.jclouds.aws.s3.internal.LiveS3Connection;
import static org.jclouds.command.pool.PoolConstants.*;
import static org.jclouds.http.HttpConstants.*;
import org.jclouds.http.config.HttpFutureCommandClientModule;
import org.jclouds.http.config.JavaUrlHttpFutureCommandClientModule;
import org.jclouds.logging.config.LoggingModule;
import org.jclouds.logging.jdk.config.JDKLoggingModule;
import java.util.List;
import java.util.Properties;
/**
* Creates {@link S3Context} or {@link Injector} instances based on the most
@ -61,162 +56,181 @@ import com.google.inject.name.Names;
* <p/>
* Note that Threadsafe objects will be bound as singletons to the Injector or
* Context provided.
*
* <p/>
* <p/>
* If no <code>Module</code>s are specified, the default
* {@link JDKLoggingModule logging} and
* {@link JavaUrlHttpFutureCommandClientModule http transports} will be
* installed.
*
* @see S3Context
*
* @author Adrian Cole
* @see S3Context
*/
public class S3ContextFactory {
public static final Properties DEFAULT_PROPERTIES;
static {
DEFAULT_PROPERTIES = new Properties();
DEFAULT_PROPERTIES.setProperty(PROPERTY_HTTP_ADDRESS,
"s3.amazonaws.com");
DEFAULT_PROPERTIES.setProperty(PROPERTY_HTTP_PORT, "443");
DEFAULT_PROPERTIES.setProperty(PROPERTY_HTTP_SECURE, "true");
DEFAULT_PROPERTIES
.setProperty(PROPERTY_POOL_MAX_CONNECTION_REUSE, "75");
DEFAULT_PROPERTIES.setProperty(PROPERTY_POOL_MAX_SESSION_FAILURES, "2");
DEFAULT_PROPERTIES.setProperty(PROPERTY_POOL_REQUEST_INVOKER_THREADS,
"1");
DEFAULT_PROPERTIES.setProperty(PROPERTY_POOL_IO_WORKER_THREADS, "2");
DEFAULT_PROPERTIES.setProperty(PROPERTY_POOL_MAX_CONNECTIONS, "12");
DEFAULT_PROPERTIES = new Properties();
DEFAULT_PROPERTIES.setProperty(PROPERTY_HTTP_ADDRESS,
"s3.amazonaws.com");
DEFAULT_PROPERTIES.setProperty(PROPERTY_HTTP_PORT, "443");
DEFAULT_PROPERTIES.setProperty(PROPERTY_HTTP_SECURE, "true");
DEFAULT_PROPERTIES
.setProperty(PROPERTY_POOL_MAX_CONNECTION_REUSE, "75");
DEFAULT_PROPERTIES.setProperty(PROPERTY_POOL_MAX_SESSION_FAILURES, "2");
DEFAULT_PROPERTIES.setProperty(PROPERTY_POOL_REQUEST_INVOKER_THREADS,
"1");
DEFAULT_PROPERTIES.setProperty(PROPERTY_POOL_IO_WORKER_THREADS, "2");
DEFAULT_PROPERTIES.setProperty(PROPERTY_POOL_MAX_CONNECTIONS, "12");
}
public static Injector createInjector(String awsAccessKeyId,
String awsSecretAccessKey, Module... modules) {
Properties properties = new Properties(DEFAULT_PROPERTIES);
properties.setProperty(PROPERTY_AWS_ACCESSKEYID, awsAccessKeyId);
properties
.setProperty(PROPERTY_AWS_SECRETACCESSKEY, awsSecretAccessKey);
return createInjector(properties, modules);
String awsSecretAccessKey, Module... modules) {
Properties properties = new Properties(DEFAULT_PROPERTIES);
properties.setProperty(PROPERTY_AWS_ACCESSKEYID, awsAccessKeyId);
properties
.setProperty(PROPERTY_AWS_SECRETACCESSKEY, awsSecretAccessKey);
return createInjector(properties, modules);
}
public static S3Context createS3Context(String awsAccessKeyId,
String awsSecretAccessKey, Module... modules) {
return createInjector(awsAccessKeyId, awsSecretAccessKey, modules)
.getInstance(S3Context.class);
String awsSecretAccessKey, Module... modules) {
return createInjector(awsAccessKeyId, awsSecretAccessKey, modules)
.getInstance(S3Context.class);
}
public static Injector createInjector(String awsAccessKeyId,
String awsSecretAccessKey, boolean isSecure, Module... modules) {
Properties properties = new Properties(DEFAULT_PROPERTIES);
properties.setProperty(PROPERTY_AWS_ACCESSKEYID, awsAccessKeyId);
properties
.setProperty(PROPERTY_AWS_SECRETACCESSKEY, awsSecretAccessKey);
properties
.setProperty(PROPERTY_HTTP_SECURE, Boolean.toString(isSecure));
if (!isSecure)
properties.setProperty(PROPERTY_HTTP_PORT, "80");
return createInjector(properties, modules);
String awsSecretAccessKey, boolean isSecure, Module... modules) {
Properties properties = new Properties(DEFAULT_PROPERTIES);
properties.setProperty(PROPERTY_AWS_ACCESSKEYID, awsAccessKeyId);
properties
.setProperty(PROPERTY_AWS_SECRETACCESSKEY, awsSecretAccessKey);
properties
.setProperty(PROPERTY_HTTP_SECURE, Boolean.toString(isSecure));
if (!isSecure)
properties.setProperty(PROPERTY_HTTP_PORT, "80");
return createInjector(properties, modules);
}
public static S3Context createS3Context(String awsAccessKeyId,
String awsSecretAccessKey, boolean isSecure, Module... modules) {
return createInjector(awsAccessKeyId, awsSecretAccessKey, isSecure,
modules).getInstance(S3Context.class);
String awsSecretAccessKey, boolean isSecure, Module... modules) {
return createInjector(awsAccessKeyId, awsSecretAccessKey, isSecure,
modules).getInstance(S3Context.class);
}
public static Injector createInjector(String awsAccessKeyId,
String awsSecretAccessKey, boolean isSecure, String server,
Module... modules) {
Properties properties = new Properties(DEFAULT_PROPERTIES);
properties.setProperty(PROPERTY_AWS_ACCESSKEYID, awsAccessKeyId);
properties
.setProperty(PROPERTY_AWS_SECRETACCESSKEY, awsSecretAccessKey);
properties
.setProperty(PROPERTY_HTTP_SECURE, Boolean.toString(isSecure));
properties.setProperty(PROPERTY_HTTP_ADDRESS, server);
if (!isSecure)
properties.setProperty(PROPERTY_HTTP_PORT, "80");
return createInjector(properties, modules);
String awsSecretAccessKey, boolean isSecure, String server,
Module... modules) {
Properties properties = new Properties(DEFAULT_PROPERTIES);
properties.setProperty(PROPERTY_AWS_ACCESSKEYID, awsAccessKeyId);
properties
.setProperty(PROPERTY_AWS_SECRETACCESSKEY, awsSecretAccessKey);
properties
.setProperty(PROPERTY_HTTP_SECURE, Boolean.toString(isSecure));
properties.setProperty(PROPERTY_HTTP_ADDRESS, server);
if (!isSecure)
properties.setProperty(PROPERTY_HTTP_PORT, "80");
return createInjector(properties, modules);
}
public static S3Context createS3Context(String awsAccessKeyId,
String awsSecretAccessKey, boolean isSecure, String server,
Module... modules) {
return createInjector(awsAccessKeyId, awsSecretAccessKey, isSecure,
server, modules).getInstance(S3Context.class);
String awsSecretAccessKey, boolean isSecure, String server,
Module... modules) {
return createInjector(awsAccessKeyId, awsSecretAccessKey, isSecure,
server, modules).getInstance(S3Context.class);
}
public static S3Context createS3Context(String awsAccessKeyId,
String awsSecretAccessKey, boolean isSecure, String server,
int port, Module... modules) {
return createInjector(awsAccessKeyId, awsSecretAccessKey, isSecure,
server, port, modules).getInstance(S3Context.class);
String awsSecretAccessKey, boolean isSecure, String server,
int port, Module... modules) {
return createInjector(awsAccessKeyId, awsSecretAccessKey, isSecure,
server, port, modules).getInstance(S3Context.class);
}
public static Injector createInjector(String awsAccessKeyId,
String awsSecretAccessKey, boolean isSecure, String server,
int port, Module... modules) {
Properties properties = new Properties(DEFAULT_PROPERTIES);
properties.setProperty(PROPERTY_AWS_ACCESSKEYID, awsAccessKeyId);
properties
.setProperty(PROPERTY_AWS_SECRETACCESSKEY, awsSecretAccessKey);
properties
.setProperty(PROPERTY_HTTP_SECURE, Boolean.toString(isSecure));
properties.setProperty(PROPERTY_HTTP_ADDRESS, server);
properties.setProperty(PROPERTY_HTTP_PORT, port + "");
return createInjector(properties, modules);
String awsSecretAccessKey, boolean isSecure, String server,
int port, Module... modules) {
Properties properties = new Properties(DEFAULT_PROPERTIES);
properties.setProperty(PROPERTY_AWS_ACCESSKEYID, awsAccessKeyId);
properties
.setProperty(PROPERTY_AWS_SECRETACCESSKEY, awsSecretAccessKey);
properties
.setProperty(PROPERTY_HTTP_SECURE, Boolean.toString(isSecure));
properties.setProperty(PROPERTY_HTTP_ADDRESS, server);
properties.setProperty(PROPERTY_HTTP_PORT, port + "");
return createInjector(properties, modules);
}
public static S3Context createS3Context(Properties properties,
Module... modules) {
return createInjector(properties, modules).getInstance(S3Context.class);
Module... modules) {
return createInjector(properties, modules).getInstance(S3Context.class);
}
/**
* Bind the given properties and install the list of modules. If no modules
* are specified, install the default {@link JDKLoggingModule}
* {@link JavaUrlHttpFutureCommandClientModule}
*
* @param properties
* - contains constants used by jclouds
* {@link #DEFAULT_PROPERTIES}
* @param configModules
* - alternative configuration modules
*
* @param properties - contains constants used by jclouds
* {@link #DEFAULT_PROPERTIES}
* @param configModules - alternative configuration modules
*/
public static Injector createInjector(final Properties properties,
Module... configModules) {
final List<Module> modules = Lists.newArrayList(configModules);
Module... configModules) {
final List<Module> modules = Lists.newArrayList(configModules);
addLoggingModuleIfNotPresent(modules);
addLoggingModuleIfNotPresent(modules);
addHttpModuleIfNotPresent(modules);
addHttpModuleIfNeededAndNotPresent(modules);
return Guice.createInjector(new AbstractModule() {
@Override
protected void configure() {
Names.bindProperties(binder(), checkNotNull(properties,
"properties"));
for (Module module : modules)
install(module);
}
}, new S3ContextModule());
addS3ConnectionModuleIfNotPresent(modules);
return Guice.createInjector(new AbstractModule() {
@Override
protected void configure() {
Names.bindProperties(binder(), checkNotNull(properties,
"properties"));
for (Module module : modules)
install(module);
}
}, new S3ContextModule());
}
@VisibleForTesting
static void addHttpModuleIfNotPresent(final List<Module> modules) {
if (!Iterables.any(modules, new Predicate<Module>() {
public boolean apply(Module input) {
return input.getClass().isAnnotationPresent(
HttpFutureCommandClientModule.class);
}
static void addHttpModuleIfNeededAndNotPresent(final List<Module> modules) {
if (Iterables.any(modules, new Predicate<Module>() {
public boolean apply(Module input) {
return input instanceof LiveS3ConnectionModule;
}
}))
modules.add(new JavaUrlHttpFutureCommandClientModule());
}) && (!Iterables.any(modules, new Predicate<Module>() {
public boolean apply(Module input) {
return input.getClass().isAnnotationPresent(
HttpFutureCommandClientModule.class);
}
})))
modules.add(new JavaUrlHttpFutureCommandClientModule());
}
@VisibleForTesting
static void addS3ConnectionModuleIfNotPresent(final List<Module> modules) {
if (!Iterables.any(modules, new Predicate<Module>() {
public boolean apply(Module input) {
return input.getClass().isAnnotationPresent(
S3ConnectionModule
.class);
}
})){
modules.add(new LiveS3ConnectionModule());
}
}
@VisibleForTesting
static void addLoggingModuleIfNotPresent(final List<Module> modules) {
if (!Iterables.any(modules, Predicates.instanceOf(LoggingModule.class)))
modules.add(new JDKLoggingModule());
if (!Iterables.any(modules, Predicates.instanceOf(LoggingModule.class)))
modules.add(new JDKLoggingModule());
}
}

View File

@ -28,17 +28,16 @@ import java.io.InputStream;
import java.util.Map;
/**
* Map view of an {@link S3Bucket}. Provides additional methods for inserting
* Map view of an {@link org.jclouds.aws.s3.domain.S3Bucket}. Provides additional methods for inserting
* common object types.
*
* <p/>
* <h2>Note</h2> All <code>put</code> operations will invoke
* {@link S3Object#generateMd5}. By extension, {@link #put(String, InputStream)}
* {@link org.jclouds.aws.s3.domain.S3Object#generateMd5}. By extension, {@link #put(Object, Object)}
* will result in the InputStream being converted to a byte array. For this
* reason, do not use {@link #put(String, InputStream)} to store files. Use
* reason, do not use {@link #put(Object, Object)} to store files. Use
* {@link #putFile(String, File)} or {@link S3ObjectMap} instead.
*
*
* @author Adrian Cole
*
*/
public interface S3InputStreamMap extends S3Map<String, InputStream> {
InputStream putString(String key, String value);

View File

@ -33,7 +33,7 @@ import org.jclouds.http.HttpResponseException;
*
* @see <a href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/UsingRESTError.html" />
* @see S3Error
* @see ParseS3ErrorFromXmlContent
* @see org.jclouds.aws.s3.handlers.ParseS3ErrorFromXmlContent
* @author Adrian Cole
*
*/

View File

@ -23,12 +23,10 @@
*/
package org.jclouds.aws.s3.commands.options;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
import java.io.UnsupportedEncodingException;
import com.google.common.base.Preconditions;
import static com.google.common.base.Preconditions.*;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;
import org.jclouds.aws.s3.domain.acl.CannedAccessPolicy;
import org.jclouds.aws.s3.reference.S3Headers;
import org.jclouds.aws.s3.util.DateService;
@ -36,9 +34,7 @@ import org.jclouds.aws.s3.util.S3Utils;
import org.jclouds.http.options.BaseHttpRequestOptions;
import org.joda.time.DateTime;
import com.google.common.base.Preconditions;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;
import java.io.UnsupportedEncodingException;
/**
* Contains options supported in the REST API for the COPY object operation.
@ -49,26 +45,24 @@ import com.google.common.collect.Multimap;
* <p/>
* <code>
* import static org.jclouds.aws.s3.commands.options.CopyObjectOptions.Builder.*
*
* <p/>
* S3Connection connection = // get connection
*
* <p/>
* Multimap<String,String> metadata = HashMultimap.create();
* metadata.put("x-amz-meta-adrian", "foo");
*
* <p/>
* // this will copy the object, provided it wasn't modified since yesterday.
* // it will not use metadata from the source, and instead use what we pass in.
* Future<S3Object.Metadata> object = connection.copyObject("sourceBucket", "objectName",
* "destinationBucket", "destinationName",
* overrideMetadataWith(meta).
* ifSourceModifiedSince(new DateTime().minusDays(1))
* );
* "destinationBucket", "destinationName",
* overrideMetadataWith(meta).
* ifSourceModifiedSince(new DateTime().minusDays(1))
* );
* <code>
*
*
* @author Adrian Cole
* @see <a href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?RESTObjectCOPY.html?"
* />
* @author Adrian Cole
*
*
*/
public class CopyObjectOptions extends BaseHttpRequestOptions {
private final static DateService dateService = new DateService();
@ -81,257 +75,253 @@ public class CopyObjectOptions extends BaseHttpRequestOptions {
/**
* Override the default ACL (private) with the specified one.
*
*
* @see CannedAccessPolicy
*/
public CopyObjectOptions overrideAcl(CannedAccessPolicy acl) {
this.acl = checkNotNull(acl, "acl");
if (!acl.equals(CannedAccessPolicy.PRIVATE))
this.replaceHeader(S3Headers.CANNED_ACL, acl.toString());
return this;
this.acl = checkNotNull(acl, "acl");
if (!acl.equals(CannedAccessPolicy.PRIVATE))
this.replaceHeader(S3Headers.CANNED_ACL, acl.toString());
return this;
}
/**
* @see CopyObjectOptions#overrideAcl(CannedAccessPolicy)
*/
public CannedAccessPolicy getAcl() {
return acl;
return acl;
}
/**
* For use in the header x-amz-copy-source-if-unmodified-since
* <p />
* <p/>
* Copies the object if it hasn't been modified since the specified time;
* otherwise returns a 412 (precondition failed).
* <p />
* <p/>
* This header can be used with x-amz-copy-source-if-match, but cannot be
* used with other conditional copy headers.
*
* @see <a href="http://rfc.net/rfc2616.html?s3.3"/>
*
* @return valid HTTP date
* @see <a href="http://rfc.net/rfc2616.html?s3.3"/>
* @see CopyObjectOptions#ifSourceModifiedSince(DateTime)
*/
public String getIfModifiedSince() {
return getFirstHeaderOrNull("x-amz-copy-source-if-modified-since");
return getFirstHeaderOrNull("x-amz-copy-source-if-modified-since");
}
/**
* For use in the header x-amz-copy-source-if-modified-since
* <p />
* <p/>
* Copies the object if it has been modified since the specified time;
* otherwise returns a 412 (failed condition).
* <p/>
* This header can be used with x-amz-copy-source-if-none-match, but cannot
* be used with other conditional copy headers.
*
* @see <a href="http://rfc.net/rfc2616.html?s3.3"/>
*
* @return valid HTTP date
* @see <a href="http://rfc.net/rfc2616.html?s3.3"/>
* @see CopyObjectOptions#ifSourceUnmodifiedSince(DateTime)
*/
public String getIfUnmodifiedSince() {
return getFirstHeaderOrNull("x-amz-copy-source-if-unmodified-since");
return getFirstHeaderOrNull("x-amz-copy-source-if-unmodified-since");
}
/**
* For use in the request header: x-amz-copy-source-if-match
* <p />
* <p/>
* Copies the object if its entity tag (ETag) matches the specified tag;
* otherwise return a 412 (precondition failed).
* <p/>
* This header can be used with x-amz-copy-source-if-unmodified-since, but
* cannot be used with other conditional copy headers.
*
*
* @see CopyObjectOptions#ifSourceMd5Matches(byte[])
*/
public String getIfMatch() {
return getFirstHeaderOrNull("x-amz-copy-source-if-match");
return getFirstHeaderOrNull("x-amz-copy-source-if-match");
}
/**
* For use in the request header: x-amz-copy-source-if-none-match
* <p />
* <p/>
* Copies the object if its entity tag (ETag) is different than the
* specified Etag; otherwise returns a 412 (failed condition).
* <p/>
* This header can be used with x-amz-copy-source-if-modified-since, but
* cannot be used with other conditional copy headers.
*
*
* @see CopyObjectOptions#ifSourceMd5DoesntMatch(byte[])
*/
public String getIfNoneMatch() {
return getFirstHeaderOrNull("x-amz-copy-source-if-none-match");
return getFirstHeaderOrNull("x-amz-copy-source-if-none-match");
}
/**
* When not null, contains the header
* [x-amz-copy-source-if-unmodified-since] -> [REPLACE] and metadata headers
* passed in from the users.
*
*
* @see #overrideMetadataWith(Multimap)
*/
public Multimap<String, String> getMetadata() {
return metadata;
return metadata;
}
/**
* Only return the object if it has changed since this time.
* <p />
* <p/>
* Not compatible with {@link #ifSourceMd5Matches(byte[])} or
* {@link #ifSourceUnmodifiedSince(DateTime)}
*/
public CopyObjectOptions ifSourceModifiedSince(DateTime ifModifiedSince) {
checkState(getIfMatch() == null,
"ifMd5Matches() is not compatible with ifModifiedSince()");
checkState(getIfUnmodifiedSince() == null,
"ifUnmodifiedSince() is not compatible with ifModifiedSince()");
replaceHeader("x-amz-copy-source-if-modified-since",
dateService.toHeaderString(checkNotNull(ifModifiedSince,
"ifModifiedSince")));
return this;
checkState(getIfMatch() == null,
"ifMd5Matches() is not compatible with ifModifiedSince()");
checkState(getIfUnmodifiedSince() == null,
"ifUnmodifiedSince() is not compatible with ifModifiedSince()");
replaceHeader("x-amz-copy-source-if-modified-since",
dateService.toHeaderString(checkNotNull(ifModifiedSince,
"ifModifiedSince")));
return this;
}
/**
* Only return the object if it hasn't changed since this time.
* <p />
* <p/>
* Not compatible with {@link #ifSourceMd5DoesntMatch(byte[])} or
* {@link #ifSourceModifiedSince(DateTime)}
*/
public CopyObjectOptions ifSourceUnmodifiedSince(DateTime ifUnmodifiedSince) {
checkState(getIfNoneMatch() == null,
"ifMd5DoesntMatch() is not compatible with ifUnmodifiedSince()");
checkState(getIfModifiedSince() == null,
"ifModifiedSince() is not compatible with ifUnmodifiedSince()");
replaceHeader("x-amz-copy-source-if-unmodified-since", dateService
.toHeaderString(checkNotNull(ifUnmodifiedSince,
"ifUnmodifiedSince")));
return this;
checkState(getIfNoneMatch() == null,
"ifMd5DoesntMatch() is not compatible with ifUnmodifiedSince()");
checkState(getIfModifiedSince() == null,
"ifModifiedSince() is not compatible with ifUnmodifiedSince()");
replaceHeader("x-amz-copy-source-if-unmodified-since", dateService
.toHeaderString(checkNotNull(ifUnmodifiedSince,
"ifUnmodifiedSince")));
return this;
}
/**
* The object's md5 hash should match the parameter <code>md5</code>.
*
* <p />
* <p/>
* <p/>
* Not compatible with {@link #ifSourceMd5DoesntMatch(byte[])} or
* {@link #ifSourceModifiedSince(DateTime)}
*
* @param md5
* hash representing the entity
* @throws UnsupportedEncodingException
* if there was a problem converting this into an S3 eTag string
*
* @param md5 hash representing the entity
* @throws UnsupportedEncodingException if there was a problem converting this into an S3 eTag string
*/
public CopyObjectOptions ifSourceMd5Matches(byte[] md5)
throws UnsupportedEncodingException {
checkState(getIfNoneMatch() == null,
"ifMd5DoesntMatch() is not compatible with ifMd5Matches()");
checkState(getIfModifiedSince() == null,
"ifModifiedSince() is not compatible with ifMd5Matches()");
replaceHeader("x-amz-copy-source-if-match", String.format("\"%1$s\"",
S3Utils.toHexString(checkNotNull(md5, "md5"))));
return this;
throws UnsupportedEncodingException {
checkState(getIfNoneMatch() == null,
"ifMd5DoesntMatch() is not compatible with ifMd5Matches()");
checkState(getIfModifiedSince() == null,
"ifModifiedSince() is not compatible with ifMd5Matches()");
replaceHeader("x-amz-copy-source-if-match", String.format("\"%1$s\"",
S3Utils.toHexString(checkNotNull(md5, "md5"))));
return this;
}
/**
* The object should not have a md5 hash corresponding with the parameter
* <code>md5</code>.
* <p />
* <p/>
* Not compatible with {@link #ifSourceMd5Matches(byte[])} or
* {@link #ifSourceUnmodifiedSince(DateTime)}
*
* @param md5
* hash representing the entity
* @throws UnsupportedEncodingException
* if there was a problem converting this into an S3 eTag string
*
* @param md5 hash representing the entity
* @throws UnsupportedEncodingException if there was a problem converting this into an S3 eTag string
*/
public CopyObjectOptions ifSourceMd5DoesntMatch(byte[] md5)
throws UnsupportedEncodingException {
checkState(getIfMatch() == null,
"ifMd5Matches() is not compatible with ifMd5DoesntMatch()");
Preconditions
.checkState(getIfUnmodifiedSince() == null,
"ifUnmodifiedSince() is not compatible with ifMd5DoesntMatch()");
replaceHeader("x-amz-copy-source-if-none-match", String.format(
"\"%1$s\"", S3Utils.toHexString(checkNotNull(md5,
"ifMd5DoesntMatch"))));
return this;
throws UnsupportedEncodingException {
checkState(getIfMatch() == null,
"ifMd5Matches() is not compatible with ifMd5DoesntMatch()");
Preconditions
.checkState(getIfUnmodifiedSince() == null,
"ifUnmodifiedSince() is not compatible with ifMd5DoesntMatch()");
replaceHeader("x-amz-copy-source-if-none-match", String.format(
"\"%1$s\"", S3Utils.toHexString(checkNotNull(md5,
"ifMd5DoesntMatch"))));
return this;
}
@Override
public Multimap<String, String> buildRequestHeaders() {
Multimap<String, String> returnVal = HashMultimap.create();
returnVal.putAll(headers);
if (metadata != null) {
returnVal.putAll(metadata);
returnVal.put("x-amz-metadata-directive", "REPLACE");
}
return returnVal;
Multimap<String, String> returnVal = HashMultimap.create();
returnVal.putAll(headers);
if (metadata != null) {
returnVal.putAll(metadata);
returnVal.put("x-amz-metadata-directive", "REPLACE");
}
return returnVal;
}
/**
* Use the provided metadata instead of what is on the source object.
*/
public CopyObjectOptions overrideMetadataWith(
Multimap<String, String> metadata) {
checkNotNull(metadata, "metadata");
for (String header : metadata.keySet()) {
checkArgument(header.startsWith("x-amz-meta-"),
"Metadata keys must start with x-amz-meta-");
}
this.metadata = metadata;
return this;
Multimap<String, String> metadata) {
checkNotNull(metadata, "metadata");
for (String header : metadata.keySet()) {
checkArgument(header.startsWith("x-amz-meta-"),
"Metadata keys must start with x-amz-meta-");
}
this.metadata = metadata;
return this;
}
public static class Builder {
/**
* @see CopyObjectOptions#overrideAcl(CannedAccessPolicy)
*/
public static CopyObjectOptions overrideAcl(CannedAccessPolicy acl) {
CopyObjectOptions options = new CopyObjectOptions();
return options.overrideAcl(acl);
}
/**
* @see CopyObjectOptions#overrideAcl(CannedAccessPolicy)
*/
public static CopyObjectOptions overrideAcl(CannedAccessPolicy acl) {
CopyObjectOptions options = new CopyObjectOptions();
return options.overrideAcl(acl);
}
/**
* @see CopyObjectOptions#getIfModifiedSince()
*/
public static CopyObjectOptions ifSourceModifiedSince(
DateTime ifModifiedSince) {
CopyObjectOptions options = new CopyObjectOptions();
return options.ifSourceModifiedSince(ifModifiedSince);
}
/**
* @see CopyObjectOptions#getIfModifiedSince()
*/
public static CopyObjectOptions ifSourceModifiedSince(
DateTime ifModifiedSince) {
CopyObjectOptions options = new CopyObjectOptions();
return options.ifSourceModifiedSince(ifModifiedSince);
}
/**
* @see CopyObjectOptions#ifSourceUnmodifiedSince(DateTime)
*/
public static CopyObjectOptions ifSourceUnmodifiedSince(
DateTime ifUnmodifiedSince) {
CopyObjectOptions options = new CopyObjectOptions();
return options.ifSourceUnmodifiedSince(ifUnmodifiedSince);
}
/**
* @see CopyObjectOptions#ifSourceUnmodifiedSince(DateTime)
*/
public static CopyObjectOptions ifSourceUnmodifiedSince(
DateTime ifUnmodifiedSince) {
CopyObjectOptions options = new CopyObjectOptions();
return options.ifSourceUnmodifiedSince(ifUnmodifiedSince);
}
/**
* @see CopyObjectOptions#ifSourceMd5Matches(byte[])
*/
public static CopyObjectOptions ifSourceMd5Matches(byte[] md5)
throws UnsupportedEncodingException {
CopyObjectOptions options = new CopyObjectOptions();
return options.ifSourceMd5Matches(md5);
}
/**
* @see CopyObjectOptions#ifSourceMd5Matches(byte[])
*/
public static CopyObjectOptions ifSourceMd5Matches(byte[] md5)
throws UnsupportedEncodingException {
CopyObjectOptions options = new CopyObjectOptions();
return options.ifSourceMd5Matches(md5);
}
/**
* @see CopyObjectOptions#ifSourceMd5DoesntMatch(byte[])
*/
public static CopyObjectOptions ifSourceMd5DoesntMatch(byte[] md5)
throws UnsupportedEncodingException {
CopyObjectOptions options = new CopyObjectOptions();
return options.ifSourceMd5DoesntMatch(md5);
}
/**
* @see CopyObjectOptions#ifSourceMd5DoesntMatch(byte[])
*/
public static CopyObjectOptions ifSourceMd5DoesntMatch(byte[] md5)
throws UnsupportedEncodingException {
CopyObjectOptions options = new CopyObjectOptions();
return options.ifSourceMd5DoesntMatch(md5);
}
/**
* @see #overrideMetadataWith(Multimap)
*/
public static CopyObjectOptions overrideMetadataWith(
Multimap<String, String> metadata) {
CopyObjectOptions options = new CopyObjectOptions();
return options.overrideMetadataWith(metadata);
}
/**
* @see #overrideMetadataWith(Multimap)
*/
public static CopyObjectOptions overrideMetadataWith(
Multimap<String, String> metadata) {
CopyObjectOptions options = new CopyObjectOptions();
return options.overrideMetadataWith(metadata);
}
}
}

View File

@ -25,12 +25,11 @@ package org.jclouds.aws.s3.commands.options;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
import org.jclouds.http.options.BaseHttpRequestOptions;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import org.jclouds.http.options.BaseHttpRequestOptions;
/**
* Contains options supported in the REST API for the GET bucket operation. <h2>
* Usage</h2> The recommended way to instantiate a GetBucketOptions object is to
@ -39,17 +38,14 @@ import org.jclouds.http.options.BaseHttpRequestOptions;
* <p/>
* <code>
* import static org.jclouds.aws.s3.commands.options.GetBucketOptions.Builder.*
*
* <p/>
* S3Connection connection = // get connection
* Future<S3Bucket> bucket = connection.listBucket("bucketName",withPrefix("home/users").maxKeys(1000));
* <code>
*
*
* @author Adrian Cole
* @see <a href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?RESTBucketGET.html?"
* />
*
* @author Adrian Cole
*
*
*/
public class ListBucketOptions extends BaseHttpRequestOptions {
public static final ListBucketOptions NONE = new ListBucketOptions();
@ -58,21 +54,21 @@ public class ListBucketOptions extends BaseHttpRequestOptions {
* Limits the response to keys which begin with the indicated prefix. You
* can use prefixes to separate a bucket into different sets of keys in a
* way similar to how a file system uses folders.
*
*
* @throws UnsupportedEncodingException
*/
public ListBucketOptions withPrefix(String prefix)
throws UnsupportedEncodingException {
options.put("prefix", URLEncoder.encode(checkNotNull(prefix, "prefix"),
"UTF-8"));
return this;
throws UnsupportedEncodingException {
options.put("prefix", URLEncoder.encode(checkNotNull(prefix, "prefix"),
"UTF-8"));
return this;
}
/**
* @see ListBucketOptions#withPrefix(String)
*/
public String getPrefix() {
return options.get("prefix");
return options.get("prefix");
}
/**
@ -80,21 +76,21 @@ public class ListBucketOptions extends BaseHttpRequestOptions {
* include keys that occur lexicographically after marker. This is
* convenient for pagination: To get the next page of results use the last
* key of the current page as the marker.
*
*
* @throws UnsupportedEncodingException
*/
public ListBucketOptions afterMarker(String marker)
throws UnsupportedEncodingException {
options.put("marker", URLEncoder.encode(checkNotNull(marker, "marker"),
"UTF-8"));
return this;
throws UnsupportedEncodingException {
options.put("marker", URLEncoder.encode(checkNotNull(marker, "marker"),
"UTF-8"));
return this;
}
/**
* @see ListBucketOptions#afterMarker(String)
*/
public String getMarker() {
return options.get("marker");
return options.get("marker");
}
/**
@ -102,16 +98,16 @@ public class ListBucketOptions extends BaseHttpRequestOptions {
* server might return fewer than this many keys, but will not return more.
*/
public ListBucketOptions maxResults(long maxKeys) {
checkState(maxKeys >= 0, "maxKeys must be >= 0");
options.put("max-keys", Long.toString(maxKeys));
return this;
checkState(maxKeys >= 0, "maxKeys must be >= 0");
options.put("max-keys", Long.toString(maxKeys));
return this;
}
/**
* @see ListBucketOptions#maxResults(long)
*/
public String getMaxKeys() {
return options.get("max-keys");
return options.get("max-keys");
}
/**
@ -119,62 +115,62 @@ public class ListBucketOptions extends BaseHttpRequestOptions {
* occurrence of the delimiter to be rolled up into a single result element
* in the CommonPrefixes collection. These rolled-up keys are not returned
* elsewhere in the response.
*
*
* @throws UnsupportedEncodingException
*/
public ListBucketOptions setDelimiter(String delimiter)
throws UnsupportedEncodingException {
options.put("delimiter", URLEncoder.encode(checkNotNull(delimiter,
"delimiter"), "UTF-8"));
return this;
public ListBucketOptions delimiter(String delimiter)
throws UnsupportedEncodingException {
options.put("delimiter", URLEncoder.encode(checkNotNull(delimiter,
"delimiter"), "UTF-8"));
return this;
}
/**
* @see ListBucketOptions#setDelimiter(String)
* @see ListBucketOptions#delimiter(String)
*/
public String getDelimiter() {
return options.get("delimiter");
return options.get("delimiter");
}
public static class Builder {
/**
* @throws UnsupportedEncodingException
* @see ListBucketOptions#withPrefix(String)
*/
public static ListBucketOptions withPrefix(String prefix)
throws UnsupportedEncodingException {
ListBucketOptions options = new ListBucketOptions();
return options.withPrefix(prefix);
}
/**
* @throws UnsupportedEncodingException
* @see ListBucketOptions#withPrefix(String)
*/
public static ListBucketOptions withPrefix(String prefix)
throws UnsupportedEncodingException {
ListBucketOptions options = new ListBucketOptions();
return options.withPrefix(prefix);
}
/**
* @throws UnsupportedEncodingException
* @see ListBucketOptions#afterMarker(String)
*/
public static ListBucketOptions afterMarker(String marker)
throws UnsupportedEncodingException {
ListBucketOptions options = new ListBucketOptions();
return options.afterMarker(marker);
}
/**
* @throws UnsupportedEncodingException
* @see ListBucketOptions#afterMarker(String)
*/
public static ListBucketOptions afterMarker(String marker)
throws UnsupportedEncodingException {
ListBucketOptions options = new ListBucketOptions();
return options.afterMarker(marker);
}
/**
* @see ListBucketOptions#maxResults(long)
*/
public static ListBucketOptions maxResults(long maxKeys) {
ListBucketOptions options = new ListBucketOptions();
return options.maxResults(maxKeys);
}
/**
* @see ListBucketOptions#maxResults(long)
*/
public static ListBucketOptions maxResults(long maxKeys) {
ListBucketOptions options = new ListBucketOptions();
return options.maxResults(maxKeys);
}
/**
* @throws UnsupportedEncodingException
* @see ListBucketOptions#delimiter(String)
*/
public static ListBucketOptions delimiter(String delimiter)
throws UnsupportedEncodingException {
ListBucketOptions options = new ListBucketOptions();
return options.setDelimiter(delimiter);
}
/**
* @throws UnsupportedEncodingException
* @see ListBucketOptions#delimiter(String)
*/
public static ListBucketOptions delimiter(String delimiter)
throws UnsupportedEncodingException {
ListBucketOptions options = new ListBucketOptions();
return options.delimiter(delimiter);
}
}
}

View File

@ -23,13 +23,12 @@
*/
package org.jclouds.aws.s3.commands.options;
import static com.google.common.base.Preconditions.checkNotNull;
import org.jclouds.aws.s3.domain.S3Bucket.Metadata.LocationConstraint;
import org.jclouds.aws.s3.domain.acl.CannedAccessPolicy;
import org.jclouds.aws.s3.reference.S3Headers;
import org.jclouds.http.options.BaseHttpRequestOptions;
import static com.google.common.base.Preconditions.*;
/**
* 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
@ -40,16 +39,14 @@ import static com.google.common.base.Preconditions.*;
* import static org.jclouds.aws.s3.commands.options.PutBucketOptions.Builder.*
* import static org.jclouds.aws.s3.domain.S3Bucket.Metadata.LocationConstraint.*;
* import org.jclouds.aws.s3.S3Connection;
*
* <p/>
* S3Connection 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?"
* />
*
* @author Adrian Cole
*
*/
public class PutBucketOptions extends BaseHttpRequestOptions {
public static final PutBucketOptions NONE = new PutBucketOptions();
@ -62,55 +59,55 @@ public class PutBucketOptions extends BaseHttpRequestOptions {
* 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;
this.constraint = checkNotNull(constraint, "constraint");
this.payload = String
.format(
"<CreateBucketConfiguration><LocationConstraint>%1$s</LocationConstraint></CreateBucketConfiguration>",
constraint.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;
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;
return acl;
}
/**
* @see PutBucketOptions#createIn(LocationConstraint)
* @see PutBucketOptions#createIn(org.jclouds.aws.s3.domain.S3Bucket.Metadata.LocationConstraint)
*/
public LocationConstraint getLocationConstraint() {
return constraint;
return constraint;
}
public static class Builder {
/**
* @see PutBucketOptions#createIn(LocationConstraint)
*/
public static PutBucketOptions createIn(LocationConstraint constraint) {
PutBucketOptions options = new PutBucketOptions();
return options.createIn(constraint);
}
/**
* @see PutBucketOptions#createIn(org.jclouds.aws.s3.domain.S3Bucket.Metadata.LocationConstraint)
*/
public static PutBucketOptions createIn(LocationConstraint constraint) {
PutBucketOptions options = new PutBucketOptions();
return options.createIn(constraint);
}
/**
* @see PutBucketOptions#withBucketAcl(CannedAccessPolicy)
*/
public static PutBucketOptions withBucketAcl(CannedAccessPolicy acl) {
PutBucketOptions options = new PutBucketOptions();
return options.withBucketAcl(acl);
}
/**
* @see PutBucketOptions#withBucketAcl(CannedAccessPolicy)
*/
public static PutBucketOptions withBucketAcl(CannedAccessPolicy acl) {
PutBucketOptions options = new PutBucketOptions();
return options.withBucketAcl(acl);
}
}
}

View File

@ -0,0 +1,96 @@
/**
*
* Copyright (C) 2009 Adrian Cole <adrian@jclouds.org>
*
* ====================================================================
* 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.config;
import com.google.inject.*;
import com.google.inject.assistedinject.FactoryProvider;
import com.google.inject.name.Named;
import org.jclouds.aws.s3.S3Connection;
import org.jclouds.aws.s3.S3Context;
import org.jclouds.aws.s3.commands.config.S3CommandsModule;
import org.jclouds.aws.s3.filters.RequestAuthorizeSignature;
import org.jclouds.aws.s3.handlers.ParseS3ErrorFromXmlContent;
import org.jclouds.aws.s3.internal.GuiceS3Context;
import org.jclouds.aws.s3.internal.LiveS3Connection;
import org.jclouds.aws.s3.internal.LiveS3InputStreamMap;
import org.jclouds.aws.s3.internal.LiveS3ObjectMap;
import org.jclouds.http.HttpConstants;
import org.jclouds.http.HttpRequestFilter;
import org.jclouds.http.HttpResponseHandler;
import org.jclouds.http.annotation.ClientErrorHandler;
import org.jclouds.http.annotation.RedirectHandler;
import org.jclouds.http.annotation.ServerErrorHandler;
import org.jclouds.http.handlers.CloseContentAndSetExceptionHandler;
import org.jclouds.logging.Logger;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
/**
* Configures the S3 connection, including logging and http transport.
*
* @author Adrian Cole
*/
@S3ConnectionModule
public class LiveS3ConnectionModule extends AbstractModule {
@Resource
protected Logger logger = Logger.NULL;
@Inject
@Named(HttpConstants.PROPERTY_HTTP_ADDRESS)
String address;
@Inject
@Named(HttpConstants.PROPERTY_HTTP_PORT)
int port;
@Inject
@Named(HttpConstants.PROPERTY_HTTP_SECURE)
boolean isSecure;
@Override
protected void configure() {
bind(S3Connection.class).to(LiveS3Connection.class)
.in(Scopes.SINGLETON);
bind(HttpResponseHandler.class).annotatedWith(RedirectHandler.class)
.to(CloseContentAndSetExceptionHandler.class).in(
Scopes.SINGLETON);
bind(HttpResponseHandler.class).annotatedWith(ClientErrorHandler.class)
.to(ParseS3ErrorFromXmlContent.class).in(Scopes.SINGLETON);
bind(HttpResponseHandler.class).annotatedWith(ServerErrorHandler.class)
.to(ParseS3ErrorFromXmlContent.class).in(Scopes.SINGLETON);
requestInjection(this);
logger.info("S3 Context = %1$s://%2$s:%3$s", (isSecure ? "https"
: "http"), address, port);
}
@Provides
@Singleton
List<HttpRequestFilter> provideRequestFilters(
RequestAuthorizeSignature requestAuthorizeSignature) {
List<HttpRequestFilter> filters = new ArrayList<HttpRequestFilter>();
filters.add(requestAuthorizeSignature);
return filters;
}
}

View File

@ -0,0 +1,21 @@
package org.jclouds.aws.s3.config;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import org.jclouds.http.HttpFutureCommandClient;
/**
* designates the the module configures a {@link org.jclouds.aws.s3.S3Connection}
*
* @author Adrian Cole
*
*/
@Retention(RUNTIME)
@Target(TYPE)
public @interface S3ConnectionModule {
}

View File

@ -23,89 +23,37 @@
*/
package org.jclouds.aws.s3.config;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.Resource;
import com.google.inject.AbstractModule;
import com.google.inject.assistedinject.FactoryProvider;
import org.jclouds.aws.s3.S3Connection;
import org.jclouds.aws.s3.S3Context;
import org.jclouds.aws.s3.commands.config.S3CommandsModule;
import org.jclouds.aws.s3.filters.RequestAuthorizeSignature;
import org.jclouds.aws.s3.handlers.ParseS3ErrorFromXmlContent;
import org.jclouds.aws.s3.internal.GuiceS3Context;
import org.jclouds.aws.s3.internal.LiveS3Connection;
import org.jclouds.aws.s3.internal.LiveS3InputStreamMap;
import org.jclouds.aws.s3.internal.LiveS3ObjectMap;
import org.jclouds.http.HttpConstants;
import org.jclouds.http.HttpRequestFilter;
import org.jclouds.http.HttpResponseHandler;
import org.jclouds.http.annotation.ClientErrorHandler;
import org.jclouds.http.annotation.RedirectHandler;
import org.jclouds.http.annotation.ServerErrorHandler;
import org.jclouds.http.handlers.CloseContentAndSetExceptionHandler;
import org.jclouds.logging.Logger;
import com.google.inject.AbstractModule;
import com.google.inject.Inject;
import com.google.inject.Provides;
import com.google.inject.Scopes;
import com.google.inject.Singleton;
import com.google.inject.assistedinject.FactoryProvider;
import com.google.inject.name.Named;
/**
* Configures the S3 connection, including logging and http transport.
*
* Configures the {@link S3Context}; requires {@link S3Connection} bound.
*
* @author Adrian Cole
*/
public class S3ContextModule extends AbstractModule {
@Resource
protected Logger logger = Logger.NULL;
@Inject
@Named(HttpConstants.PROPERTY_HTTP_ADDRESS)
String address;
@Inject
@Named(HttpConstants.PROPERTY_HTTP_PORT)
int port;
@Inject
@Named(HttpConstants.PROPERTY_HTTP_SECURE)
boolean isSecure;
@Override
protected void configure() {
install(new S3CommandsModule());
bind(S3Connection.class).to(LiveS3Connection.class)
.in(Scopes.SINGLETON);
bind(GuiceS3Context.S3ObjectMapFactory.class).toProvider(
FactoryProvider.newFactory(
GuiceS3Context.S3ObjectMapFactory.class,
LiveS3ObjectMap.class));
bind(GuiceS3Context.S3InputStreamMapFactory.class).toProvider(
FactoryProvider.newFactory(
GuiceS3Context.S3InputStreamMapFactory.class,
LiveS3InputStreamMap.class));
bind(S3Context.class).to(GuiceS3Context.class);
bind(HttpResponseHandler.class).annotatedWith(RedirectHandler.class)
.to(CloseContentAndSetExceptionHandler.class).in(
Scopes.SINGLETON);
bind(HttpResponseHandler.class).annotatedWith(ClientErrorHandler.class)
.to(ParseS3ErrorFromXmlContent.class).in(Scopes.SINGLETON);
bind(HttpResponseHandler.class).annotatedWith(ServerErrorHandler.class)
.to(ParseS3ErrorFromXmlContent.class).in(Scopes.SINGLETON);
requestInjection(this);
logger.info("S3 Context = %1$s://%2$s:%3$s", (isSecure ? "https"
: "http"), address, port);
}
this.requireBinding(S3Connection.class);
install(new S3CommandsModule());
bind(GuiceS3Context.S3ObjectMapFactory.class).toProvider(
FactoryProvider.newFactory(
GuiceS3Context.S3ObjectMapFactory.class,
LiveS3ObjectMap.class));
bind(GuiceS3Context.S3InputStreamMapFactory.class).toProvider(
FactoryProvider.newFactory(
GuiceS3Context.S3InputStreamMapFactory.class,
LiveS3InputStreamMap.class));
bind(S3Context.class).to(GuiceS3Context.class);
@Provides
@Singleton
List<HttpRequestFilter> provideRequestFilters(
RequestAuthorizeSignature requestAuthorizeSignature) {
List<HttpRequestFilter> filters = new ArrayList<HttpRequestFilter>();
filters.add(requestAuthorizeSignature);
return filters;
}
}

View File

@ -24,36 +24,35 @@
package org.jclouds.aws.s3.domain;
import static com.google.common.base.Preconditions.checkNotNull;
import org.joda.time.DateTime;
import java.util.HashSet;
import java.util.Set;
import org.joda.time.DateTime;
/**
* A container that provides namespace, access control and aggregation of
* {@link S3Object}s
*
* <p/>
* <p/>
* Every object stored in Amazon S3 is contained in a bucket. Buckets partition
* the namespace of objects stored in Amazon S3 at the top level. Within a
* bucket, you can use any names for your objects, but bucket names must be
* unique across all of Amazon S3.
*
* <p/>
* Buckets are similar to Internet domain names. Just as Amazon is the only
* owner of the domain name Amazon.com, only one person or organization can own
* a bucket within Amazon S3. Once you create a uniquely named bucket in Amazon
* S3, you can organize and name the objects within the bucket in any way you
* like and the bucket will remain yours for as long as you like and as long as
* you have the Amazon S3 account.
*
* <p/>
* The similarities between buckets and domain names is not a coincidenceÑthere
* is a direct mapping between Amazon S3 buckets and subdomains of
* s3.amazonaws.com. Objects stored in Amazon S3 are addressable using the REST
* API under the domain bucketname.s3.amazonaws.com. For example, if the object
* homepage.html?is stored in the Amazon S3 bucket mybucket its address would be
* http://mybucket.s3.amazonaws.com/homepage.html?
*
*
* @author Adrian Cole
* @see <a
* href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html"
@ -62,148 +61,145 @@ import org.joda.time.DateTime;
public class S3Bucket {
@Override
public String toString() {
final StringBuilder sb = new StringBuilder();
sb.append("S3Bucket");
sb.append("{metadata=").append(metadata);
sb.append(", isComplete=").append(isComplete);
sb.append('}');
return sb.toString();
final StringBuilder sb = new StringBuilder();
sb.append("S3Bucket");
sb.append("{metadata=").append(metadata);
sb.append(", isTruncated=").append(isTruncated);
sb.append('}');
return sb.toString();
}
@Override
public boolean equals(Object o) {
if (this == o)
return true;
if (!(o instanceof S3Bucket))
return false;
if (this == o)
return true;
if (!(o instanceof S3Bucket))
return false;
S3Bucket s3Bucket = (S3Bucket) o;
S3Bucket s3Bucket = (S3Bucket) o;
if (isComplete != s3Bucket.isComplete)
return false;
if (!metadata.equals(s3Bucket.metadata))
return false;
if (objects != null ? !objects.equals(s3Bucket.objects)
: s3Bucket.objects != null)
return false;
if (isTruncated != s3Bucket.isTruncated)
return false;
if (!metadata.equals(s3Bucket.metadata))
return false;
if (objects != null ? !objects.equals(s3Bucket.objects)
: s3Bucket.objects != null)
return false;
return true;
return true;
}
@Override
public int hashCode() {
int result = objects != null ? objects.hashCode() : 0;
result = 31 * result + metadata.hashCode();
result = 31 * result + (isComplete ? 1 : 0);
return result;
int result = objects != null ? objects.hashCode() : 0;
result = 31 * result + metadata.hashCode();
result = 31 * result + (isTruncated ? 1 : 0);
return result;
}
/**
* System metadata of the S3Bucket
*
*
* @author Adrian Cole
*
*/
public static class Metadata {
@Override
public String toString() {
final StringBuilder sb = new StringBuilder();
sb.append("Metadata");
sb.append("{name='").append(name).append('\'');
sb.append(", creationDate=").append(creationDate);
sb.append(", canonicalUser=").append(canonicalUser);
sb.append('}');
return sb.toString();
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder();
sb.append("Metadata");
sb.append("{name='").append(name).append('\'');
sb.append(", creationDate=").append(creationDate);
sb.append(", canonicalUser=").append(canonicalUser);
sb.append('}');
return sb.toString();
}
@Override
public boolean equals(Object o) {
if (this == o)
return true;
if (!(o instanceof Metadata))
return false;
@Override
public boolean equals(Object o) {
if (this == o)
return true;
if (!(o instanceof Metadata))
return false;
Metadata metadata = (Metadata) o;
if (canonicalUser != null ? !canonicalUser
.equals(metadata.canonicalUser)
: metadata.canonicalUser != null)
return false;
if (!name.equals(metadata.name))
return false;
Metadata metadata = (Metadata) o;
if (canonicalUser != null ? !canonicalUser
.equals(metadata.canonicalUser)
: metadata.canonicalUser != null)
return false;
if (!name.equals(metadata.name))
return false;
return true;
}
return true;
}
@Override
public int hashCode() {
int result = name.hashCode();
result = 31 * result
+ (canonicalUser != null ? canonicalUser.hashCode() : 0);
return result;
}
@Override
public int hashCode() {
int result = name.hashCode();
result = 31 * result
+ (canonicalUser != null ? canonicalUser.hashCode() : 0);
return result;
}
/**
* Location constraint of the bucket.
*
* @see <a href=
* "http://docs.amazonwebservices.com/AmazonS3/latest/RESTBucketLocationGET.html"
* />
* @author Adrian Cole
*
*/
public static enum LocationConstraint {
EU
}
/**
* Location constraint of the bucket.
*
* @author Adrian Cole
* @see <a href=
* "http://docs.amazonwebservices.com/AmazonS3/latest/RESTBucketLocationGET.html"
* />
*/
public static enum LocationConstraint {
EU
}
private final String name;
private DateTime creationDate;
private CanonicalUser canonicalUser;
private final String name;
private DateTime creationDate;
private CanonicalUser canonicalUser;
/**
* @see #getName()
*/
public Metadata(String name) {
this.name = checkNotNull(name, "name");
}
/**
* @see #getName()
*/
public Metadata(String name) {
this.name = checkNotNull(name, "name");
}
/**
* To comply with Amazon S3 requirements, bucket names must:
*
* Contain lowercase letters, numbers, periods (.), underscores (_), and
* dashes (-)
*
* Start with a number or letter
*
* Be between 3 and 255 characters long
*
* Not be in an IP address style (e.g., "192.168.5.4")
*
*/
public String getName() {
return name;
}
/**
* To comply with Amazon S3 requirements, bucket names must:
* <p/>
* Contain lowercase letters, numbers, periods (.), underscores (_), and
* dashes (-)
* <p/>
* Start with a number or letter
* <p/>
* Be between 3 and 255 characters long
* <p/>
* Not be in an IP address style (e.g., "192.168.5.4")
*/
public String getName() {
return name;
}
public DateTime getCreationDate() {
return creationDate;
}
public DateTime getCreationDate() {
return creationDate;
}
public void setCreationDate(DateTime creationDate) {
this.creationDate = creationDate;
}
public void setCreationDate(DateTime creationDate) {
this.creationDate = creationDate;
}
/**
* Every bucket and object in Amazon S3 has an owner, the user that
* created the bucket or object. The owner of a bucket or object cannot
* be changed. However, if the object is overwritten by another user
* (deleted and rewritten), the new object will have a new owner.
*/
public CanonicalUser getOwner() {
return canonicalUser;
}
/**
* Every bucket and object in Amazon S3 has an owner, the user that
* created the bucket or object. The owner of a bucket or object cannot
* be changed. However, if the object is overwritten by another user
* (deleted and rewritten), the new object will have a new owner.
*/
public CanonicalUser getOwner() {
return canonicalUser;
}
public void setOwner(CanonicalUser canonicalUser) {
this.canonicalUser = canonicalUser;
}
public void setOwner(CanonicalUser canonicalUser) {
this.canonicalUser = canonicalUser;
}
}
@ -217,84 +213,84 @@ public class S3Bucket {
private long maxKeys;
private final Metadata metadata;
private boolean isComplete;
private boolean isTruncated;
public S3Bucket(String name) {
this.metadata = new Metadata(name);
this.metadata = new Metadata(name);
}
public String getName() {
return this.metadata.getName();
return this.metadata.getName();
}
public S3Bucket(Metadata metadata) {
this.metadata = checkNotNull(metadata, "metadata");
this.metadata = checkNotNull(metadata, "metadata");
}
/**
* @see org.jclouds.aws.s3.S3Connection#listBucket(String)
*/
public Set<S3Object.Metadata> getContents() {
return objects;
return objects;
}
public void setContents(Set<S3Object.Metadata> objects) {
this.objects = objects;
this.objects = objects;
}
/**
* @return true, if the list contains all objects.
*/
public boolean isComplete() {
return isComplete;
public boolean isTruncated() {
return isTruncated;
}
public void setComplete(boolean complete) {
isComplete = complete;
public void setTruncated(boolean truncated) {
isTruncated = truncated;
}
public Metadata getMetadata() {
return metadata;
return metadata;
}
public void setCommonPrefixes(Set<String> commonPrefixes) {
this.commonPrefixes = commonPrefixes;
this.commonPrefixes = commonPrefixes;
}
/**
* Example:
* <p />
* <p/>
* if the following keys are in the bucket
*
* <p/>
* a/1/a<br/>
* a/1/b<br/>
* a/2/a<br/>
* a/2/b<br/>
* <p />
* <p/>
* and prefix is set to <code>a/</code> and delimiter is set to
* <code>/</code> then commonprefixes would return 1,2
*
*
* @see org.jclouds.aws.s3.commands.options.ListBucketOptions#getPrefix()
*/
public Set<String> getCommonPrefixes() {
return commonPrefixes;
return commonPrefixes;
}
public void setPrefix(String prefix) {
this.prefix = prefix;
this.prefix = prefix;
}
/**
* return keys that start with this.
*
*
* @see org.jclouds.aws.s3.commands.options.ListBucketOptions#getPrefix()
*/
public String getPrefix() {
return prefix;
return prefix;
}
public void setMaxKeys(long maxKeys) {
this.maxKeys = maxKeys;
this.maxKeys = maxKeys;
}
/**
@ -302,25 +298,25 @@ public class S3Bucket {
* @see org.jclouds.aws.s3.commands.options.ListBucketOptions#getMaxKeys()
*/
public long getMaxKeys() {
return maxKeys;
return maxKeys;
}
public void setMarker(String marker) {
this.marker = marker;
this.marker = marker;
}
/**
* when set, bucket contains results whose keys are lexigraphically after
* marker.
*
*
* @see org.jclouds.aws.s3.commands.options.ListBucketOptions#getMarker()
*/
public String getMarker() {
return marker;
return marker;
}
public void setDelimiter(String delimiter) {
this.delimiter = delimiter;
this.delimiter = delimiter;
}
/**
@ -330,7 +326,7 @@ public class S3Bucket {
* note that delimiter has no effect on prefix. prefix can contain the
* delimiter many times, or not at all. delimiter only restricts after the
* prefix.
*
*
* @see org.jclouds.aws.s3.commands.options.ListBucketOptions#getMarker()
*/
public String getDelimiter() {

View File

@ -23,32 +23,28 @@
*/
package org.jclouds.aws.s3.domain;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import static com.google.common.base.Preconditions.*;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;
import org.jclouds.aws.s3.commands.options.GetObjectOptions;
import org.jclouds.aws.s3.util.S3Utils;
import org.jclouds.aws.s3.util.S3Utils.Md5InputStreamResult;
import org.jclouds.http.ContentTypes;
import org.joda.time.DateTime;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
/**
* Amazon S3 is designed to store objects. Objects are stored in
* {@link S3Bucket buckets} and consist of a {@link S3Object#getValue() value},
* {@link S3Bucket buckets} and consist of a {@link org.jclouds.aws.s3.domain.S3Object#getData() value},
* a {@link S3Object#getKey key}, {@link S3Object.Metadata#getUserMetadata()
* metadata}, and an access control policy.
*
*
* @author Adrian Cole
* @see <a href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?UsingObjects.html"
* />
* @author Adrian Cole
*/
public class S3Object {
public static final S3Object NOT_FOUND = new S3Object(Metadata.NOT_FOUND);
@ -59,381 +55,372 @@ public class S3Object {
private String contentRange;
public S3Object(String key) {
this(new Metadata(key));
this(new Metadata(key));
}
public S3Object(Metadata metadata) {
this.metadata = metadata;
this.metadata = metadata;
}
public S3Object(Metadata metadata, Object data) {
this(metadata);
setData(data);
this(metadata);
setData(data);
}
public S3Object(String key, Object data) {
this(key);
setData(data);
this(key);
setData(data);
}
/**
* System and user Metadata for the {@link S3Object}.
*
*
* @author Adrian Cole
* @see <a href=
* "http://docs.amazonwebservices.com/AmazonS3/2006-03-01/UsingMetadata.html"
* />
* @author Adrian Cole
*
*/
public static class Metadata {
public static final Metadata NOT_FOUND = new Metadata("NOT_FOUND");
public static class Metadata implements Comparable<Metadata> {
public static final Metadata NOT_FOUND = new Metadata("NOT_FOUND");
// parsed during list, head, or get
private final String key;
private byte[] md5;
private volatile long size = -1;
// parsed during list, head, or get
private final String key;
private byte[] md5;
private volatile long size = -1;
// only parsed during head or get
private Multimap<String, String> allHeaders = HashMultimap.create();
private Multimap<String, String> userMetadata = HashMultimap.create();
private DateTime lastModified;
private String dataType = ContentTypes.BINARY;
private String cacheControl;
private String dataDisposition;
private String dataEncoding;
// only parsed during head or get
private Multimap<String, String> allHeaders = HashMultimap.create();
private Multimap<String, String> userMetadata = HashMultimap.create();
private DateTime lastModified;
private String dataType = ContentTypes.BINARY;
private String cacheControl;
private String dataDisposition;
private String dataEncoding;
// only parsed on list
private CanonicalUser owner = null;
private String storageClass = null;
// only parsed on list
private CanonicalUser owner = null;
private String storageClass = null;
/**
* @see #getKey()
* @param key
*/
public Metadata(String key) {
checkNotNull(key, "key");
checkArgument(!key.startsWith("/"), "keys cannot start with /");
this.key = key;
}
/**
* @param key
* @see #getKey()
*/
public Metadata(String key) {
checkNotNull(key, "key");
checkArgument(!key.startsWith("/"), "keys cannot start with /");
this.key = key;
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder();
sb.append("Metadata");
sb.append("{key='").append(key).append('\'');
sb.append(", lastModified=").append(lastModified);
sb.append(", md5=").append(
getMd5() == null ? "null" : Arrays.asList(getMd5())
.toString());
sb.append(", size=").append(size);
sb.append(", dataType='").append(dataType).append('\'');
sb.append('}');
return sb.toString();
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder();
sb.append("Metadata");
sb.append("{key='").append(key).append('\'');
sb.append(", lastModified=").append(lastModified);
sb.append(", md5=").append(
getMd5() == null ? "null" : Arrays.asList(getMd5())
.toString());
sb.append(", size=").append(size);
sb.append(", dataType='").append(dataType).append('\'');
sb.append('}');
return sb.toString();
}
@Override
public boolean equals(Object o) {
if (this == o)
return true;
if (!(o instanceof Metadata))
return false;
@Override
public boolean equals(Object o) {
if (this == o)
return true;
if (!(o instanceof Metadata))
return false;
Metadata metadata = (Metadata) o;
Metadata metadata = (Metadata) o;
if (size != metadata.size)
return false;
if (dataType != null ? !dataType.equals(metadata.dataType)
: metadata.dataType != null)
return false;
if (!key.equals(metadata.key))
return false;
if (lastModified != null ? !lastModified
.equals(metadata.lastModified)
: metadata.lastModified != null)
return false;
if (!Arrays.equals(getMd5(), metadata.getMd5()))
return false;
return true;
}
if (size != metadata.size)
return false;
if (dataType != null ? !dataType.equals(metadata.dataType)
: metadata.dataType != null)
return false;
if (!key.equals(metadata.key))
return false;
if (lastModified != null ? !lastModified
.equals(metadata.lastModified)
: metadata.lastModified != null)
return false;
if (!Arrays.equals(getMd5(), metadata.getMd5()))
return false;
return true;
}
@Override
public int hashCode() {
int result = key.hashCode();
result = 31 * result
+ (lastModified != null ? lastModified.hashCode() : 0);
result = 31 * result
+ (getMd5() != null ? Arrays.hashCode(getMd5()) : 0);
result = 31 * result + (int) (size ^ (size >>> 32));
result = 31 * result + (dataType != null ? dataType.hashCode() : 0);
return result;
}
@Override
public int hashCode() {
int result = key.hashCode();
result = 31 * result
+ (lastModified != null ? lastModified.hashCode() : 0);
result = 31 * result
+ (getMd5() != null ? Arrays.hashCode(getMd5()) : 0);
result = 31 * result + (int) (size ^ (size >>> 32));
result = 31 * result + (dataType != null ? dataType.hashCode() : 0);
return result;
}
/**
* The key is the handle that you assign to an object that allows you
* retrieve it later. A key is a sequence of Unicode characters whose
* UTF-8 encoding is at most 1024 bytes long. Each object in a bucket
* must have a unique key.
*
* @see <a href=
* "http://docs.amazonwebservices.com/AmazonS3/2006-03-01/UsingKeys.html"
* />
*/
public String getKey() {
return key;
}
/**
* The key is the handle that you assign to an object that allows you
* retrieve it later. A key is a sequence of Unicode characters whose
* UTF-8 encoding is at most 1024 bytes long. Each object in a bucket
* must have a unique key.
*
* @see <a href=
* "http://docs.amazonwebservices.com/AmazonS3/2006-03-01/UsingKeys.html"
* />
*/
public String getKey() {
return key;
}
public DateTime getLastModified() {
return lastModified;
}
public DateTime getLastModified() {
return lastModified;
}
public void setLastModified(DateTime lastModified) {
this.lastModified = lastModified;
}
public void setLastModified(DateTime lastModified) {
this.lastModified = lastModified;
}
/**
* The size of the object, in bytes.
*
* @see <a href=
* "http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html?sec14.13."
* />
*
* @return
*/
public long getSize() {
return size;
}
/**
* The size of the object, in bytes.
*
* @see <a href=
* "http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html?sec14.13."
* />
*/
public long getSize() {
return size;
}
public void setSize(long size) {
this.size = size;
}
public void setSize(long size) {
this.size = size;
}
/**
* A standard MIME type describing the format of the contents. If none
* is provided, the default is binary/octet-stream.
*
* @see <a href=
* "http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html?sec14.17."
* />
*
* @return
*/
public String getContentType() {
return dataType;
}
/**
* A standard MIME type describing the format of the contents. If none
* is provided, the default is binary/octet-stream.
* @see <a href=
* "http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html?sec14.17."
* />
*/
public String getContentType() {
return dataType;
}
public void setContentType(String dataType) {
this.dataType = dataType;
}
public void setContentType(String dataType) {
this.dataType = dataType;
}
public void setMd5(byte[] md5) {
this.md5 = md5;
}
public void setMd5(byte[] md5) {
this.md5 = Arrays.copyOf(md5, md5.length);
}
/**
* @return the md5 value stored in the Etag header returned by S3.
*/
public byte[] getMd5() {
return md5;
}
/**
* @return the md5 value stored in the Etag header returned by S3.
*/
public byte[] getMd5() {
return (md5 == null) ? null : Arrays.copyOf(md5, md5.length);
}
public void setUserMetadata(Multimap<String, String> userMetadata) {
this.userMetadata = userMetadata;
}
public void setUserMetadata(Multimap<String, String> userMetadata) {
this.userMetadata = userMetadata;
}
/**
*
* Any header starting with <code>x-amz-meta-</code> is considered user
* metadata. It will be stored with the object and returned when you
* retrieve the object. The total size of the HTTP request, not
* including the body, must be less than 8 KB.
*
*/
public Multimap<String, String> getUserMetadata() {
return userMetadata;
}
/**
* Any header starting with <code>x-amz-meta-</code> is considered user
* metadata. It will be stored with the object and returned when you
* retrieve the object. The total size of the HTTP request, not
* including the body, must be less than 8 KB.
*/
public Multimap<String, String> getUserMetadata() {
return userMetadata;
}
public void setOwner(CanonicalUser owner) {
this.owner = owner;
}
public void setOwner(CanonicalUser owner) {
this.owner = owner;
}
/**
* Every bucket and object in Amazon S3 has an owner, the user that
* created the bucket or object. The owner of a bucket or object cannot
* be changed. However, if the object is overwritten by another user
* (deleted and rewritten), the new object will have a new owner.
*/
public CanonicalUser getOwner() {
return owner;
}
/**
* Every bucket and object in Amazon S3 has an owner, the user that
* created the bucket or object. The owner of a bucket or object cannot
* be changed. However, if the object is overwritten by another user
* (deleted and rewritten), the new object will have a new owner.
*/
public CanonicalUser getOwner() {
return owner;
}
public void setStorageClass(String storageClass) {
this.storageClass = storageClass;
}
public void setStorageClass(String storageClass) {
this.storageClass = storageClass;
}
/**
* Currently defaults to 'STANDARD' and not used.
*/
public String getStorageClass() {
return storageClass;
}
/**
* Currently defaults to 'STANDARD' and not used.
*/
public String getStorageClass() {
return storageClass;
}
public void setCacheControl(String cacheControl) {
this.cacheControl = cacheControl;
}
public void setCacheControl(String cacheControl) {
this.cacheControl = cacheControl;
}
/**
* Can be used to specify caching behavior along the request/reply
* chain.
*
* @link http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html?sec14.9.
*/
public String getCacheControl() {
return cacheControl;
}
/**
* Can be used to specify caching behavior along the request/reply
* chain.
*
* @link http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html?sec14.9.
*/
public String getCacheControl() {
return cacheControl;
}
public void setContentDisposition(String dataDisposition) {
this.dataDisposition = dataDisposition;
}
public void setContentDisposition(String dataDisposition) {
this.dataDisposition = dataDisposition;
}
/**
* Specifies presentational information for the object.
*
* @see <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec19.html?sec19.5.1."/>
*/
public String getContentDisposition() {
return dataDisposition;
}
/**
* Specifies presentational information for the object.
*
* @see <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec19.html?sec19.5.1."/>
*/
public String getContentDisposition() {
return dataDisposition;
}
public void setContentEncoding(String dataEncoding) {
this.dataEncoding = dataEncoding;
}
public void setContentEncoding(String dataEncoding) {
this.dataEncoding = dataEncoding;
}
/**
* Specifies what content encodings have been applied to the object and
* thus what decoding mechanisms must be applied in order to obtain the
* media-type referenced by the Content-Type header field.
*
* @see <a href=
* "http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html?sec14.11"
* />
*/
public String getContentEncoding() {
return dataEncoding;
}
/**
* Specifies what content encodings have been applied to the object and
* thus what decoding mechanisms must be applied in order to obtain the
* media-type referenced by the Content-Type header field.
*
* @see <a href=
* "http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html?sec14.11"
* />
*/
public String getContentEncoding() {
return dataEncoding;
}
public void setAllHeaders(Multimap<String, String> allHeaders) {
this.allHeaders = allHeaders;
}
public void setAllHeaders(Multimap<String, String> allHeaders) {
this.allHeaders = allHeaders;
}
/**
*
* @return all http response headers associated with this S3Object
*/
public Multimap<String, String> getAllHeaders() {
return allHeaders;
}
/**
* @return all http response headers associated with this S3Object
*/
public Multimap<String, String> getAllHeaders() {
return allHeaders;
}
public int compareTo(Metadata o) {
return (this == o) ? 0 : getKey().compareTo(o.getKey());
}
}
/**
* @see Metadata#getKey()
*/
public String getKey() {
return metadata.getKey();
return metadata.getKey();
}
/**
* Sets payload for the request or the content from the response. If size
* isn't set, this will attempt to discover it.
*
* @param data
* typically InputStream for downloads, or File, byte [], String,
* or InputStream for uploads.
*
* @param data typically InputStream for downloads, or File, byte [], String,
* or InputStream for uploads.
*/
public void setData(Object data) {
this.data = checkNotNull(data, "data");
if (getMetadata().getSize() == -1)
this.getMetadata().setSize(S3Utils.calculateSize(data));
this.data = checkNotNull(data, "data");
if (getMetadata().getSize() == -1)
this.getMetadata().setSize(S3Utils.calculateSize(data));
}
/**
* generate an MD5 Hash for the current data.
*
* <p/>
* <h2>Note</h2>
* <p/>
* If this is an InputStream, it will be converted to a byte array first.
*
* @throws IOException
* if there is a problem generating the hash.
*
* @throws IOException if there is a problem generating the hash.
*/
public void generateMd5() throws IOException {
checkState(data != null, "data");
if (data instanceof InputStream) {
Md5InputStreamResult result = S3Utils
.generateMd5Result((InputStream) data);
getMetadata().setSize(result.length);
getMetadata().setMd5(result.md5);
setData(result.data);
} else {
getMetadata().setMd5(S3Utils.md5(data));
}
checkState(data != null, "data");
if (data instanceof InputStream) {
Md5InputStreamResult result = S3Utils
.generateMd5Result((InputStream) data);
getMetadata().setSize(result.length);
getMetadata().setMd5(result.md5);
setData(result.data);
} else {
getMetadata().setMd5(S3Utils.md5(data));
}
}
/**
*
* @return InputStream, if downloading, or whatever was set during
* {@link #setData(Object)}
*/
public Object getData() {
return data;
return data;
}
public void setMetadata(Metadata metadata) {
this.metadata = metadata;
this.metadata = metadata;
}
/**
*
* @return System and User metadata relevant to this object.
*/
public Metadata getMetadata() {
return metadata;
return metadata;
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder();
sb.append("S3Object");
sb.append("{metadata=").append(metadata);
sb.append('}');
return sb.toString();
final StringBuilder sb = new StringBuilder();
sb.append("S3Object");
sb.append("{metadata=").append(metadata);
sb.append('}');
return sb.toString();
}
@Override
public boolean equals(Object o) {
if (this == o)
return true;
if (!(o instanceof S3Object))
return false;
if (this == o)
return true;
if (!(o instanceof S3Object))
return false;
S3Object s3Object = (S3Object) o;
S3Object s3Object = (S3Object) o;
if (data != null ? !data.equals(s3Object.data) : s3Object.data != null)
return false;
if (!metadata.equals(s3Object.metadata))
return false;
if (data != null ? !data.equals(s3Object.data) : s3Object.data != null)
return false;
if (!metadata.equals(s3Object.metadata))
return false;
return true;
return true;
}
@Override
public int hashCode() {
int result = data != null ? data.hashCode() : 0;
result = 31 * result + metadata.hashCode();
return result;
int result = data != null ? data.hashCode() : 0;
result = 31 * result + metadata.hashCode();
return result;
}
public void setContentLength(long contentLength) {
this.contentLength = contentLength;
this.contentLength = contentLength;
}
/**
@ -443,30 +430,29 @@ public class S3Object {
* Chunking is only used when
* {@link org.jclouds.aws.s3.S3Connection#getObject(String, String, org.jclouds.aws.s3.commands.options.GetObjectOptions) }
* is called with options like tail, range, or startAt.
*
* @see org.jclouds.http.HttpHeaders#CONTENT_LENGTH
* @see GetObjectOptions
*
* @return the length in bytes that can be be obtained from
* {@link #getData()}
*
* @see org.jclouds.http.HttpHeaders#CONTENT_LENGTH
* @see GetObjectOptions
*/
public long getContentLength() {
return contentLength;
return contentLength;
}
public void setContentRange(String contentRange) {
this.contentRange = contentRange;
this.contentRange = contentRange;
}
/**
* If this is not-null, {@link #getContentLength() } will the size of chunk
* of the S3Object available via {@link #getData()}
*
*
* @see org.jclouds.http.HttpHeaders#CONTENT_RANGE
* @see GetObjectOptions
*/
public String getContentRange() {
return contentRange;
return contentRange;
}
}

View File

@ -24,19 +24,9 @@
package org.jclouds.aws.s3.internal;
import static com.google.common.base.Preconditions.checkNotNull;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;
import com.google.inject.name.Named;
import org.jclouds.aws.s3.S3Connection;
import org.jclouds.aws.s3.S3Map;
import org.jclouds.aws.s3.domain.S3Bucket;
@ -44,20 +34,23 @@ import org.jclouds.aws.s3.domain.S3Object;
import org.jclouds.aws.s3.reference.S3Constants;
import org.jclouds.util.Utils;
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;
import com.google.inject.name.Named;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
/**
* Implements core Map functionality with an {@link S3Connection}
* <p/>
* All commands will wait a maximum of ${jclouds.s3.map.timeout} milliseconds to
* complete before throwing an exception.
*
*
* @author Adrian Cole
*
* @param <V>
* value of the map
* value of the map
*/
public abstract class BaseS3Map<V> implements S3Map<String, V> {
@ -73,172 +66,171 @@ public abstract class BaseS3Map<V> implements S3Map<String, V> {
@Inject
public BaseS3Map(S3Connection connection, @Assisted String bucket) {
this.connection = checkNotNull(connection, "connection");
this.bucket = checkNotNull(bucket, "bucket");
this.connection = checkNotNull(connection, "connection");
this.bucket = checkNotNull(bucket, "bucketName");
}
/**
* {@inheritDoc}
* <p/>
* This returns the number of keys in the {@link S3Bucket}
*
*
* @see S3Bucket#getContents()
*/
public int size() {
try {
S3Bucket bucket = refreshBucket();
Set<S3Object.Metadata> contents = bucket.getContents();
return contents.size();
} catch (Exception e) {
Utils.<S3RuntimeException> rethrowIfRuntimeOrSameType(e);
throw new S3RuntimeException("Error getting size of bucket"
+ bucket, e);
}
try {
S3Bucket bucket = refreshBucket();
Set<S3Object.Metadata> contents = bucket.getContents();
return contents.size();
} catch (Exception e) {
Utils.<S3RuntimeException>rethrowIfRuntimeOrSameType(e);
throw new S3RuntimeException("Error getting size of bucketName"
+ bucket, e);
}
}
protected boolean containsMd5(byte[] md5) throws InterruptedException,
ExecutionException, TimeoutException {
for (S3Object.Metadata metadata : refreshBucket().getContents()) {
if (Arrays.equals(md5, metadata.getMd5()))
return true;
}
return false;
ExecutionException, TimeoutException {
for (S3Object.Metadata metadata : refreshBucket().getContents()) {
if (Arrays.equals(md5, metadata.getMd5()))
return true;
}
return false;
}
protected byte[] getMd5(Object value) throws IOException,
FileNotFoundException, InterruptedException, ExecutionException,
TimeoutException {
S3Object object = null;
if (value instanceof S3Object) {
object = (S3Object) value;
} else {
object = new S3Object("dummy", value);
}
if (object.getMetadata().getMd5() == null)
object.generateMd5();
return object.getMetadata().getMd5();
FileNotFoundException, InterruptedException, ExecutionException,
TimeoutException {
S3Object object = null;
if (value instanceof S3Object) {
object = (S3Object) value;
} else {
object = new S3Object("dummy", value);
}
if (object.getMetadata().getMd5() == null)
object.generateMd5();
return object.getMetadata().getMd5();
}
/**
* attempts asynchronous gets on all objects.
*
*
* @see S3Connection#getObject(String, String)
*/
protected Set<S3Object> getAllObjects() {
Set<S3Object> objects = new HashSet<S3Object>();
Set<Future<S3Object>> futureObjects = new HashSet<Future<S3Object>>();
for (String key : keySet()) {
futureObjects.add(connection.getObject(bucket, key));
}
for (Future<S3Object> futureObject : futureObjects) {
S3Object object = null;
try {
object = futureObject.get(requestTimeoutMilliseconds,
TimeUnit.MILLISECONDS);
} catch (Exception e) {
Utils.<S3RuntimeException> rethrowIfRuntimeOrSameType(e);
throw new S3RuntimeException(String.format(
"Error getting value from bucket %1$s:%2$s", bucket,
object != null ? object.getKey() : "unknown"), e);
}
if (object != S3Object.NOT_FOUND)
objects.add(object);
}
return objects;
Set<S3Object> objects = new HashSet<S3Object>();
Set<Future<S3Object>> futureObjects = new HashSet<Future<S3Object>>();
for (String key : keySet()) {
futureObjects.add(connection.getObject(bucket, key));
}
for (Future<S3Object> futureObject : futureObjects) {
S3Object object = null;
try {
object = futureObject.get(requestTimeoutMilliseconds,
TimeUnit.MILLISECONDS);
} catch (Exception e) {
Utils.<S3RuntimeException>rethrowIfRuntimeOrSameType(e);
throw new S3RuntimeException(String.format(
"Error getting value from bucket %1$s", bucket), e);
}
if (object != S3Object.NOT_FOUND)
objects.add(object);
}
return objects;
}
/**
* {@inheritDoc}
*
* <p/>
* Note that if value is an instance of InputStream, it will be read and
* closed following this method. To reuse data from InputStreams, pass
* {@link InputStream}s inside {@link S3Object}s
* {@link java.io.InputStream}s inside {@link S3Object}s
*/
public boolean containsValue(Object value) {
try {
byte[] md5 = getMd5(value);
return containsMd5(md5);
} catch (Exception e) {
Utils.<S3RuntimeException> rethrowIfRuntimeOrSameType(e);
throw new S3RuntimeException(String.format(
"Error searching for ETAG of value: [%2$s] in bucket:%1$s",
bucket, value), e);
}
try {
byte[] md5 = getMd5(value);
return containsMd5(md5);
} catch (Exception e) {
Utils.<S3RuntimeException>rethrowIfRuntimeOrSameType(e);
throw new S3RuntimeException(String.format(
"Error searching for ETAG of value: [%2$s] in bucketName:%1$s",
bucket, value), e);
}
}
public static class S3RuntimeException extends RuntimeException {
private static final long serialVersionUID = 1L;
private static final long serialVersionUID = 1L;
S3RuntimeException(String s) {
super(s);
}
S3RuntimeException(String s) {
super(s);
}
public S3RuntimeException(String s, Throwable throwable) {
super(s, throwable);
}
public S3RuntimeException(String s, Throwable throwable) {
super(s, throwable);
}
}
public void clear() {
try {
List<Future<Boolean>> deletes = new ArrayList<Future<Boolean>>();
for (String key : keySet()) {
deletes.add(connection.deleteObject(bucket, key));
}
for (Future<Boolean> isdeleted : deletes)
if (!isdeleted.get(requestTimeoutMilliseconds,
TimeUnit.MILLISECONDS)) {
throw new S3RuntimeException("failed to delete entry");
}
} catch (Exception e) {
Utils.<S3RuntimeException> rethrowIfRuntimeOrSameType(e);
throw new S3RuntimeException("Error clearing bucket" + bucket, e);
}
try {
List<Future<Boolean>> deletes = new ArrayList<Future<Boolean>>();
for (String key : keySet()) {
deletes.add(connection.deleteObject(bucket, key));
}
for (Future<Boolean> isdeleted : deletes)
if (!isdeleted.get(requestTimeoutMilliseconds,
TimeUnit.MILLISECONDS)) {
throw new S3RuntimeException("failed to delete entry");
}
} catch (Exception e) {
Utils.<S3RuntimeException>rethrowIfRuntimeOrSameType(e);
throw new S3RuntimeException("Error clearing bucketName" + bucket, e);
}
}
protected S3Bucket refreshBucket() throws InterruptedException,
ExecutionException, TimeoutException {
S3Bucket currentBucket = connection.listBucket(bucket).get(
requestTimeoutMilliseconds, TimeUnit.MILLISECONDS);
if (currentBucket == S3Bucket.NOT_FOUND)
throw new S3RuntimeException("bucket not found: " + bucket);
else
return currentBucket;
ExecutionException, TimeoutException {
S3Bucket currentBucket = connection.listBucket(bucket).get(
requestTimeoutMilliseconds, TimeUnit.MILLISECONDS);
if (currentBucket == S3Bucket.NOT_FOUND)
throw new S3RuntimeException("bucketName not found: " + bucket);
else
return currentBucket;
}
public Set<String> keySet() {
try {
Set<String> keys = new HashSet<String>();
for (S3Object.Metadata object : refreshBucket().getContents())
keys.add(object.getKey());
return keys;
} catch (Exception e) {
Utils.<S3RuntimeException> rethrowIfRuntimeOrSameType(e);
throw new S3RuntimeException("Error getting keys in bucket: "
+ bucket, e);
}
try {
Set<String> keys = new HashSet<String>();
for (S3Object.Metadata object : refreshBucket().getContents())
keys.add(object.getKey());
return keys;
} catch (Exception e) {
Utils.<S3RuntimeException>rethrowIfRuntimeOrSameType(e);
throw new S3RuntimeException("Error getting keys in bucketName: "
+ bucket, e);
}
}
public boolean containsKey(Object key) {
try {
return connection.headObject(bucket, key.toString()).get(
requestTimeoutMilliseconds, TimeUnit.MILLISECONDS) != S3Object.Metadata.NOT_FOUND;
} catch (Exception e) {
Utils.<S3RuntimeException> rethrowIfRuntimeOrSameType(e);
throw new S3RuntimeException(String.format(
"Error searching for %1$s:%2$s", bucket, key), e);
}
try {
return connection.headObject(bucket, key.toString()).get(
requestTimeoutMilliseconds, TimeUnit.MILLISECONDS) != S3Object.Metadata.NOT_FOUND;
} catch (Exception e) {
Utils.<S3RuntimeException>rethrowIfRuntimeOrSameType(e);
throw new S3RuntimeException(String.format(
"Error searching for %1$s:%2$s", bucket, key), e);
}
}
public boolean isEmpty() {
return keySet().size() == 0;
return keySet().size() == 0;
}
public S3Bucket getBucket() {
try {
return refreshBucket();
} catch (Exception e) {
Utils.<S3RuntimeException> rethrowIfRuntimeOrSameType(e);
throw new S3RuntimeException("Error getting bucket" + bucket, e);
}
try {
return refreshBucket();
} catch (Exception e) {
Utils.<S3RuntimeException>rethrowIfRuntimeOrSameType(e);
throw new S3RuntimeException("Error getting bucketName" + bucket, e);
}
}
}

View File

@ -23,10 +23,8 @@
*/
package org.jclouds.aws.s3.internal;
import java.io.IOException;
import javax.annotation.Resource;
import com.google.inject.Inject;
import com.google.inject.Injector;
import org.jclouds.aws.s3.S3Connection;
import org.jclouds.aws.s3.S3Context;
import org.jclouds.aws.s3.S3InputStreamMap;
@ -34,22 +32,22 @@ import org.jclouds.aws.s3.S3ObjectMap;
import org.jclouds.lifecycle.Closer;
import org.jclouds.logging.Logger;
import com.google.inject.Inject;
import com.google.inject.Injector;
import javax.annotation.Resource;
import java.io.IOException;
/**
* Uses a Guice Injector to configure the objects served by S3Context methods.
*
* @see Injector
*
* @author Adrian Cole
* @see Injector
*/
public class GuiceS3Context implements S3Context {
public interface S3ObjectMapFactory {
S3ObjectMap createMapView(String bucket);
S3ObjectMap createMapView(String bucket);
}
public interface S3InputStreamMapFactory {
S3InputStreamMap createMapView(String bucket);
S3InputStreamMap createMapView(String bucket);
}
@Resource
@ -61,48 +59,48 @@ public class GuiceS3Context implements S3Context {
@Inject
private GuiceS3Context(Injector injector, Closer closer,
S3ObjectMapFactory s3ObjectMapFactory,
S3InputStreamMapFactory s3InputStreamMapFactory) {
this.injector = injector;
this.s3InputStreamMapFactory = s3InputStreamMapFactory;
this.s3ObjectMapFactory = s3ObjectMapFactory;
this.closer = closer;
S3ObjectMapFactory s3ObjectMapFactory,
S3InputStreamMapFactory s3InputStreamMapFactory) {
this.injector = injector;
this.s3InputStreamMapFactory = s3InputStreamMapFactory;
this.s3ObjectMapFactory = s3ObjectMapFactory;
this.closer = closer;
}
/**
* {@inheritDoc}
*/
public S3Connection getConnection() {
return injector.getInstance(S3Connection.class);
return injector.getInstance(S3Connection.class);
}
/**
* {@inheritDoc}
*/
public S3InputStreamMap createInputStreamMap(String bucket) {
getConnection().putBucketIfNotExists(bucket);
return s3InputStreamMapFactory.createMapView(bucket);
getConnection().putBucketIfNotExists(bucket);
return s3InputStreamMapFactory.createMapView(bucket);
}
/**
* {@inheritDoc}
*/
public S3ObjectMap createS3ObjectMap(String bucket) {
getConnection().putBucketIfNotExists(bucket);
return s3ObjectMapFactory.createMapView(bucket);
getConnection().putBucketIfNotExists(bucket);
return s3ObjectMapFactory.createMapView(bucket);
}
/**
* {@inheritDoc}
*
*
* @see Closer
*/
public void close() {
try {
closer.close();
} catch (IOException e) {
logger.error(e, "error closing content");
}
try {
closer.close();
} catch (IOException e) {
logger.error(e, "error closing content");
}
}
}

View File

@ -23,260 +23,249 @@
*/
package org.jclouds.aws.s3.internal;
import java.io.File;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import com.google.common.annotations.VisibleForTesting;
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;
import org.jclouds.aws.s3.S3Connection;
import org.jclouds.aws.s3.S3InputStreamMap;
import org.jclouds.aws.s3.domain.S3Object;
import org.jclouds.util.Utils;
import com.google.common.annotations.VisibleForTesting;
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;
import java.io.File;
import java.io.InputStream;
import java.util.*;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
/**
* Map representation of a live connection to S3. All put operations will result
* in Md5 calculation. If this is not desired, use {@link LiveS3ObjectMap}
* instead.
*
*
* @author Adrian Cole
* @see S3Connection
* @see BaseS3Map
* @author Adrian Cole
*/
public class LiveS3InputStreamMap extends BaseS3Map<InputStream> implements
S3InputStreamMap {
S3InputStreamMap {
@Inject
public LiveS3InputStreamMap(S3Connection connection, @Assisted String bucket) {
super(connection, bucket);
super(connection, bucket);
}
/**
* {@inheritDoc}
*
*
* @see S3Connection#getObject(String, String)
*/
public InputStream get(Object o) {
try {
return (InputStream) (connection.getObject(bucket, o.toString())
.get(requestTimeoutMilliseconds, TimeUnit.MILLISECONDS))
.getData();
} catch (Exception e) {
Utils.<S3RuntimeException> rethrowIfRuntimeOrSameType(e);
throw new S3RuntimeException(String.format(
"Error geting object %1$s:%2$s", bucket, o), e);
}
try {
return (InputStream) (connection.getObject(bucket, o.toString())
.get(requestTimeoutMilliseconds, TimeUnit.MILLISECONDS))
.getData();
} catch (Exception e) {
Utils.<S3RuntimeException>rethrowIfRuntimeOrSameType(e);
throw new S3RuntimeException(String.format(
"Error geting object %1$s:%2$s", bucket, o), e);
}
}
/**
* {@inheritDoc}
*
*
* @see S3Connection#deleteObject(String, String)
*/
public InputStream remove(Object o) {
InputStream old = get(o);
try {
connection.deleteObject(bucket, o.toString()).get(
requestTimeoutMilliseconds, TimeUnit.MILLISECONDS);
} catch (Exception e) {
Utils.<S3RuntimeException> rethrowIfRuntimeOrSameType(e);
throw new S3RuntimeException(String.format(
"Error removing object %1$s:%2$s", bucket, o), e);
}
return old;
InputStream old = get(o);
try {
connection.deleteObject(bucket, o.toString()).get(
requestTimeoutMilliseconds, TimeUnit.MILLISECONDS);
} catch (Exception e) {
Utils.<S3RuntimeException>rethrowIfRuntimeOrSameType(e);
throw new S3RuntimeException(String.format(
"Error removing object %1$s:%2$s", bucket, o), e);
}
return old;
}
/**
* {@inheritDoc}
*
*
* @see #getAllObjects()
*/
public Collection<InputStream> values() {
Collection<InputStream> values = new LinkedList<InputStream>();
Set<S3Object> objects = getAllObjects();
for (S3Object object : objects) {
values.add((InputStream) object.getData());
}
return values;
Collection<InputStream> values = new LinkedList<InputStream>();
Set<S3Object> objects = getAllObjects();
for (S3Object object : objects) {
values.add((InputStream) object.getData());
}
return values;
}
/**
* {@inheritDoc}
*
*
* @see #getAllObjects()
*/
public Set<Map.Entry<String, InputStream>> entrySet() {
Set<Map.Entry<String, InputStream>> entrySet = new HashSet<Map.Entry<String, InputStream>>();
for (S3Object object : getAllObjects()) {
entrySet.add(new Entry(object.getKey(), (InputStream) object
.getData()));
}
return entrySet;
Set<Map.Entry<String, InputStream>> entrySet = new HashSet<Map.Entry<String, InputStream>>();
for (S3Object object : getAllObjects()) {
entrySet.add(new Entry(object.getKey(), (InputStream) object
.getData()));
}
return entrySet;
}
/**
* {@inheritDoc}
*/
public class Entry implements java.util.Map.Entry<String, InputStream> {
private InputStream value;
private String key;
private InputStream value;
private String key;
Entry(String key, InputStream value) {
this.key = key;
this.value = value;
}
Entry(String key, InputStream value) {
this.key = key;
this.value = value;
}
public String getKey() {
return key;
}
public String getKey() {
return key;
}
public InputStream getValue() {
return value;
}
public InputStream getValue() {
return value;
}
/**
* {@inheritDoc}
*
* @see LiveS3InputStreamMap#put(String, InputStream)
*/
public InputStream setValue(InputStream value) {
return put(key, value);
}
/**
* {@inheritDoc}
*
* @see LiveS3InputStreamMap#put(String, InputStream)
*/
public InputStream setValue(InputStream value) {
return put(key, value);
}
}
/**
* {@inheritDoc}
*
*
* @see #putAllInternal(Map)
*/
public void putAll(Map<? extends String, ? extends InputStream> map) {
putAllInternal(map);
putAllInternal(map);
}
/**
* {@inheritDoc}
*
*
* @see #putAllInternal(Map)
*/
public void putAllBytes(Map<? extends String, ? extends byte[]> map) {
putAllInternal(map);
putAllInternal(map);
}
/**
* {@inheritDoc}
*
*
* @see #putAllInternal(Map)
*/
public void putAllFiles(Map<? extends String, ? extends File> map) {
putAllInternal(map);
putAllInternal(map);
}
/**
* {@inheritDoc}
*
*
* @see #putAllInternal(Map)
*/
public void putAllStrings(Map<? extends String, ? extends String> map) {
putAllInternal(map);
putAllInternal(map);
}
/**
* submits requests to add all objects and collects the results later. All
* values will have md5 calculated first. As a side-effect of this, the
* content will be copied into a byte [].
*
*
* @see S3Connection#putObject(String, S3Object)
*/
@VisibleForTesting
void putAllInternal(Map<? extends String, ? extends Object> map) {
try {
List<Future<byte[]>> puts = new ArrayList<Future<byte[]>>();
for (String key : map.keySet()) {
S3Object object = new S3Object(key);
object.setData(map.get(key));
object.generateMd5();
puts.add(connection.putObject(bucket, object));
}
for (Future<byte[]> put : puts)
// this will throw an exception if there was a problem
put.get(requestTimeoutMilliseconds, TimeUnit.MILLISECONDS);
} catch (Exception e) {
Utils.<S3RuntimeException> rethrowIfRuntimeOrSameType(e);
throw new S3RuntimeException("Error putting into bucket" + bucket,
e);
}
try {
List<Future<byte[]>> puts = new ArrayList<Future<byte[]>>();
for (Map.Entry<? extends String, ? extends Object> entry : map.entrySet()) {
S3Object object = new S3Object(entry.getKey());
object.setData(entry.getValue());
object.generateMd5();
puts.add(connection.putObject(bucket, object));
}
for (Future<byte[]> put : puts)
// this will throw an exception if there was a problem
put.get(requestTimeoutMilliseconds, TimeUnit.MILLISECONDS);
} catch (Exception e) {
Utils.<S3RuntimeException>rethrowIfRuntimeOrSameType(e);
throw new S3RuntimeException("Error putting into bucketName" + bucket,
e);
}
}
/**
* {@inheritDoc}
*
*
* @see #putInternal(String, Object)
*/
public InputStream putString(String key, String value) {
return putInternal(key, value);
return putInternal(key, value);
}
/**
* {@inheritDoc}
*
*
* @see #putInternal(String, Object)
*/
public InputStream putFile(String key, File value) {
return putInternal(key, value);
return putInternal(key, value);
}
/**
* {@inheritDoc}
*
*
* @see #putInternal(String, Object)
*/
public InputStream putBytes(String key, byte[] value) {
return putInternal(key, value);
return putInternal(key, value);
}
/**
* {@inheritDoc}
*
*
* @see #putInternal(String, Object)
*/
public InputStream put(String key, InputStream value) {
return putInternal(key, value);
return putInternal(key, value);
}
/**
*
* calculates md5 before adding the object to s3. As a side-effect of this,
* the content will be copied into a byte []. *
*
*
* @see S3Connection#putObject(String, S3Object)
*/
@VisibleForTesting
InputStream putInternal(String s, Object o) {
S3Object object = new S3Object(s);
try {
InputStream returnVal = containsKey(s) ? get(s) : null;
object.setData(o);
object.generateMd5();
connection.putObject(bucket, object).get(
requestTimeoutMilliseconds, TimeUnit.MILLISECONDS);
return returnVal;
} catch (Exception e) {
Utils.<S3RuntimeException> rethrowIfRuntimeOrSameType(e);
throw new S3RuntimeException(String.format(
"Error adding object %1$s:%2$s", bucket, object), e);
}
S3Object object = new S3Object(s);
try {
InputStream returnVal = containsKey(s) ? get(s) : null;
object.setData(o);
object.generateMd5();
connection.putObject(bucket, object).get(
requestTimeoutMilliseconds, TimeUnit.MILLISECONDS);
return returnVal;
} catch (Exception e) {
Utils.<S3RuntimeException>rethrowIfRuntimeOrSameType(e);
throw new S3RuntimeException(String.format(
"Error adding object %1$s:%2$s", bucket, object), e);
}
}
}

View File

@ -127,7 +127,7 @@ public class LiveS3ObjectMap extends BaseS3Map<S3Object> implements S3ObjectMap
} catch (Exception e) {
Utils.<S3RuntimeException> rethrowIfRuntimeOrSameType(e);
throw new S3RuntimeException(
String.format("Error putting object %1$s:%2$s%n%1$s",
String.format("Error putting object %1$s:%2$s%n%3$s",
bucket, key, value), e);
}
return returnVal;
@ -149,7 +149,7 @@ public class LiveS3ObjectMap extends BaseS3Map<S3Object> implements S3ObjectMap
put.get(requestTimeoutMilliseconds, TimeUnit.MILLISECONDS);
} catch (Exception e) {
Utils.<S3RuntimeException> rethrowIfRuntimeOrSameType(e);
throw new S3RuntimeException("Error putting into bucket" + bucket,
throw new S3RuntimeException("Error putting into bucketName" + bucket,
e);
}
}

View File

@ -22,8 +22,8 @@
* ====================================================================
*/
/**
* This package contains an Amazon S3 client implemented by {@link HttpFutureCommand} commands.
*
* This package contains an Amazon S3 client implemented by {@link org.jclouds.http.HttpFutureCommandClient} commands.
*
* @see <a href="http://aws.amazon.com/s3"/>
* @author Adrian Cole
*/

View File

@ -25,17 +25,6 @@ package org.jclouds.aws.s3.util;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.util.regex.Pattern;
import org.apache.commons.io.IOUtils;
import org.apache.commons.io.output.ByteArrayOutputStream;
import org.bouncycastle.crypto.digests.MD5Digest;
@ -46,205 +35,211 @@ import org.bouncycastle.util.encoders.Base64;
import org.jclouds.aws.s3.domain.S3Object;
import org.jclouds.util.Utils;
import java.io.*;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.util.regex.Pattern;
/**
* Encryption, Hashing, and IO Utilities needed to sign and verify S3 requests
* and responses.
*
*
* @author Adrian Cole
*
*/
public class S3Utils extends Utils {
private static final Pattern IP_PATTERN = Pattern
.compile("b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).)"
+ "{3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)b");
.compile("b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).)"
+ "{3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)b");
public static String validateBucketName(String bucketName) {
checkNotNull(bucketName, "bucketName");
checkArgument(bucketName.matches("^[a-z0-9].*"),
"bucket name must start with a number or letter");
checkArgument(
bucketName.matches("^[-_.a-z0-9]+"),
"bucket name can only contain lowercase letters, numbers, periods (.), underscores (_), and dashes (-)");
checkArgument(bucketName.length() > 2 && bucketName.length() < 256,
"bucket name must be between 3 and 255 characters long");
checkArgument(!IP_PATTERN.matcher(bucketName).matches(),
"bucket name cannot be ip address style");
return bucketName;
checkNotNull(bucketName, "bucketName");
checkArgument(bucketName.matches("^[a-z0-9].*"),
"bucketName name must start with a number or letter");
checkArgument(
bucketName.matches("^[-_.a-z0-9]+"),
"bucketName name can only contain lowercase letters, numbers, periods (.), underscores (_), and dashes (-)");
checkArgument(bucketName.length() > 2 && bucketName.length() < 256,
"bucketName name must be between 3 and 255 characters long");
checkArgument(!IP_PATTERN.matcher(bucketName).matches(),
"bucketName name cannot be ip address style");
return bucketName;
}
static final byte[] HEX_CHAR_TABLE = { (byte) '0', (byte) '1', (byte) '2',
(byte) '3', (byte) '4', (byte) '5', (byte) '6', (byte) '7',
(byte) '8', (byte) '9', (byte) 'a', (byte) 'b', (byte) 'c',
(byte) 'd', (byte) 'e', (byte) 'f' };
static final byte[] HEX_CHAR_TABLE = {(byte) '0', (byte) '1', (byte) '2',
(byte) '3', (byte) '4', (byte) '5', (byte) '6', (byte) '7',
(byte) '8', (byte) '9', (byte) 'a', (byte) 'b', (byte) 'c',
(byte) 'd', (byte) 'e', (byte) 'f'};
public static String toHexString(byte[] raw)
throws UnsupportedEncodingException {
byte[] hex = new byte[2 * raw.length];
int index = 0;
throws UnsupportedEncodingException {
byte[] hex = new byte[2 * raw.length];
int index = 0;
for (byte b : raw) {
int v = b & 0xFF;
hex[index++] = HEX_CHAR_TABLE[v >>> 4];
hex[index++] = HEX_CHAR_TABLE[v & 0xF];
}
return new String(hex, "ASCII");
for (byte b : raw) {
int v = b & 0xFF;
hex[index++] = HEX_CHAR_TABLE[v >>> 4];
hex[index++] = HEX_CHAR_TABLE[v & 0xF];
}
return new String(hex, "ASCII");
}
public static long calculateSize(Object data) {
long size = -1;
if (data instanceof byte[]) {
size = ((byte[]) data).length;
} else if (data instanceof String) {
size = ((String) data).length();
} else if (data instanceof File) {
size = ((File) data).length();
}
return size;
long size = -1;
if (data instanceof byte[]) {
size = ((byte[]) data).length;
} else if (data instanceof String) {
size = ((String) data).length();
} else if (data instanceof File) {
size = ((File) data).length();
}
return size;
}
/**
*
* @throws IOException
*/
public static byte[] md5(Object data) throws IOException {
checkNotNull(data, "data must be set before calling generateMd5()");
byte[] md5 = null;
if (data == null || data instanceof byte[]) {
md5 = S3Utils.md5((byte[]) data);
} else if (data instanceof String) {
md5 = S3Utils.md5(((String) data).getBytes());
} else if (data instanceof File) {
md5 = S3Utils.md5(((File) data));
} else {
throw new UnsupportedOperationException("Content not supported "
+ data.getClass());
}
return md5;
checkNotNull(data, "data must be set before calling generateMd5()");
byte[] md5 = null;
if (data == null) {
} else if (data instanceof byte[]) {
md5 = S3Utils.md5((byte[]) data);
} else if (data instanceof String) {
md5 = S3Utils.md5(((String) data).getBytes());
} else if (data instanceof File) {
md5 = S3Utils.md5(((File) data));
} else {
throw new UnsupportedOperationException("Content not supported "
+ data.getClass());
}
return md5;
}
public static byte[] fromHexString(String hex) {
byte[] bytes = new byte[hex.length() / 2];
for (int i = 0; i < bytes.length; i++) {
bytes[i] = (byte) Integer.parseInt(hex.substring(2 * i, 2 * i + 2),
16);
}
return bytes;
byte[] bytes = new byte[hex.length() / 2];
for (int i = 0; i < bytes.length; i++) {
bytes[i] = (byte) Integer.parseInt(hex.substring(2 * i, 2 * i + 2),
16);
}
return bytes;
}
public static String hmacSha1Base64(String toEncode, byte[] key)
throws NoSuchAlgorithmException, NoSuchProviderException,
InvalidKeyException {
HMac hmac = new HMac(new SHA1Digest());
byte[] resBuf = new byte[hmac.getMacSize()];
byte[] plainBytes = toEncode.getBytes();
byte[] keyBytes = key;
hmac.init(new KeyParameter(keyBytes));
hmac.update(plainBytes, 0, plainBytes.length);
hmac.doFinal(resBuf, 0);
return toBase64String(resBuf);
throws NoSuchAlgorithmException, NoSuchProviderException,
InvalidKeyException {
HMac hmac = new HMac(new SHA1Digest());
byte[] resBuf = new byte[hmac.getMacSize()];
byte[] plainBytes = toEncode.getBytes();
byte[] keyBytes = key;
hmac.init(new KeyParameter(keyBytes));
hmac.update(plainBytes, 0, plainBytes.length);
hmac.doFinal(resBuf, 0);
return toBase64String(resBuf);
}
public static String md5Hex(byte[] toEncode)
throws NoSuchAlgorithmException, NoSuchProviderException,
InvalidKeyException, UnsupportedEncodingException {
byte[] resBuf = md5(toEncode);
return toHexString(resBuf);
throws NoSuchAlgorithmException, NoSuchProviderException,
InvalidKeyException, UnsupportedEncodingException {
byte[] resBuf = md5(toEncode);
return toHexString(resBuf);
}
public static String md5Base64(byte[] toEncode)
throws NoSuchAlgorithmException, NoSuchProviderException,
InvalidKeyException {
byte[] resBuf = md5(toEncode);
return toBase64String(resBuf);
throws NoSuchAlgorithmException, NoSuchProviderException,
InvalidKeyException {
byte[] resBuf = md5(toEncode);
return toBase64String(resBuf);
}
public static String toBase64String(byte[] resBuf) {
return new String(Base64.encode(resBuf));
return new String(Base64.encode(resBuf));
}
public static byte[] md5(byte[] plainBytes) {
MD5Digest md5 = new MD5Digest();
byte[] resBuf = new byte[md5.getDigestSize()];
md5.update(plainBytes, 0, plainBytes.length);
md5.doFinal(resBuf, 0);
return resBuf;
MD5Digest md5 = new MD5Digest();
byte[] resBuf = new byte[md5.getDigestSize()];
md5.update(plainBytes, 0, plainBytes.length);
md5.doFinal(resBuf, 0);
return resBuf;
}
public static byte[] md5(File toEncode) throws IOException {
MD5Digest md5 = new MD5Digest();
byte[] resBuf = new byte[md5.getDigestSize()];
byte[] buffer = new byte[1024];
int numRead = -1;
InputStream i = new FileInputStream(toEncode);
try {
do {
numRead = i.read(buffer);
if (numRead > 0) {
md5.update(buffer, 0, numRead);
}
} while (numRead != -1);
} finally {
IOUtils.closeQuietly(i);
}
md5.doFinal(resBuf, 0);
return resBuf;
MD5Digest md5 = new MD5Digest();
byte[] resBuf = new byte[md5.getDigestSize()];
byte[] buffer = new byte[1024];
int numRead = -1;
InputStream i = new FileInputStream(toEncode);
try {
do {
numRead = i.read(buffer);
if (numRead > 0) {
md5.update(buffer, 0, numRead);
}
} while (numRead != -1);
} finally {
IOUtils.closeQuietly(i);
}
md5.doFinal(resBuf, 0);
return resBuf;
}
public static Md5InputStreamResult generateMd5Result(InputStream toEncode)
throws IOException {
MD5Digest md5 = new MD5Digest();
byte[] resBuf = new byte[md5.getDigestSize()];
byte[] buffer = new byte[1024];
ByteArrayOutputStream out = new ByteArrayOutputStream();
long length = 0;
int numRead = -1;
try {
do {
numRead = toEncode.read(buffer);
if (numRead > 0) {
length += numRead;
md5.update(buffer, 0, numRead);
out.write(buffer, 0, numRead);
}
} while (numRead != -1);
} finally {
IOUtils.closeQuietly(toEncode);
}
md5.doFinal(resBuf, 0);
return new Md5InputStreamResult(out.toByteArray(), resBuf, length);
throws IOException {
MD5Digest md5 = new MD5Digest();
byte[] resBuf = new byte[md5.getDigestSize()];
byte[] buffer = new byte[1024];
ByteArrayOutputStream out = new ByteArrayOutputStream();
long length = 0;
int numRead = -1;
try {
do {
numRead = toEncode.read(buffer);
if (numRead > 0) {
length += numRead;
md5.update(buffer, 0, numRead);
out.write(buffer, 0, numRead);
}
} while (numRead != -1);
} finally {
out.close();
IOUtils.closeQuietly(toEncode);
}
md5.doFinal(resBuf, 0);
return new Md5InputStreamResult(out.toByteArray(), resBuf, length);
}
public static class Md5InputStreamResult {
public final byte[] data;
public final byte[] md5;
public final long length;
public final byte[] data;
public final byte[] md5;
public final long length;
Md5InputStreamResult(byte[] data, byte[] md5, long length) {
this.data = checkNotNull(data, "data");
this.md5 = checkNotNull(md5, "md5");
checkArgument(length >= 0, "length cannot me negative");
this.length = length;
}
Md5InputStreamResult(byte[] data, byte[] md5, long length) {
this.data = checkNotNull(data, "data");
this.md5 = checkNotNull(md5, "md5");
checkArgument(length >= 0, "length cannot me negative");
this.length = length;
}
}
public static String getContentAsStringAndClose(S3Object object)
throws IOException {
checkNotNull(object, "s3Object");
checkNotNull(object.getData(), "s3Object.content");
Object o = object.getData();
throws IOException {
checkNotNull(object, "s3Object");
checkNotNull(object.getData(), "s3Object.content");
Object o = object.getData();
if (o instanceof InputStream) {
String returnVal = toStringAndClose((InputStream) o);
if (object.getMetadata().getContentType().indexOf("xml") >= 0) {
if (o instanceof InputStream) {
String returnVal = toStringAndClose((InputStream) o);
if (object.getMetadata().getContentType().indexOf("xml") >= 0) {
}
return returnVal;
} else {
throw new IllegalArgumentException("Object type not supported: "
+ o.getClass().getName());
}
}
return returnVal;
} else {
throw new IllegalArgumentException("Object type not supported: "
+ o.getClass().getName());
}
}
}

View File

@ -24,7 +24,7 @@
package org.jclouds.aws.s3.xml;
import static com.google.common.base.Preconditions.checkNotNull;
import com.google.inject.Inject;
import org.jclouds.aws.s3.domain.CanonicalUser;
import org.jclouds.aws.s3.domain.S3Bucket;
import org.jclouds.aws.s3.domain.S3Object;
@ -33,16 +33,14 @@ import org.jclouds.aws.s3.util.S3Utils;
import org.jclouds.http.commands.callables.xml.ParseSax;
import org.xml.sax.Attributes;
import com.google.inject.Inject;
/**
* Parses the following XML document:
* <p/>
* ListBucketResult xmlns="http://s3.amazonaws.com/doc/2006-03-01"
*
*
* @author Adrian Cole
* @see <a href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?RESTBucketGET.html"
* />
* @author Adrian Cole
*/
public class ListBucketHandler extends ParseSax.HandlerWithResult<S3Bucket> {
private S3Bucket s3Bucket;
@ -54,72 +52,72 @@ public class ListBucketHandler extends ParseSax.HandlerWithResult<S3Bucket> {
@Inject
public ListBucketHandler(DateService dateParser) {
this.dateParser = dateParser;
this.dateParser = dateParser;
}
public S3Bucket getResult() {
return s3Bucket;
return s3Bucket;
}
public void setBucketName(String bucketName) {
this.s3Bucket = new S3Bucket(checkNotNull(bucketName, "bucketName"));
this.s3Bucket = new S3Bucket(checkNotNull(bucketName, "bucketName"));
}
private boolean inCommonPrefixes;
public void startElement(String uri, String name, String qName,
Attributes attrs) {
if (qName.equals("CommonPrefixes")) {
inCommonPrefixes = true;
}
Attributes attrs) {
if (qName.equals("CommonPrefixes")) {
inCommonPrefixes = true;
}
}
public void endElement(String uri, String name, String qName) {
if (qName.equals("ID")) {
currentOwner = new CanonicalUser(currentText.toString());
} else if (qName.equals("DisplayName")) {
currentOwner.setDisplayName(currentText.toString());
} else if (qName.equals("Key")) { // content stuff
currentObjectMetadata = new S3Object.Metadata(currentText
.toString());
} else if (qName.equals("LastModified")) {
currentObjectMetadata.setLastModified(dateParser
.dateTimeFromXMLFormat(currentText.toString()));
} else if (qName.equals("ETag")) {
currentObjectMetadata.setMd5(S3Utils.fromHexString(currentText
.toString().replaceAll("\"", "")));
} else if (qName.equals("Size")) {
currentObjectMetadata.setSize(Long
.parseLong(currentText.toString()));
} else if (qName.equals("Owner")) {
currentObjectMetadata.setOwner(currentOwner);
} else if (qName.equals("StorageClass")) {
currentObjectMetadata.setStorageClass(currentText.toString());
} else if (qName.equals("Contents")) {
s3Bucket.getContents().add(currentObjectMetadata);
} else if (qName.equals("Name")) {// bucket stuff last, as least likely
} else if (qName.equals("Prefix")) {
String prefix = currentText.toString().trim();
if (inCommonPrefixes)
s3Bucket.getCommonPrefixes().add(prefix);
else
s3Bucket.setPrefix(prefix);
} else if (qName.equals("Delimiter")) {
if (!currentText.toString().equals(""))
s3Bucket.setDelimiter(currentText.toString().trim());
} else if (qName.equals("Marker")) {
if (!currentText.toString().equals(""))
s3Bucket.setMarker(currentText.toString());
} else if (qName.equals("MaxKeys")) {
s3Bucket.setMaxKeys(Long.parseLong(currentText.toString()));
} else if (qName.equals("IsTruncated")) {
boolean isTruncated = Boolean.parseBoolean(currentText.toString());
s3Bucket.setComplete(!isTruncated);
}
currentText = new StringBuilder();
if (qName.equals("ID")) {
currentOwner = new CanonicalUser(currentText.toString());
} else if (qName.equals("DisplayName")) {
currentOwner.setDisplayName(currentText.toString());
} else if (qName.equals("Key")) { // content stuff
currentObjectMetadata = new S3Object.Metadata(currentText
.toString());
} else if (qName.equals("LastModified")) {
currentObjectMetadata.setLastModified(dateParser
.dateTimeFromXMLFormat(currentText.toString()));
} else if (qName.equals("ETag")) {
currentObjectMetadata.setMd5(S3Utils.fromHexString(currentText
.toString().replaceAll("\"", "")));
} else if (qName.equals("Size")) {
currentObjectMetadata.setSize(Long
.parseLong(currentText.toString()));
} else if (qName.equals("Owner")) {
currentObjectMetadata.setOwner(currentOwner);
} else if (qName.equals("StorageClass")) {
currentObjectMetadata.setStorageClass(currentText.toString());
} else if (qName.equals("Contents")) {
s3Bucket.getContents().add(currentObjectMetadata);
} else if (qName.equals("Name")) {// bucketName stuff last, as least likely
} else if (qName.equals("Prefix")) {
String prefix = currentText.toString().trim();
if (inCommonPrefixes)
s3Bucket.getCommonPrefixes().add(prefix);
else
s3Bucket.setPrefix(prefix);
} else if (qName.equals("Delimiter")) {
if (!currentText.toString().equals(""))
s3Bucket.setDelimiter(currentText.toString().trim());
} else if (qName.equals("Marker")) {
if (!currentText.toString().equals(""))
s3Bucket.setMarker(currentText.toString());
} else if (qName.equals("MaxKeys")) {
s3Bucket.setMaxKeys(Long.parseLong(currentText.toString()));
} else if (qName.equals("IsTruncated")) {
boolean isTruncated = Boolean.parseBoolean(currentText.toString());
s3Bucket.setTruncated(isTruncated);
}
currentText = new StringBuilder();
}
public void characters(char ch[], int start, int length) {
currentText.append(ch, start, length);
currentText.append(ch, start, length);
}
}

View File

@ -23,22 +23,21 @@
*/
package org.jclouds.aws.s3.xml;
import java.util.List;
import com.google.common.annotations.VisibleForTesting;
import com.google.inject.Inject;
import com.google.inject.Provider;
import org.jclouds.aws.s3.domain.S3Bucket;
import org.jclouds.aws.s3.domain.S3Error;
import org.jclouds.aws.s3.domain.S3Object;
import org.jclouds.http.commands.callables.xml.ParseSax;
import com.google.common.annotations.VisibleForTesting;
import com.google.inject.Inject;
import com.google.inject.Provider;
import java.util.List;
/**
* Creates Parsers needed to interpret S3 Server messages. This class uses guice
* assisted inject, which mandates the creation of many single-method
* interfaces. These interfaces are not intended for public api.
*
*
* @author Adrian Cole
*/
public class S3ParserFactory {
@ -48,18 +47,18 @@ public class S3ParserFactory {
@VisibleForTesting
public static interface GenericParseFactory<T> {
ParseSax<T> create(ParseSax.HandlerWithResult<T> handler);
ParseSax<T> create(ParseSax.HandlerWithResult<T> handler);
}
@Inject
Provider<ListAllMyBucketsHandler> ListAllMyBucketsHandlerprovider;
/**
* @return a parser used to handle {@link ListOwnedBuckets} responses
* @return a parser used to handle {@link org.jclouds.aws.s3.commands.ListOwnedBuckets} responses
*/
public ParseSax<List<S3Bucket.Metadata>> createListBucketsParser() {
return parseListAllMyBucketsFactory
.create(ListAllMyBucketsHandlerprovider.get());
return parseListAllMyBucketsFactory
.create(ListAllMyBucketsHandlerprovider.get());
}
@Inject
@ -69,10 +68,10 @@ public class S3ParserFactory {
Provider<ListBucketHandler> ListBucketHandlerprovider;
/**
* @return a parser used to handle {@link ListBucket} responses
* @return a parser used to handle {@link org.jclouds.aws.s3.commands.ListBucket} responses
*/
public ParseSax<S3Bucket> createListBucketParser() {
return parseListBucketFactory.create(ListBucketHandlerprovider.get());
return parseListBucketFactory.create(ListBucketHandlerprovider.get());
}
@Inject
@ -82,10 +81,10 @@ public class S3ParserFactory {
Provider<CopyObjectHandler> copyObjectHandlerProvider;
/**
* @return a parser used to handle {@link CopyObject} responses
* @return a parser used to handle {@link org.jclouds.aws.s3.commands.CopyObject} responses
*/
public ParseSax<S3Object.Metadata> createCopyObjectParser() {
return parseCopyObjectFactory.create(copyObjectHandlerProvider.get());
return parseCopyObjectFactory.create(copyObjectHandlerProvider.get());
}
@Inject
@ -98,7 +97,7 @@ public class S3ParserFactory {
* @return a parser used to handle error conditions.
*/
public ParseSax<S3Error> createErrorParser() {
return parseErrorFactory.create(errorHandlerProvider.get());
return parseErrorFactory.create(errorHandlerProvider.get());
}
}

View File

@ -35,7 +35,7 @@ import java.util.concurrent.Executors;
*
* @author Adrian Cole
*/
@Test(groups = "unit", sequential = true, testName = "s3.PerformanceTest")
@Test(groups = "performance", sequential = true, testName = "s3.PerformanceTest")
public class PerformanceTest {
protected static int LOOP_COUNT = 1000;
protected ExecutorService exec;

View File

@ -0,0 +1,141 @@
/**
*
* Copyright (C) 2009 Adrian Cole <adrian@jclouds.org>
*
* ====================================================================
* 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;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import org.apache.commons.io.IOUtils;
import org.jclouds.aws.s3.internal.BaseS3Map;
import static org.testng.Assert.assertEquals;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Parameters;
import org.testng.annotations.Test;
import java.io.*;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.TreeSet;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeoutException;
@Test
public abstract class BaseS3MapIntegrationTest<T> extends S3IntegrationTest {
public abstract void testPutAll();
public abstract void testEntrySet() throws IOException;
public abstract void testValues() throws IOException;
protected BaseS3Map<T> map;
protected Map<String, String> fiveStrings = ImmutableMap.of("one", "apple",
"two", "bear", "three", "candy", "four", "dogma", "five", "emma");
protected Map<String, byte[]> fiveBytes = ImmutableMap.of("one", "apple"
.getBytes(), "two", "bear".getBytes(), "three", "candy".getBytes(),
"four", "dogma".getBytes(), "five", "emma".getBytes());
protected Map<String, InputStream> fiveInputs;
protected Map<String, File> fiveFiles;
String tmpDirectory;
@BeforeMethod(dependsOnMethods = "setUpBucket", groups = {"integration", "live"})
@Parameters({"basedir"})
protected void setUpTempDir(String basedir) throws InterruptedException,
ExecutionException, FileNotFoundException, IOException,
TimeoutException {
tmpDirectory = basedir + File.separator + "target" + File.separator
+ "testFiles" + File.separator + getClass().getSimpleName();
new File(tmpDirectory).mkdirs();
fiveFiles = ImmutableMap.of("one", new File(tmpDirectory, "apple"),
"two", new File(tmpDirectory, "bear"), "three", new File(
tmpDirectory, "candy"), "four", new File(tmpDirectory,
"dogma"), "five", new File(tmpDirectory, "emma"));
for (File file : fiveFiles.values()) {
IOUtils.write(file.getName(), new FileOutputStream(file));
}
fiveInputs = ImmutableMap.of("one", IOUtils.toInputStream("apple"),
"two", IOUtils.toInputStream("bear"), "three", IOUtils
.toInputStream("candy"), "four", IOUtils
.toInputStream("dogma"), "five", IOUtils
.toInputStream("emma"));
map = createMap(context, bucketName);
map.clear();
}
protected abstract BaseS3Map<T> createMap(S3Context context, String bucket);
@Test(groups = {"integration", "live"})
public void testClear() {
map.clear();
assertEquals(map.size(), 0);
putString("one", "apple");
assertEquals(map.size(), 1);
map.clear();
assertEquals(map.size(), 0);
}
@Test(groups = {"integration", "live"})
public abstract void testRemove() throws IOException;
@Test(groups = {"integration", "live"})
public void testKeySet() {
assertEquals(map.keySet().size(), 0);
putString("one", "two");
assertEquals(map.keySet(), ImmutableSet.of("one"));
}
@Test(groups = {"integration", "live"})
public void testContainsKey() {
assert !map.containsKey("one");
putString("one", "apple");
assert map.containsKey("one");
}
@Test(groups = {"integration", "live"})
public void testIsEmpty() {
assert map.isEmpty();
putString("one", "apple");
assert !map.isEmpty();
}
abstract protected void putString(String key, String value);
protected void fourLeftRemovingOne() {
map.remove("one");
assertEquals(map.size(), 4);
assertEquals(new TreeSet<String>(map.keySet()), new TreeSet<String>(
ImmutableSet.of("two", "three", "four", "five")));
}
@Test(groups = {"integration", "live"})
public abstract void testPut() throws IOException;
@Test(groups = {"integration", "live"})
public void testGetBucket() {
assertEquals(map.getBucket().getName(), bucketName);
}
}

View File

@ -1,156 +0,0 @@
/**
*
* Copyright (C) 2009 Adrian Cole <adrian@jclouds.org>
*
* ====================================================================
* 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;
import static org.testng.Assert.assertEquals;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Map;
import java.util.TreeSet;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.apache.commons.io.IOUtils;
import org.jclouds.aws.s3.internal.BaseS3Map;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Parameters;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
public abstract class BaseS3MapTest<T> extends S3IntegrationTest {
public abstract void testPutAll();
public abstract void testEntrySet() throws IOException;
public abstract void testValues() throws IOException;
protected BaseS3Map<T> map;
protected Map<String, String> fiveStrings = ImmutableMap.of("one", "apple",
"two", "bear", "three", "candy", "four", "dogma", "five", "emma");
protected Map<String, byte[]> fiveBytes = ImmutableMap.of("one", "apple"
.getBytes(), "two", "bear".getBytes(), "three", "candy".getBytes(),
"four", "dogma".getBytes(), "five", "emma".getBytes());
protected Map<String, InputStream> fiveInputs;
protected Map<String, File> fiveFiles;
String tmpDirectory;
private String bucket;
@BeforeMethod
@Parameters( { "basedir" })
protected void setUpTempDir(String basedir) throws InterruptedException,
ExecutionException, FileNotFoundException, IOException,
TimeoutException {
tmpDirectory = basedir + File.separator + "target" + File.separator
+ "testFiles" + File.separator + getClass().getSimpleName();
new File(tmpDirectory).mkdirs();
fiveFiles = ImmutableMap.of("one", new File(tmpDirectory, "apple"),
"two", new File(tmpDirectory, "bear"), "three", new File(
tmpDirectory, "candy"), "four", new File(tmpDirectory,
"dogma"), "five", new File(tmpDirectory, "emma"));
for (File file : fiveFiles.values()) {
IOUtils.write(file.getName(), new FileOutputStream(file));
}
fiveInputs = ImmutableMap.of("one", IOUtils.toInputStream("apple"),
"two", IOUtils.toInputStream("bear"), "three", IOUtils
.toInputStream("candy"), "four", IOUtils
.toInputStream("dogma"), "five", IOUtils
.toInputStream("emma"));
bucket = (bucketPrefix + ".mimi").toLowerCase();
client.putBucketIfNotExists(bucket).get(10, TimeUnit.SECONDS);
map = createMap(context, bucket);
map.clear();
}
protected abstract BaseS3Map<T> createMap(S3Context context, String bucket);
@AfterMethod
public void tearDown() {
map.clear();
map = null;
}
@Test
public void testClear() {
map.clear();
assertEquals(map.size(), 0);
putString("one", "apple");
assertEquals(map.size(), 1);
map.clear();
assertEquals(map.size(), 0);
}
@Test()
public abstract void testRemove() throws IOException;
@Test()
public void testKeySet() {
assertEquals(map.keySet().size(), 0);
putString("one", "two");
assertEquals(map.keySet(), ImmutableSet.of("one"));
}
@Test()
public void testContainsKey() {
assert !map.containsKey("one");
putString("one", "apple");
assert map.containsKey("one");
}
@Test()
public void testIsEmpty() {
assert map.isEmpty();
putString("one", "apple");
assert !map.isEmpty();
}
abstract protected void putString(String key, String value);
protected void fourLeftRemovingOne() {
map.remove("one");
assertEquals(map.size(), 4);
assertEquals(new TreeSet<String>(map.keySet()), new TreeSet<String>(
ImmutableSet.of("two", "three", "four", "five")));
}
@Test
public abstract void testPut() throws IOException;
@Test()
public void testGetBucket() {
assertEquals(map.getBucket().getName(), bucket);
}
}

View File

@ -0,0 +1,94 @@
/**
*
* Copyright (C) 2009 Adrian Cole <adrian@jclouds.org>
*
* ====================================================================
* 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;
import static com.google.common.base.Preconditions.checkNotNull;
import org.jclouds.aws.s3.domain.S3Bucket;
import org.jclouds.aws.s3.domain.S3Object;
import org.jclouds.aws.s3.util.S3Utils;
import static org.testng.Assert.assertEquals;
import org.testng.annotations.Optional;
import org.testng.annotations.Parameters;
import org.testng.annotations.Test;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.List;
import java.util.concurrent.TimeUnit;
/**
* Tests connection by listing all the buckets and their size
*
* @author Adrian Cole
*/
@Test(testName = "s3.S3ConnectionIntegrationTest")
public class S3ConnectionIntegrationTest extends S3IntegrationTest {
@Test(groups = {"integration"})
void testListBuckets() throws Exception {
List<S3Bucket.Metadata> myBuckets = client.listOwnedBuckets().get(10,
TimeUnit.SECONDS);
for (S3Bucket.Metadata bucket : myBuckets) {
context.createInputStreamMap(bucket.getName()).size();
}
}
private static final String sysHttpStreamUrl = System
.getProperty("jclouds.s3.httpstream.url");
private static final String sysHttpStreamMd5 = System
.getProperty("jclouds.s3.httpstream.md5");
@Test(groups = {"integration"})
@Parameters({"jclouds.s3.httpstream.url", "jclouds.s3.httpstream.md5"})
public void testCopyUrl(@Optional String httpStreamUrl,
@Optional String httpStreamMd5) throws Exception {
httpStreamUrl = checkNotNull(httpStreamUrl != null ? httpStreamUrl
: sysHttpStreamUrl, "httpStreamUrl");
httpStreamMd5 = checkNotNull(httpStreamMd5 != null ? httpStreamMd5
: sysHttpStreamMd5, "httpStreamMd5");
String bucketName = bucketPrefix + "tcu";
createBucketAndEnsureEmpty(bucketName);
String key = "hello";
URL url = new URL(httpStreamUrl);
byte[] md5 = S3Utils
.fromHexString(httpStreamMd5);
URLConnection connection = url.openConnection();
int length = connection.getContentLength();
InputStream input = connection.getInputStream();
S3Object object = new S3Object(key, input);
object.setContentLength(length);
object.getMetadata().setMd5(md5);
object.getMetadata().setSize(length);
byte[] newMd5 = client.putObject(bucketName, object).get(30,
TimeUnit.SECONDS);
assertEquals(newMd5, md5);
}
}

View File

@ -1,50 +0,0 @@
/**
*
* Copyright (C) 2009 Adrian Cole <adrian@jclouds.org>
*
* ====================================================================
* 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;
import java.util.List;
import java.util.concurrent.TimeUnit;
import org.jclouds.aws.s3.domain.S3Bucket;
import org.testng.annotations.Test;
/**
* Tests connection by listing all the buckets and their size
*
* @author Adrian Cole
*
*/
@Test(groups = "unit", testName = "s3.S3ConnectionTest")
public class S3ConnectionTest extends S3IntegrationTest {
@Test
void testListBuckets() throws Exception {
List<S3Bucket.Metadata> myBuckets = client.listOwnedBuckets().get(10,
TimeUnit.SECONDS);
for (S3Bucket.Metadata bucket : myBuckets) {
context.createInputStreamMap(bucket.getName()).size();
}
}
}

View File

@ -23,79 +23,89 @@
*/
package org.jclouds.aws.s3;
import static org.testng.Assert.assertEquals;
import java.util.ArrayList;
import java.util.List;
import com.google.inject.AbstractModule;
import com.google.inject.Module;
import org.jclouds.aws.s3.config.LiveS3ConnectionModule;
import org.jclouds.http.config.HttpFutureCommandClientModule;
import org.jclouds.http.config.JavaUrlHttpFutureCommandClientModule;
import org.jclouds.logging.config.LoggingModule;
import org.jclouds.logging.config.NullLoggingModule;
import org.jclouds.logging.jdk.config.JDKLoggingModule;
import static org.testng.Assert.assertEquals;
import org.testng.annotations.Test;
import com.google.inject.AbstractModule;
import com.google.inject.Module;
import java.util.ArrayList;
import java.util.List;
/**
* Tests behavior of modules configured in S3ContextFactory
*
*
* @author Adrian Cole
*
*/
@Test(groups = "unit", testName = "s3.S3ContextFactoryTest")
public class S3ContextFactoryTest {
@HttpFutureCommandClientModule
static class HttpModule extends AbstractModule {
@Override
protected void configure() {
@Override
protected void configure() {
}
}
}
@Test
public void testAddHttpModuleIfNotPresent() {
List<Module> modules = new ArrayList<Module>();
HttpModule module = new HttpModule();
modules.add(module);
S3ContextFactory.addHttpModuleIfNotPresent(modules);
assertEquals(modules.size(), 1);
assertEquals(modules.remove(0), module);
List<Module> modules = new ArrayList<Module>();
HttpModule module = new HttpModule();
modules.add(module);
S3ContextFactory.addHttpModuleIfNeededAndNotPresent(modules);
assertEquals(modules.size(), 1);
assertEquals(modules.remove(0), module);
}
@Test
public void testAddLoggingModuleIfNotPresent() {
List<Module> modules = new ArrayList<Module>();
LoggingModule module = new NullLoggingModule();
modules.add(module);
S3ContextFactory.addLoggingModuleIfNotPresent(modules);
assertEquals(modules.size(), 1);
assertEquals(modules.remove(0), module);
List<Module> modules = new ArrayList<Module>();
LoggingModule module = new NullLoggingModule();
modules.add(module);
S3ContextFactory.addLoggingModuleIfNotPresent(modules);
assertEquals(modules.size(), 1);
assertEquals(modules.remove(0), module);
}
@Test
public void testAddNone() {
List<Module> modules = new ArrayList<Module>();
LoggingModule loggingModule = new NullLoggingModule();
modules.add(loggingModule);
HttpModule httpModule = new HttpModule();
modules.add(httpModule);
S3ContextFactory.addHttpModuleIfNotPresent(modules);
S3ContextFactory.addLoggingModuleIfNotPresent(modules);
assertEquals(modules.size(), 2);
assertEquals(modules.remove(0), loggingModule);
assertEquals(modules.remove(0), httpModule);
List<Module> modules = new ArrayList<Module>();
LoggingModule loggingModule = new NullLoggingModule();
modules.add(loggingModule);
HttpModule httpModule = new HttpModule();
modules.add(httpModule);
S3ContextFactory.addHttpModuleIfNeededAndNotPresent(modules);
S3ContextFactory.addLoggingModuleIfNotPresent(modules);
assertEquals(modules.size(), 2);
assertEquals(modules.remove(0), loggingModule);
assertEquals(modules.remove(0), httpModule);
}
@Test
public void testAddBoth() {
List<Module> modules = new ArrayList<Module>();
S3ContextFactory.addHttpModuleIfNotPresent(modules);
S3ContextFactory.addLoggingModuleIfNotPresent(modules);
assertEquals(modules.size(), 2);
assert modules.remove(0) instanceof JavaUrlHttpFutureCommandClientModule;
assert modules.remove(0) instanceof JDKLoggingModule;
public void testAddBothWhenNotLive() {
List<Module> modules = new ArrayList<Module>();
S3ContextFactory.addHttpModuleIfNeededAndNotPresent(modules);
S3ContextFactory.addLoggingModuleIfNotPresent(modules);
assertEquals(modules.size(), 1);
assert modules.remove(0) instanceof JDKLoggingModule;
}
@Test
public void testAddBothWhenLive() {
List<Module> modules = new ArrayList<Module>();
modules.add(new LiveS3ConnectionModule());
S3ContextFactory.addHttpModuleIfNeededAndNotPresent(modules);
S3ContextFactory.addLoggingModuleIfNotPresent(modules);
assertEquals(modules.size(), 3);
assert modules.remove(0) instanceof LiveS3ConnectionModule;
assert modules.remove(0) instanceof JavaUrlHttpFutureCommandClientModule;
assert modules.remove(0) instanceof JDKLoggingModule;
}
}

View File

@ -0,0 +1,210 @@
/**
*
* Copyright (C) 2009 Adrian Cole <adrian@jclouds.org>
*
* ====================================================================
* 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;
import org.apache.commons.io.IOUtils;
import org.jclouds.aws.s3.internal.BaseS3Map;
import org.jclouds.util.Utils;
import static org.testng.Assert.assertEquals;
import org.testng.annotations.Test;
import java.io.IOException;
import java.io.InputStream;
import java.util.Collection;
import java.util.HashSet;
import java.util.Map.Entry;
import java.util.Set;
import java.util.TreeSet;
/**
* Tests to cover @{link LiveS3ObjectMap}
*
* @author Adrian Cole
*/
@Test(testName = "s3.S3InputStreamMapIntegrationTest")
public class S3InputStreamMapIntegrationTest extends BaseS3MapIntegrationTest<InputStream> {
S3InputStreamMap map = null;
@SuppressWarnings("unchecked")
protected BaseS3Map<InputStream> createMap(S3Context context, String bucket) {
map = context.createInputStreamMap(bucket);
return (BaseS3Map<InputStream>) map;
}
@Override
@Test(groups = {"integration", "live"})
public void testValues() throws IOException {
map.putAll(this.fiveInputs);
Collection<InputStream> values = map.values();
assertEquals(values.size(), 5);
Set<String> valuesAsString = new HashSet<String>();
for (InputStream stream : values) {
valuesAsString.add(Utils.toStringAndClose(stream));
}
valuesAsString.removeAll(fiveStrings.values());
assert valuesAsString.size() == 0;
}
@Test(groups = {"integration", "live"})
public void testRemove() throws IOException {
putString("one", "two");
InputStream old = map.remove("one");
assertEquals(Utils.toStringAndClose(old), "two");
old = map.remove("one");
assert old == null;
old = map.get("one");
assert old == null;
assertEquals(map.keySet().size(), 0);
}
@Override
@Test(groups = {"integration", "live"})
public void testEntrySet() throws IOException {
map.putAllStrings(this.fiveStrings);
Set<Entry<String, InputStream>> entries = map.entrySet();
assertEquals(entries.size(), 5);
for (Entry<String, InputStream> entry : entries) {
assertEquals(IOUtils.toString(entry.getValue()), fiveStrings
.get(entry.getKey()));
entry.setValue(IOUtils.toInputStream(""));
}
assertEquals(map.size(), 5);
for (InputStream value : map.values()) {
assertEquals(IOUtils.toString(value), "");
}
}
@Test(groups = {"integration", "live"})
public void testContainsStringValue() {
map.putString("one", "apple");
assert map.containsValue(fiveStrings.get("one"));
}
@Test(groups = {"integration", "live"})
public void testContainsFileValue() {
map.putString("one", "apple");
assert map.containsValue(fiveFiles.get("one"));
}
@Test(groups = {"integration", "live"})
public void testContainsInputStreamValue() {
map.putString("one", "apple");
assert map.containsValue(this.fiveInputs.get("one"));
}
@Test(groups = {"integration", "live"})
public void testContainsBytesValue() {
map.putString("one", "apple");
assert map.containsValue(this.fiveBytes.get("one"));
}
@Override
@Test(groups = {"integration", "live"})
public void testPutAll() {
map.putAll(this.fiveInputs);
assertEquals(map.size(), 5);
assertEquals(new TreeSet<String>(map.keySet()), new TreeSet<String>(
fiveInputs.keySet()));
fourLeftRemovingOne();
}
@Test(groups = {"integration", "live"})
public void testPutAllBytes() {
map.putAllBytes(this.fiveBytes);
assertEquals(map.size(), 5);
assertEquals(new TreeSet<String>(map.keySet()), new TreeSet<String>(
fiveBytes.keySet()));
fourLeftRemovingOne();
}
@Test(groups = {"integration", "live"})
public void testPutAllFiles() {
map.putAllFiles(this.fiveFiles);
assertEquals(map.size(), 5);
assertEquals(new TreeSet<String>(map.keySet()), new TreeSet<String>(
fiveFiles.keySet()));
fourLeftRemovingOne();
}
@Test(groups = {"integration", "live"})
public void testPutAllStrings() {
map.putAllStrings(this.fiveStrings);
assertEquals(map.size(), 5);
assertEquals(new TreeSet<String>(map.keySet()), new TreeSet<String>(
fiveStrings.keySet()));
fourLeftRemovingOne();
}
@Test(groups = {"integration", "live"})
public void testPutString() throws IOException {
InputStream old = map.putString("one", "apple");
getOneReturnsAppleAndOldValueIsNull(old);
InputStream apple = map.putString("one", "bear");
getOneReturnsBearAndOldValueIsApple(apple);
}
void getOneReturnsAppleAndOldValueIsNull(InputStream old)
throws IOException {
assert old == null;
assertEquals(Utils.toStringAndClose(map.get("one")), "apple");
assertEquals(map.size(), 1);
}
void getOneReturnsBearAndOldValueIsApple(InputStream oldValue)
throws IOException {
assertEquals(Utils.toStringAndClose(map.get("one")), "bear");
assertEquals(Utils.toStringAndClose(oldValue), "apple");
assertEquals(map.size(), 1);
}
@Test(groups = {"integration", "live"})
public void testPutFile() throws IOException {
InputStream old = map.putFile("one", fiveFiles.get("one"));
getOneReturnsAppleAndOldValueIsNull(old);
InputStream apple = map.putFile("one", fiveFiles.get("two"));
getOneReturnsBearAndOldValueIsApple(apple);
}
@Test(groups = {"integration", "live"})
public void testPutBytes() throws IOException {
InputStream old = map.putBytes("one", "apple".getBytes());
getOneReturnsAppleAndOldValueIsNull(old);
InputStream apple = map.putBytes("one", "bear".getBytes());
getOneReturnsBearAndOldValueIsApple(apple);
}
@Test(groups = {"integration", "live"})
public void testPut() throws IOException {
InputStream old = map.put("one", IOUtils.toInputStream("apple"));
getOneReturnsAppleAndOldValueIsNull(old);
InputStream apple = map.put("one", IOUtils.toInputStream("bear"));
getOneReturnsBearAndOldValueIsApple(apple);
}
@Override
protected void putString(String key, String value) {
map.putString(key, value);
}
}

View File

@ -1,211 +0,0 @@
/**
*
* Copyright (C) 2009 Adrian Cole <adrian@jclouds.org>
*
* ====================================================================
* 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;
import static org.testng.Assert.assertEquals;
import java.io.IOException;
import java.io.InputStream;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import java.util.TreeSet;
import java.util.Map.Entry;
import org.apache.commons.io.IOUtils;
import org.jclouds.aws.s3.internal.BaseS3Map;
import org.jclouds.util.Utils;
import org.testng.annotations.Test;
/**
* Tests to cover @{link LiveS3ObjectMap}
*
* @author Adrian Cole
*/
@Test(groups = "unit", sequential = true, testName = "s3.S3InputStreamMapTest")
public class S3InputStreamMapTest extends BaseS3MapTest<InputStream> {
S3InputStreamMap map = null;
@SuppressWarnings("unchecked")
protected BaseS3Map<InputStream> createMap(S3Context context, String bucket) {
map = context.createInputStreamMap(bucket);
return (BaseS3Map<InputStream>) map;
}
@Override
@Test()
public void testValues() throws IOException {
map.putAll(this.fiveInputs);
Collection<InputStream> values = map.values();
assertEquals(values.size(), 5);
Set<String> valuesAsString = new HashSet<String>();
for (InputStream stream : values) {
valuesAsString.add(Utils.toStringAndClose(stream));
}
valuesAsString.removeAll(fiveStrings.values());
assert valuesAsString.size() == 0;
}
@Test()
public void testRemove() throws IOException {
putString("one", "two");
InputStream old = map.remove("one");
assertEquals(Utils.toStringAndClose(old), "two");
old = map.remove("one");
assert old == null;
old = map.get("one");
assert old == null;
assertEquals(map.keySet().size(), 0);
}
@Override
@Test()
public void testEntrySet() throws IOException {
map.putAllStrings(this.fiveStrings);
Set<Entry<String, InputStream>> entries = map.entrySet();
assertEquals(entries.size(), 5);
for (Entry<String, InputStream> entry : entries) {
assertEquals(IOUtils.toString(entry.getValue()), fiveStrings
.get(entry.getKey()));
entry.setValue(IOUtils.toInputStream(""));
}
assertEquals(map.size(), 5);
for (InputStream value : map.values()) {
assertEquals(IOUtils.toString(value), "");
}
}
@Test()
public void testContainsStringValue() {
map.putString("one", "apple");
assert map.containsValue(fiveStrings.get("one"));
}
@Test()
public void testContainsFileValue() {
map.putString("one", "apple");
assert map.containsValue(fiveFiles.get("one"));
}
@Test()
public void testContainsInputStreamValue() {
map.putString("one", "apple");
assert map.containsValue(this.fiveInputs.get("one"));
}
@Test()
public void testContainsBytesValue() {
map.putString("one", "apple");
assert map.containsValue(this.fiveBytes.get("one"));
}
@Override
@Test()
public void testPutAll() {
map.putAll(this.fiveInputs);
assertEquals(map.size(), 5);
assertEquals(new TreeSet<String>(map.keySet()), new TreeSet<String>(
fiveInputs.keySet()));
fourLeftRemovingOne();
}
@Test()
public void testPutAllBytes() {
map.putAllBytes(this.fiveBytes);
assertEquals(map.size(), 5);
assertEquals(new TreeSet<String>(map.keySet()), new TreeSet<String>(
fiveBytes.keySet()));
fourLeftRemovingOne();
}
@Test
public void testPutAllFiles() {
map.putAllFiles(this.fiveFiles);
assertEquals(map.size(), 5);
assertEquals(new TreeSet<String>(map.keySet()), new TreeSet<String>(
fiveFiles.keySet()));
fourLeftRemovingOne();
}
@Test()
public void testPutAllStrings() {
map.putAllStrings(this.fiveStrings);
assertEquals(map.size(), 5);
assertEquals(new TreeSet<String>(map.keySet()), new TreeSet<String>(
fiveStrings.keySet()));
fourLeftRemovingOne();
}
@Test()
public void testPutString() throws IOException {
InputStream old = map.putString("one", "apple");
getOneReturnsAppleAndOldValueIsNull(old);
InputStream apple = map.putString("one", "bear");
getOneReturnsBearAndOldValueIsApple(apple);
}
void getOneReturnsAppleAndOldValueIsNull(InputStream old)
throws IOException {
assert old == null;
assertEquals(Utils.toStringAndClose(map.get("one")), "apple");
assertEquals(map.size(), 1);
}
void getOneReturnsBearAndOldValueIsApple(InputStream oldValue)
throws IOException {
assertEquals(Utils.toStringAndClose(map.get("one")), "bear");
assertEquals(Utils.toStringAndClose(oldValue), "apple");
assertEquals(map.size(), 1);
}
@Test()
public void testPutFile() throws IOException {
InputStream old = map.putFile("one", fiveFiles.get("one"));
getOneReturnsAppleAndOldValueIsNull(old);
InputStream apple = map.putFile("one", fiveFiles.get("two"));
getOneReturnsBearAndOldValueIsApple(apple);
}
@Test()
public void testPutBytes() throws IOException {
InputStream old = map.putBytes("one", "apple".getBytes());
getOneReturnsAppleAndOldValueIsNull(old);
InputStream apple = map.putBytes("one", "bear".getBytes());
getOneReturnsBearAndOldValueIsApple(apple);
}
@Test()
public void testPut() throws IOException {
InputStream old = map.put("one", IOUtils.toInputStream("apple"));
getOneReturnsAppleAndOldValueIsNull(old);
InputStream apple = map.put("one", IOUtils.toInputStream("bear"));
getOneReturnsBearAndOldValueIsApple(apple);
}
@Override
protected void putString(String key, String value) {
map.putString(key, value);
}
}

View File

@ -24,196 +24,223 @@
package org.jclouds.aws.s3;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.testng.Assert.assertEquals;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.CancellationException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.logging.ConsoleHandler;
import java.util.logging.Formatter;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.LogRecord;
import java.util.logging.Logger;
import com.google.inject.Module;
import org.jclouds.aws.s3.config.StubS3ConnectionModule;
import org.jclouds.aws.s3.domain.S3Bucket;
import org.jclouds.aws.s3.domain.S3Object;
import org.jclouds.aws.s3.reference.S3Constants;
import org.jclouds.aws.s3.util.S3Utils;
import org.jclouds.http.HttpConstants;
import org.jclouds.http.config.JavaUrlHttpFutureCommandClientModule;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Optional;
import org.testng.annotations.Parameters;
import org.testng.annotations.Test;
import static org.testng.Assert.assertEquals;
import org.testng.ITestContext;
import org.testng.annotations.*;
import com.google.inject.Module;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.*;
import java.util.concurrent.*;
import java.util.logging.*;
import java.util.logging.Formatter;
@Test
public class S3IntegrationTest {
protected static final String TEST_STRING = "<apples><apple name=\"fuji\"></apple> </apples>";
protected byte[] goodMd5;
protected byte[] badMd5;
protected String bucketName;
protected void createBucketAndEnsureEmpty(String sourceBucket)
throws InterruptedException, ExecutionException, TimeoutException {
client.putBucketIfNotExists(sourceBucket).get(10, TimeUnit.SECONDS);
assertEquals(client.listBucket(sourceBucket).get(10, TimeUnit.SECONDS)
.getContents().size(), 0);
throws InterruptedException, ExecutionException, TimeoutException {
client.putBucketIfNotExists(sourceBucket).get(10, TimeUnit.SECONDS);
assertEquals(client.listBucket(sourceBucket).get(10, TimeUnit.SECONDS)
.getContents().size(), 0);
}
protected void addObjectToBucket(String sourceBucket, String key)
throws InterruptedException, ExecutionException, TimeoutException,
IOException {
S3Object sourceObject = new S3Object(key);
sourceObject.getMetadata().setContentType("text/xml");
sourceObject.setData(TEST_STRING);
addObjectToBucket(sourceBucket, sourceObject);
throws InterruptedException, ExecutionException, TimeoutException,
IOException {
S3Object sourceObject = new S3Object(key);
sourceObject.getMetadata().setContentType("text/xml");
sourceObject.setData(TEST_STRING);
addObjectToBucket(sourceBucket, sourceObject);
}
protected void addObjectToBucket(String sourceBucket, S3Object object)
throws InterruptedException, ExecutionException, TimeoutException,
IOException {
;
client.putObject(sourceBucket, object).get(10, TimeUnit.SECONDS);
throws InterruptedException, ExecutionException, TimeoutException,
IOException {
client.putObject(sourceBucket, object).get(10, TimeUnit.SECONDS);
}
protected S3Object validateContent(String sourceBucket, String key)
throws InterruptedException, ExecutionException, TimeoutException,
IOException {
assertEquals(client.listBucket(sourceBucket).get(10, TimeUnit.SECONDS)
.getContents().size(), 1);
S3Object newObject = client.getObject(sourceBucket, key).get(10,
TimeUnit.SECONDS);
assert newObject != S3Object.NOT_FOUND;
assertEquals(S3Utils.getContentAsStringAndClose(newObject), TEST_STRING);
return newObject;
throws InterruptedException, ExecutionException, TimeoutException,
IOException {
assertEquals(client.listBucket(sourceBucket).get(10, TimeUnit.SECONDS)
.getContents().size(), 1);
S3Object newObject = client.getObject(sourceBucket, key).get(10,
TimeUnit.SECONDS);
assert newObject != S3Object.NOT_FOUND;
assertEquals(S3Utils.getContentAsStringAndClose(newObject), TEST_STRING);
return newObject;
}
@BeforeTest
@BeforeClass(groups = {"integration", "live"})
void enableDebug() {
if (debugEnabled()) {
Handler HANDLER = new ConsoleHandler() {
{
setLevel(Level.ALL);
setFormatter(new Formatter() {
if (debugEnabled()) {
Handler HANDLER = new ConsoleHandler() {
{
setLevel(Level.ALL);
setFormatter(new Formatter() {
@Override
public String format(LogRecord record) {
return String.format(
"[%tT %-7s] [%-7s] [%s]: %s %s\n",
new Date(record.getMillis()), record
.getLevel(), Thread.currentThread()
.getName(), record.getLoggerName(),
record.getMessage(),
record.getThrown() == null ? "" : record
.getThrown());
}
});
}
};
Logger guiceLogger = Logger.getLogger("org.jclouds");
guiceLogger.addHandler(HANDLER);
guiceLogger.setLevel(Level.ALL);
}
@Override
public String format(LogRecord record) {
return String.format(
"[%tT %-7s] [%-7s] [%s]: %s %s\n",
new Date(record.getMillis()), record
.getLevel(), Thread.currentThread()
.getName(), record.getLoggerName(),
record.getMessage(),
record.getThrown() == null ? "" : record
.getThrown());
}
});
}
};
Logger guiceLogger = Logger.getLogger("org.jclouds");
guiceLogger.addHandler(HANDLER);
guiceLogger.setLevel(Level.ALL);
}
}
protected S3Connection client;
protected S3Context context = null;
protected String bucketPrefix = (System.getProperty("user.name") + "." + this
.getClass().getSimpleName()).toLowerCase();
.getClass().getSimpleName()).toLowerCase();
private static final String sysAWSAccessKeyId = System
.getProperty(S3Constants.PROPERTY_AWS_ACCESSKEYID);
.getProperty(S3Constants.PROPERTY_AWS_ACCESSKEYID);
private static final String sysAWSSecretAccessKey = System
.getProperty(S3Constants.PROPERTY_AWS_SECRETACCESSKEY);
.getProperty(S3Constants.PROPERTY_AWS_SECRETACCESSKEY);
@BeforeTest
@Parameters( { S3Constants.PROPERTY_AWS_ACCESSKEYID,
S3Constants.PROPERTY_AWS_SECRETACCESSKEY })
protected void setUpClient(@Optional String AWSAccessKeyId,
@Optional String AWSSecretAccessKey) throws Exception {
context = createS3Context(AWSAccessKeyId != null ? AWSAccessKeyId
: sysAWSAccessKeyId,
AWSSecretAccessKey != null ? AWSSecretAccessKey
: sysAWSSecretAccessKey);
client = context.getConnection();
deleteEverything();
goodMd5 = S3Utils.md5(TEST_STRING);
badMd5 = S3Utils.md5("alf");
@BeforeClass(inheritGroups = false, groups = {"integration", "live"})
@Parameters({S3Constants.PROPERTY_AWS_ACCESSKEYID,
S3Constants.PROPERTY_AWS_SECRETACCESSKEY})
protected void setUpCredentials(@Optional String AWSAccessKeyId,
@Optional String AWSSecretAccessKey, ITestContext testContext) throws Exception {
AWSAccessKeyId = AWSAccessKeyId != null ? AWSAccessKeyId
: sysAWSAccessKeyId;
AWSSecretAccessKey = AWSSecretAccessKey != null ? AWSSecretAccessKey
: sysAWSSecretAccessKey;
if (AWSAccessKeyId != null)
testContext.setAttribute(S3Constants.PROPERTY_AWS_ACCESSKEYID, AWSAccessKeyId);
if (AWSSecretAccessKey != null)
testContext.setAttribute(S3Constants.PROPERTY_AWS_SECRETACCESSKEY, AWSSecretAccessKey);
}
@BeforeClass(dependsOnMethods = {"setUpCredentials"}, groups = {"integration", "live"})
protected void setUpClient(ITestContext testContext) throws Exception {
if (testContext.getAttribute(S3Constants.PROPERTY_AWS_ACCESSKEYID) != null) {
String AWSAccessKeyId = (String) testContext.getAttribute(S3Constants.PROPERTY_AWS_ACCESSKEYID);
String AWSSecretAccessKey = (String) testContext.getAttribute(S3Constants.PROPERTY_AWS_SECRETACCESSKEY);
createLiveS3Context(AWSAccessKeyId, AWSSecretAccessKey);
} else {
createStubS3Context();
}
client = context.getConnection();
assert client != null;
deleteEverything();
goodMd5 = S3Utils.md5(TEST_STRING);
badMd5 = S3Utils.md5("alf");
}
protected void createStubS3Context() {
Properties props = new Properties();
props.setProperty(S3Constants.PROPERTY_HTTP_ADDRESS, "stub");
context = S3ContextFactory.createS3Context(props, new StubS3ConnectionModule());
}
protected void createLiveS3Context(String AWSAccessKeyId, String AWSSecretAccessKey) {
context = S3ContextFactory.createS3Context(buildS3Properties(
checkNotNull(AWSAccessKeyId, "AWSAccessKeyId"),
checkNotNull(AWSSecretAccessKey, "AWSSecretAccessKey")),
createHttpModule());
}
@BeforeMethod(dependsOnMethods = "deleteBucket", groups = {"integration", "live"})
public void setUpBucket(Method method) throws TimeoutException, ExecutionException, InterruptedException {
bucketName = (bucketPrefix + method.getName()).toLowerCase();
createBucketAndEnsureEmpty(bucketName);
}
@BeforeMethod(groups = {"integration", "live"})
@AfterMethod(groups = {"integration", "live"})
public void deleteBucket() throws TimeoutException, ExecutionException, InterruptedException {
if (bucketName != null)
deleteBucket(bucketName);
}
protected boolean debugEnabled() {
return false;
}
protected S3Context createS3Context(String AWSAccessKeyId,
String AWSSecretAccessKey) {
return S3ContextFactory.createS3Context(buildS3Properties(
AWSAccessKeyId, AWSSecretAccessKey), createHttpModule());
return false;
}
protected Properties buildS3Properties(String AWSAccessKeyId,
String AWSSecretAccessKey) {
Properties properties = new Properties(
S3ContextFactory.DEFAULT_PROPERTIES);
properties.setProperty(S3Constants.PROPERTY_AWS_ACCESSKEYID,
checkNotNull(AWSAccessKeyId, "AWSAccessKeyId"));
properties.setProperty(S3Constants.PROPERTY_AWS_SECRETACCESSKEY,
checkNotNull(AWSSecretAccessKey, "AWSSecretAccessKey"));
properties.setProperty(HttpConstants.PROPERTY_HTTP_SECURE, "false");
properties.setProperty(HttpConstants.PROPERTY_HTTP_PORT, "80");
return properties;
String AWSSecretAccessKey) {
Properties properties = new Properties(
S3ContextFactory.DEFAULT_PROPERTIES);
properties.setProperty(S3Constants.PROPERTY_AWS_ACCESSKEYID,
checkNotNull(AWSAccessKeyId, "AWSAccessKeyId"));
properties.setProperty(S3Constants.PROPERTY_AWS_SECRETACCESSKEY,
checkNotNull(AWSSecretAccessKey, "AWSSecretAccessKey"));
properties.setProperty(HttpConstants.PROPERTY_HTTP_SECURE, "false");
properties.setProperty(HttpConstants.PROPERTY_HTTP_PORT, "80");
return properties;
}
protected Module createHttpModule() {
return new JavaUrlHttpFutureCommandClientModule();
return new JavaUrlHttpFutureCommandClientModule();
}
protected void deleteEverything() throws Exception {
try {
List<S3Bucket.Metadata> metadata = client.listOwnedBuckets().get(
10, TimeUnit.SECONDS);
List<Future<Boolean>> results = new ArrayList<Future<Boolean>>();
for (S3Bucket.Metadata metaDatum : metadata) {
if (metaDatum.getName().startsWith(bucketPrefix.toLowerCase())) {
S3Bucket bucket = client.listBucket(metaDatum.getName())
.get(10, TimeUnit.SECONDS);
for (S3Object.Metadata objectMeta : bucket.getContents()) {
results.add(client.deleteObject(metaDatum.getName(),
objectMeta.getKey()));
}
Iterator<Future<Boolean>> iterator = results.iterator();
while (iterator.hasNext()) {
iterator.next().get(10, TimeUnit.SECONDS);
iterator.remove();
}
client.deleteBucketIfEmpty(metaDatum.getName()).get(10,
TimeUnit.SECONDS);
}
try {
List<S3Bucket.Metadata> metadata = client.listOwnedBuckets().get(
10, TimeUnit.SECONDS);
for (S3Bucket.Metadata metaDatum : metadata) {
if (metaDatum.getName().startsWith(bucketPrefix.toLowerCase())) {
deleteBucket(metaDatum.getName());
}
}
} catch (CancellationException e) {
throw e;
}
}
} catch (CancellationException e) {
throw e;
}
}
@AfterTest
private void deleteBucket(String name) throws InterruptedException, ExecutionException, TimeoutException {
if (client.bucketExists(name).get(10, TimeUnit.SECONDS)) {
List<Future<Boolean>> results = new ArrayList<Future<Boolean>>();
S3Bucket bucket = client.listBucket(name)
.get(10, TimeUnit.SECONDS);
for (S3Object.Metadata objectMeta : bucket.getContents()) {
results.add(client.deleteObject(name,
objectMeta.getKey()));
}
Iterator<Future<Boolean>> iterator = results.iterator();
while (iterator.hasNext()) {
iterator.next().get(10, TimeUnit.SECONDS);
iterator.remove();
}
client.deleteBucketIfEmpty(name).get(10,
TimeUnit.SECONDS);
}
}
@AfterClass
protected void tearDownClient() throws Exception {
deleteEverything();
context.close();
context = null;
deleteEverything();
context.close();
context = null;
}
}

View File

@ -0,0 +1,166 @@
/**
*
* Copyright (C) 2009 Adrian Cole <adrian@jclouds.org>
*
* ====================================================================
* 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;
import org.apache.commons.io.IOUtils;
import org.jclouds.aws.s3.domain.S3Object;
import org.jclouds.aws.s3.internal.BaseS3Map;
import org.jclouds.aws.s3.util.S3Utils;
import static org.testng.Assert.assertEquals;
import org.testng.annotations.Test;
import java.io.IOException;
import java.util.*;
import java.util.Map.Entry;
/**
* Tests to cover @{link LiveS3ObjectMap}
*
* @author Adrian Cole
*/
@Test(testName = "s3.S3ObjectMapIntegrationTest")
public class S3ObjectMapIntegrationTest extends BaseS3MapIntegrationTest<S3Object> {
S3ObjectMap map = null;
@SuppressWarnings("unchecked")
protected BaseS3Map<S3Object> createMap(S3Context context, String bucket) {
map = context.createS3ObjectMap(bucket);
return (BaseS3Map<S3Object>) map;
}
@Override
@Test(groups = {"integration", "live"})
public void testValues() throws IOException {
putFiveStrings();
Collection<S3Object> values = map.values();
assertEquals(values.size(), 5);
Set<String> valuesAsString = new HashSet<String>();
for (S3Object object : values) {
valuesAsString.add(S3Utils.getContentAsStringAndClose(object));
}
valuesAsString.removeAll(fiveStrings.values());
assert valuesAsString.size() == 0;
}
@Test(groups = {"integration", "live"})
public void testRemove() throws IOException {
putString("one", "two");
S3Object old = map.remove("one");
assertEquals(S3Utils.getContentAsStringAndClose(old), "two");
old = map.remove("one");
assert old == S3Object.NOT_FOUND;
old = map.get("one");
assert old == S3Object.NOT_FOUND;
assertEquals(map.keySet().size(), 0);
}
@Override
@Test(groups = {"integration", "live"})
public void testEntrySet() throws IOException {
putFiveStrings();
Set<Entry<String, S3Object>> entries = map.entrySet();
assertEquals(entries.size(), 5);
for (Entry<String, S3Object> entry : entries) {
assertEquals(S3Utils.getContentAsStringAndClose(entry.getValue()),
fiveStrings.get(entry.getKey()));
S3Object value = entry.getValue();
value.setData("");
value.generateMd5();
entry.setValue(value);
}
assertEquals(map.size(), 5);
for (S3Object value : map.values()) {
assertEquals(S3Utils.getContentAsStringAndClose(value), "");
}
}
@Test(groups = {"integration", "live"})
public void testContains() {
putString("one", "apple");
S3Object object = new S3Object("one");
object.setData("apple");
assert map.containsValue(object);
}
void getOneReturnsAppleAndOldValueIsNull(S3Object old) throws IOException {
assert old == S3Object.NOT_FOUND;
assertEquals(S3Utils.getContentAsStringAndClose(map.get("one")),
"apple");
assert map.size() == 1;
}
void getOneReturnsBearAndOldValueIsApple(S3Object oldValue)
throws IOException {
assertEquals(S3Utils.getContentAsStringAndClose(map.get("one")), "bear");
assertEquals(S3Utils.getContentAsStringAndClose(oldValue), "apple");
assert map.size() == 1;
}
@Test(groups = {"integration", "live"})
public void testPut() throws IOException {
S3Object object = new S3Object("one");
object.setData(IOUtils.toInputStream("apple"));
object.generateMd5();
S3Object old = map.put(object.getKey(), object);
getOneReturnsAppleAndOldValueIsNull(old);
object.setData(IOUtils.toInputStream("bear"));
object.generateMd5();
S3Object apple = map.put(object.getKey(), object);
getOneReturnsBearAndOldValueIsApple(apple);
}
@Test(groups = {"integration", "live"})
public void testPutAll() {
Map<String, S3Object> newMap = new HashMap<String, S3Object>();
for (String key : fiveInputs.keySet()) {
S3Object object = new S3Object(key);
object.setData(fiveInputs.get(key));
object.getMetadata().setSize(fiveBytes.get(key).length);
newMap.put(key, object);
}
map.putAll(newMap);
assertEquals(map.size(), 5);
assertEquals(new TreeSet<String>(map.keySet()), new TreeSet<String>(
fiveInputs.keySet()));
fourLeftRemovingOne();
}
@Override
protected void putString(String key, String value) {
S3Object object = new S3Object(key);
object.setData(value);
map.put(key, object);
}
protected void putFiveStrings() {
Map<String, S3Object> newMap = new HashMap<String, S3Object>();
for (Map.Entry<String, String> entry : fiveStrings.entrySet()) {
S3Object object = new S3Object(entry.getKey());
object.setData(entry.getValue());
newMap.put(entry.getKey(), object);
}
map.putAll(newMap);
}
}

View File

@ -1,172 +0,0 @@
/**
*
* Copyright (C) 2009 Adrian Cole <adrian@jclouds.org>
*
* ====================================================================
* 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;
import static org.testng.Assert.assertEquals;
import java.io.IOException;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import java.util.Map.Entry;
import org.apache.commons.io.IOUtils;
import org.jclouds.aws.s3.domain.S3Object;
import org.jclouds.aws.s3.internal.BaseS3Map;
import org.jclouds.aws.s3.util.S3Utils;
import org.testng.annotations.Test;
/**
* Tests to cover @{link LiveS3ObjectMap}
*
* @author Adrian Cole
*/
@Test(groups = "unit", sequential = true, testName = "s3.S3ObjectMapTest")
public class S3ObjectMapTest extends BaseS3MapTest<S3Object> {
S3ObjectMap map = null;
@SuppressWarnings("unchecked")
protected BaseS3Map<S3Object> createMap(S3Context context, String bucket) {
map = context.createS3ObjectMap(bucket);
return (BaseS3Map<S3Object>) map;
}
@Override
@Test()
public void testValues() throws IOException {
putFiveStrings();
Collection<S3Object> values = map.values();
assertEquals(values.size(), 5);
Set<String> valuesAsString = new HashSet<String>();
for (S3Object object : values) {
valuesAsString.add(S3Utils.getContentAsStringAndClose(object));
}
valuesAsString.removeAll(fiveStrings.values());
assert valuesAsString.size() == 0;
}
@Test()
public void testRemove() throws IOException {
putString("one", "two");
S3Object old = map.remove("one");
assertEquals(S3Utils.getContentAsStringAndClose(old), "two");
old = map.remove("one");
assert old == S3Object.NOT_FOUND;
old = map.get("one");
assert old == S3Object.NOT_FOUND;
assertEquals(map.keySet().size(), 0);
}
@Override
@Test()
public void testEntrySet() throws IOException {
putFiveStrings();
Set<Entry<String, S3Object>> entries = map.entrySet();
assertEquals(entries.size(), 5);
for (Entry<String, S3Object> entry : entries) {
assertEquals(S3Utils.getContentAsStringAndClose(entry.getValue()),
fiveStrings.get(entry.getKey()));
S3Object value = entry.getValue();
value.setData("");
value.generateMd5();
entry.setValue(value);
}
assertEquals(map.size(), 5);
for (S3Object value : map.values()) {
assertEquals(S3Utils.getContentAsStringAndClose(value), "");
}
}
@Test()
public void testContains() {
putString("one", "apple");
S3Object object = new S3Object("one");
object.setData("apple");
assert map.containsValue(object);
}
void getOneReturnsAppleAndOldValueIsNull(S3Object old) throws IOException {
assert old == S3Object.NOT_FOUND;
assertEquals(S3Utils.getContentAsStringAndClose(map.get("one")),
"apple");
assert map.size() == 1;
}
void getOneReturnsBearAndOldValueIsApple(S3Object oldValue)
throws IOException {
assertEquals(S3Utils.getContentAsStringAndClose(map.get("one")), "bear");
assertEquals(S3Utils.getContentAsStringAndClose(oldValue), "apple");
assert map.size() == 1;
}
@Test
public void testPut() throws IOException {
S3Object object = new S3Object("one");
object.setData(IOUtils.toInputStream("apple"));
object.generateMd5();
S3Object old = map.put(object.getKey(), object);
getOneReturnsAppleAndOldValueIsNull(old);
object.setData(IOUtils.toInputStream("bear"));
object.generateMd5();
S3Object apple = map.put(object.getKey(), object);
getOneReturnsBearAndOldValueIsApple(apple);
}
@Test
public void testPutAll() {
Map<String, S3Object> newMap = new HashMap<String, S3Object>();
for (String key : fiveInputs.keySet()) {
S3Object object = new S3Object(key);
object.setData(fiveInputs.get(key));
object.getMetadata().setSize(fiveBytes.get(key).length);
newMap.put(key, object);
}
map.putAll(newMap);
assertEquals(map.size(), 5);
assertEquals(new TreeSet<String>(map.keySet()), new TreeSet<String>(
fiveInputs.keySet()));
fourLeftRemovingOne();
}
@Override
protected void putString(String key, String value) {
S3Object object = new S3Object(key);
object.setData(value);
map.put(key, object);
}
protected void putFiveStrings() {
Map<String, S3Object> newMap = new HashMap<String, S3Object>();
for (Map.Entry<String, String> entry : fiveStrings.entrySet()) {
S3Object object = new S3Object(entry.getKey());
object.setData(entry.getValue());
newMap.put(entry.getKey(), object);
}
map.putAll(newMap);
}
}

View File

@ -26,6 +26,7 @@ package org.jclouds.aws.s3;
import org.bouncycastle.util.encoders.Base64;
import org.jclouds.aws.PerformanceTest;
import org.jclouds.aws.s3.util.S3Utils;
import static org.testng.Assert.assertEquals;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
@ -38,90 +39,89 @@ import java.util.concurrent.CompletionService;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorCompletionService;
import static org.testng.Assert.*;
/**
* This tests the performance of Digest commands.
*
*
* @author Adrian Cole
*/
@Test(groups = "unit", sequential = true, testName = "s3.PerformanceTest")
@Test(groups = "performance", sequential = true, testName = "s3.PerformanceTest")
public class S3UtilsTest extends PerformanceTest {
@Test(dataProvider = "hmacsha1")
void testBouncyCastleDigestSerialResponseTime(byte[] key, String message,
String base64Digest) throws NoSuchProviderException,
NoSuchAlgorithmException, InvalidKeyException {
for (int i = 0; i < 10000; i++)
testBouncyCastleHmacSha1Base64(key, message, base64Digest);
String base64Digest) throws NoSuchProviderException,
NoSuchAlgorithmException, InvalidKeyException {
for (int i = 0; i < 10000; i++)
testBouncyCastleHmacSha1Base64(key, message, base64Digest);
}
@Test(dataProvider = "hmacsha1")
void testBouncyCastleDigestParallelResponseTime(final byte[] key,
final String message, final String base64Digest)
throws NoSuchProviderException, NoSuchAlgorithmException,
InvalidKeyException, InterruptedException, ExecutionException {
CompletionService<Boolean> completer = new ExecutorCompletionService<Boolean>(
exec);
for (int i = 0; i < 10000; i++)
completer.submit(new Callable<Boolean>() {
public Boolean call() throws Exception {
testBouncyCastleHmacSha1Base64(key, message, base64Digest);
return true;
}
});
for (int i = 0; i < 10000; i++)
assert completer.take().get();
final String message, final String base64Digest)
throws NoSuchProviderException, NoSuchAlgorithmException,
InvalidKeyException, InterruptedException, ExecutionException {
CompletionService<Boolean> completer = new ExecutorCompletionService<Boolean>(
exec);
for (int i = 0; i < 10000; i++)
completer.submit(new Callable<Boolean>() {
public Boolean call() throws Exception {
testBouncyCastleHmacSha1Base64(key, message, base64Digest);
return true;
}
});
for (int i = 0; i < 10000; i++)
assert completer.take().get();
}
@DataProvider(name = "md5")
public Object[][] createMD5Data() {
return base64MD5MessageDigest;
return base64MD5MessageDigest;
}
public final static Object[][] base64MD5MessageDigest = {
{ "apple", "1f3870be274f6c49b3e31a0c6728957f" },
{ "bear", "893b56e3cfe153fb770a120b83bac20c" },
{ "candy", "c48ba993d35c3abe0380f91738fe2a34" },
{ "dogma", "95eb470e4faee302e9cd3063b1923dab" },
{ "emma", "00a809937eddc44521da9521269e75c6" } };
{"apple", "1f3870be274f6c49b3e31a0c6728957f"},
{"bear", "893b56e3cfe153fb770a120b83bac20c"},
{"candy", "c48ba993d35c3abe0380f91738fe2a34"},
{"dogma", "95eb470e4faee302e9cd3063b1923dab"},
{"emma", "00a809937eddc44521da9521269e75c6"}};
public final static Object[][] base64KeyMessageDigest = {
{ Base64.decode("CwsLCwsLCwsLCwsLCwsLCwsLCws="), "Hi There",
"thcxhlUFcmTii8C2+zeMjvFGvgA=" },
{ Base64.decode("SmVmZQ=="), "what do ya want for nothing?",
"7/zfauXrL6LSdBbV8YTfnCWafHk=" },
{ Base64.decode("DAwMDAwMDAwMDAwMDAwMDAwMDAw="),
"Test With Truncation", "TBoDQktV4H/n8nvh1Yu5MkqaWgQ=" },
{
Base64
.decode("qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqo="),
"Test Using Larger Than Block-Size Key - Hash Key First",
"qkrl4VJy0A6VcFY3zoo7Ve1AIRI=" },
{
Base64
.decode("qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqo="),
"Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data",
"6OmdD0UjfXhta7qnllx4CLv/GpE=" } };
{Base64.decode("CwsLCwsLCwsLCwsLCwsLCwsLCws="), "Hi There",
"thcxhlUFcmTii8C2+zeMjvFGvgA="},
{Base64.decode("SmVmZQ=="), "what do ya want for nothing?",
"7/zfauXrL6LSdBbV8YTfnCWafHk="},
{Base64.decode("DAwMDAwMDAwMDAwMDAwMDAwMDAw="),
"Test With Truncation", "TBoDQktV4H/n8nvh1Yu5MkqaWgQ="},
{
Base64
.decode("qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqo="),
"Test Using Larger Than Block-Size Key - Hash Key First",
"qkrl4VJy0A6VcFY3zoo7Ve1AIRI="},
{
Base64
.decode("qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqo="),
"Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data",
"6OmdD0UjfXhta7qnllx4CLv/GpE="}};
@DataProvider(name = "hmacsha1")
public Object[][] createData1() {
return base64KeyMessageDigest;
return base64KeyMessageDigest;
}
@Test(dataProvider = "hmacsha1")
public void testBouncyCastleHmacSha1Base64(byte[] key, String message,
String base64Digest) throws NoSuchProviderException,
NoSuchAlgorithmException, InvalidKeyException {
String b64 = S3Utils.hmacSha1Base64(message, key);
assertEquals(b64, base64Digest);
String base64Digest) throws NoSuchProviderException,
NoSuchAlgorithmException, InvalidKeyException {
String b64 = S3Utils.hmacSha1Base64(message, key);
assertEquals(b64, base64Digest);
}
@Test(dataProvider = "md5")
public void testBouncyCastleMD5Digest(String message,
String base64Digest) throws NoSuchProviderException,
NoSuchAlgorithmException, InvalidKeyException, UnsupportedEncodingException {
String b64 = S3Utils.md5Hex(message.getBytes());
assertEquals(base64Digest,b64);
String base64Digest) throws NoSuchProviderException,
NoSuchAlgorithmException, InvalidKeyException, UnsupportedEncodingException {
String b64 = S3Utils.md5Hex(message.getBytes());
assertEquals(base64Digest, b64);
}
}

View File

@ -28,20 +28,20 @@ import org.testng.annotations.Test;
import java.util.Properties;
/**
* This performs the same test as {@link S3ConnectionTest}, except using SSL.
*
* This performs the same test as {@link S3ConnectionIntegrationTest}, except using SSL.
*
* @author Adrian Cole
*/
@Test(groups = "unit", testName = "s3.SecureS3ConnectionTest")
public class SecureS3ConnectionTest extends S3ConnectionTest {
@Test(groups = {"live"}, testName = "s3.SecureS3ConnectionIntegrationTest")
public class SecureS3ConnectionIntegrationTest extends S3ConnectionIntegrationTest {
@Override
protected Properties buildS3Properties(String AWSAccessKeyId,
String AWSSecretAccessKey) {
Properties properties = super.buildS3Properties(AWSAccessKeyId,
AWSSecretAccessKey);
properties.setProperty("jclouds.http.secure", Boolean.toString(true));
properties.setProperty("jclouds.http.port", "443");
return properties;
String AWSSecretAccessKey) {
Properties properties = super.buildS3Properties(AWSAccessKeyId,
AWSSecretAccessKey);
properties.setProperty("jclouds.http.secure", Boolean.toString(true));
properties.setProperty("jclouds.http.port", "443");
return properties;
}
}

View File

@ -23,226 +23,459 @@
*/
package org.jclouds.aws.s3;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.jclouds.aws.s3.commands.options.CopyObjectOptions;
import org.jclouds.aws.s3.commands.options.GetObjectOptions;
import org.jclouds.aws.s3.commands.options.ListBucketOptions;
import org.jclouds.aws.s3.commands.options.PutBucketOptions;
import org.jclouds.aws.s3.commands.options.PutObjectOptions;
import com.google.common.base.Function;
import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.thoughtworks.xstream.XStream;
import org.apache.commons.io.IOUtils;
import org.apache.commons.io.output.ByteArrayOutputStream;
import static org.easymock.classextension.EasyMock.createNiceMock;
import org.jclouds.aws.s3.commands.CopyObject;
import org.jclouds.aws.s3.commands.options.*;
import org.jclouds.aws.s3.domain.S3Bucket;
import org.jclouds.aws.s3.domain.S3Object;
import org.jclouds.aws.s3.domain.S3Bucket.Metadata;
import org.jclouds.aws.s3.domain.S3Object;
import org.jclouds.aws.s3.domain.acl.CannedAccessPolicy;
import org.jclouds.aws.s3.util.DateService;
import org.jclouds.aws.s3.util.S3Utils;
import org.jclouds.http.HttpResponse;
import org.jclouds.http.HttpResponseException;
import org.joda.time.DateTime;
import java.io.*;
import java.net.URLDecoder;
import java.util.*;
import java.util.concurrent.*;
/**
* // TODO: Adrian: Document this!
*
*
* @author Adrian Cole
*/
public class StubS3Connection implements S3Connection {
private static Map<String, Map<String, Object>> bucketToContents = new ConcurrentHashMap<String, Map<String, Object>>();
private static Map<String, Map<String, S3Object>> bucketToContents = new ConcurrentHashMap<String, Map<String, S3Object>>();
private static Map<String, Metadata.LocationConstraint> bucketToLocation = new ConcurrentHashMap<String, Metadata.LocationConstraint>();
private static Map<String, CannedAccessPolicy> keyToAcl = new ConcurrentHashMap<String, CannedAccessPolicy>();
/**
* @throws java.io.IOException
*/
public static byte[] toByteArray(Object data) throws IOException {
checkNotNull(data, "data must be set before calling generateMd5()");
byte[] bytes = null;
if (data == null || data instanceof byte[]) {
bytes = (byte[]) data;
} else if (data instanceof String) {
bytes = ((String) data).getBytes();
} else if (data instanceof File || data instanceof InputStream) {
InputStream io = (data instanceof InputStream) ? (InputStream) data : new FileInputStream((File) data);
bytes = IOUtils.toByteArray(io);
IOUtils.closeQuietly(io);
} else {
throw new UnsupportedOperationException("Content not supported "
+ data.getClass());
}
return bytes;
}
public Future<S3Object> getObject(final String s3Bucket, final String key) {
return new FutureBase<S3Object>() {
public S3Object get() throws InterruptedException,
ExecutionException {
if (!bucketToContents.containsKey(s3Bucket))
return S3Object.NOT_FOUND;
Map<String, Object> realContents = bucketToContents
.get(s3Bucket);
if (!realContents.containsKey(key))
return S3Object.NOT_FOUND;
S3Object object = new S3Object(key);
object.setData(realContents.get(key));
return object;
}
};
return getObject(s3Bucket, key, new GetObjectOptions());
}
public S3Object.Metadata copy(S3Object.Metadata in) {
return (S3Object.Metadata) xstream.fromXML(xstream.toXML(in));
}
public S3Object.Metadata copy(S3Object.Metadata in, String newKey) {
return (S3Object.Metadata) xstream.fromXML(xstream.toXML(in).replaceAll(in.getKey(), newKey));
}
public Future<S3Object.Metadata> headObject(final String s3Bucket,
final String key) {
return new FutureBase<S3Object.Metadata>() {
public S3Object.Metadata get() throws InterruptedException,
ExecutionException {
if (!bucketToContents.containsKey(s3Bucket))
return S3Object.Metadata.NOT_FOUND;
Map<String, Object> realContents = bucketToContents
.get(s3Bucket);
if (!realContents.containsKey(key))
return S3Object.Metadata.NOT_FOUND;
S3Object.Metadata metadata = new S3Object.Metadata(key);
return metadata;
}
};
final String key) {
return new FutureBase<S3Object.Metadata>() {
public S3Object.Metadata get() throws InterruptedException,
ExecutionException {
if (!bucketToContents.containsKey(s3Bucket))
return S3Object.Metadata.NOT_FOUND;
Map<String, S3Object> realContents = bucketToContents
.get(s3Bucket);
if (!realContents.containsKey(key))
return S3Object.Metadata.NOT_FOUND;
return realContents.get(key).getMetadata();
}
};
}
public Future<Boolean> deleteObject(final String s3Bucket, final String key) {
return new FutureBase<Boolean>() {
public Boolean get() throws InterruptedException,
ExecutionException {
if (bucketToContents.containsKey(s3Bucket)) {
bucketToContents.get(s3Bucket).remove(key);
}
return true;
}
};
return new FutureBase<Boolean>() {
public Boolean get() throws InterruptedException,
ExecutionException {
if (bucketToContents.containsKey(s3Bucket)) {
bucketToContents.get(s3Bucket).remove(key);
}
return true;
}
};
}
public Future<byte[]> putObject(final String s3Bucket, final S3Object object) {
return new FutureBase<byte[]>() {
public byte[] get() throws InterruptedException, ExecutionException {
if (!bucketToContents.containsKey(s3Bucket)) {
throw new ExecutionException(new RuntimeException(
"bucket not found: " + s3Bucket));
}
bucketToContents.get(s3Bucket).put(object.getKey(),
object.getClass());
return object.getKey().getBytes();// todo actually md5
}
};
return putObject(s3Bucket, object, new PutObjectOptions());
}
public Future<Boolean> putBucketIfNotExists(final String s3Bucket) {
return new FutureBase<Boolean>() {
public Boolean get() throws InterruptedException,
ExecutionException {
if (!bucketToContents.containsKey(s3Bucket)) {
bucketToContents.put(s3Bucket,
new ConcurrentHashMap<String, Object>());
}
return bucketToContents.containsKey(s3Bucket);
}
};
return new FutureBase<Boolean>() {
public Boolean get() throws InterruptedException,
ExecutionException {
if (!bucketToContents.containsKey(s3Bucket)) {
bucketToContents.put(s3Bucket,
new ConcurrentHashMap<String, S3Object>());
}
return bucketToContents.containsKey(s3Bucket);
}
};
}
public Future<Boolean> deleteBucketIfEmpty(final String s3Bucket) {
return new FutureBase<Boolean>() {
public Boolean get() throws InterruptedException,
ExecutionException {
if (bucketToContents.containsKey(s3Bucket)) {
if (bucketToContents.get(s3Bucket).size() == 0)
return true;
}
return false;
}
};
return new FutureBase<Boolean>() {
public Boolean get() throws InterruptedException,
ExecutionException {
if (bucketToContents.containsKey(s3Bucket)) {
if (bucketToContents.get(s3Bucket).size() == 0)
bucketToContents.remove(s3Bucket);
else
return false;
}
return true;
}
};
}
XStream xstream = new XStream();
public Future<S3Object.Metadata> copyObject(final String sourceBucket,
final String sourceObject, final String destinationBucket,
final String destinationObject) {
return new FutureBase<S3Object.Metadata>() {
public S3Object.Metadata get() throws InterruptedException,
ExecutionException {
Map<String, Object> source = bucketToContents.get(sourceBucket);
Map<String, Object> dest = bucketToContents
.get(destinationBucket);
if (source.containsKey(sourceObject)) {
dest.put(destinationObject, source.get(sourceObject));
return new S3Object.Metadata(destinationObject);
}
return S3Object.Metadata.NOT_FOUND;
}
};
final String sourceObject, final String destinationBucket,
final String destinationObject) {
return copyObject(sourceBucket, sourceObject, destinationBucket, destinationObject, new CopyObjectOptions());
}
public Future<Boolean> bucketExists(final String s3Bucket) {
return new FutureBase<Boolean>() {
public Boolean get() throws InterruptedException,
ExecutionException {
return bucketToContents.containsKey(s3Bucket);
}
};
return new FutureBase<Boolean>() {
public Boolean get() throws InterruptedException,
ExecutionException {
return bucketToContents.containsKey(s3Bucket);
}
};
}
public Future<S3Bucket> listBucket(final String s3Bucket) {
return new FutureBase<S3Bucket>() {
public S3Bucket get() throws InterruptedException,
ExecutionException {
Set<S3Object.Metadata> contents = new HashSet<S3Object.Metadata>();
Map<String, Object> realContents = bucketToContents
.get(s3Bucket);
if (realContents != null) {
for (String key : realContents.keySet()) {
S3Object.Metadata metadata = new S3Object.Metadata(key);
contents.add(metadata);
}
}
S3Bucket returnVal = new S3Bucket(s3Bucket);
returnVal.setContents(contents);
return returnVal;
}
}
;
return listBucket(s3Bucket, new ListBucketOptions());
}
private abstract class FutureBase<V> implements Future<V> {
public boolean cancel(boolean b) {
return false;
}
public boolean cancel(boolean b) {
return false;
}
public boolean isCancelled() {
return false;
}
public boolean isCancelled() {
return false;
}
public boolean isDone() {
return true;
}
public boolean isDone() {
return true;
}
public V get(long l, TimeUnit timeUnit) throws InterruptedException,
ExecutionException, TimeoutException {
return get();
}
public V get(long l, TimeUnit timeUnit) throws InterruptedException,
ExecutionException, TimeoutException {
return get();
}
}
public Future<List<Metadata>> listOwnedBuckets() {
return new FutureBase<List<S3Bucket.Metadata>>() {
public List<S3Bucket.Metadata> get() throws InterruptedException,
ExecutionException {
List<S3Bucket.Metadata> list = new ArrayList<S3Bucket.Metadata>();
for (String name : bucketToContents.keySet())
list.add(new S3Bucket.Metadata(name));
return list;
}
};
return new FutureBase<List<S3Bucket.Metadata>>() {
public List<S3Bucket.Metadata> get() throws InterruptedException,
ExecutionException {
return Lists.newArrayList(Iterables.transform(
bucketToContents.keySet(),
new Function<String, Metadata>() {
public Metadata apply(String name) {
return new S3Bucket.Metadata(name);
}
}));
}
};
}
public Future<Boolean> putBucketIfNotExists(String name,
PutBucketOptions options) {
throw new UnsupportedOperationException("todo");
PutBucketOptions options) {
if (options.getLocationConstraint() != null)
bucketToLocation.put(name, options.getLocationConstraint());
keyToAcl.put(name, options.getAcl());
return putBucketIfNotExists(name);
}
public Future<S3Bucket> listBucket(String name, ListBucketOptions options) {
throw new UnsupportedOperationException("todo");
class DelimiterFilter implements Predicate<S3Object.Metadata> {
private final String prefix;
private final String delimiter;
DelimiterFilter(String prefix, String delimiter) {
this.prefix = prefix;
this.delimiter = delimiter;
}
public boolean apply(S3Object.Metadata metadata) {
if (prefix == null)
return metadata.getKey().indexOf(delimiter) == -1;
if (metadata.getKey().startsWith(prefix))
return metadata.getKey().replaceFirst(prefix, "").indexOf(delimiter) == -1;
return false;
}
}
class CommonPrefixes implements Function<S3Object.Metadata, String> {
private final String prefix;
private final String delimiter;
static final String NO_PREFIX = "NO_PREFIX";
CommonPrefixes(String prefix, String delimiter) {
this.prefix = prefix;
this.delimiter = delimiter;
}
public String apply(S3Object.Metadata metadata) {
String working = metadata.getKey();
if (prefix != null) {
if (working.startsWith(prefix)) {
working = working.replaceFirst(prefix, "");
}
}
if (working.contains(delimiter)) {
return working.substring(0, working.indexOf(delimiter));
}
return NO_PREFIX;
}
}
public Future<S3Bucket> listBucket(final String name, final ListBucketOptions options) {
return new FutureBase<S3Bucket>() {
public S3Bucket get() throws InterruptedException,
ExecutionException {
final Map<String, S3Object> realContents = bucketToContents
.get(name);
if (realContents == null) return S3Bucket.NOT_FOUND;
SortedSet<S3Object.Metadata> contents = Sets.newTreeSet(
Iterables.transform(realContents.keySet(),
new Function<String, S3Object.Metadata>() {
public S3Object.Metadata apply(String key) {
return realContents.get(key).getMetadata();
}
}));
S3Bucket returnVal = new S3Bucket(name);
if (options.getMarker() != null) {
contents = contents.tailSet(new S3Object.Metadata(URLDecoder.decode(options.getMarker())));
// amazon spec means after the marker, not including it.
contents.remove(new S3Object.Metadata(options.getMarker()));
returnVal.setMarker(URLDecoder.decode(options.getMarker()));
}
if (options.getPrefix() != null) {
contents = Sets.newTreeSet(Iterables.filter(contents, new Predicate<S3Object.Metadata>() {
public boolean apply(S3Object.Metadata o) {
return (o != null && o.getKey().startsWith(URLDecoder.decode(options.getPrefix())));
}
}));
returnVal.setPrefix(URLDecoder.decode(options.getPrefix()));
}
if (options.getDelimiter() != null) {
Iterable<String> iterable = Iterables.transform(contents, new CommonPrefixes(
options.getPrefix() != null ? URLDecoder.decode(options.getPrefix()) : null, URLDecoder.decode(options.getDelimiter())));
Set<String> commonPrefixes = iterable != null ? Sets.newTreeSet(iterable) : new HashSet<String>();
commonPrefixes.remove(CommonPrefixes.NO_PREFIX);
contents = Sets.newTreeSet(Iterables.filter(contents, new DelimiterFilter(
options.getPrefix() != null ? URLDecoder.decode(options.getPrefix()) : null, URLDecoder.decode(options.getDelimiter()))));
returnVal.setCommonPrefixes(commonPrefixes);
returnVal.setDelimiter(URLDecoder.decode(options.getDelimiter()));
}
if (options.getMaxKeys() != null) {
contents = firstSliceOfSize(contents, Integer.parseInt(options.getMaxKeys()));
returnVal.setMaxKeys(Integer.parseInt(options.getMaxKeys()));
returnVal.setTruncated(true);
}
returnVal.setContents(contents);
return returnVal;
}
};
}
public static <T extends Comparable> SortedSet<T> firstSliceOfSize(Iterable<T> elements, int size) {
List<List<T>> slices = Lists.partition(
Lists.newArrayList(elements), size);
return Sets.newTreeSet(slices.get(0));
}
public Future<org.jclouds.aws.s3.domain.S3Object.Metadata> copyObject(
String sourceBucket, String sourceObject, String destinationBucket,
String destinationObject, CopyObjectOptions options) {
// TODO Auto-generated method stub
return null;
final String sourceBucket, final String sourceObject, final String destinationBucket,
final String destinationObject, final CopyObjectOptions options) {
return new FutureBase<S3Object.Metadata>() {
public S3Object.Metadata get() throws InterruptedException,
ExecutionException {
Map<String, S3Object> source = bucketToContents.get(sourceBucket);
Map<String, S3Object> dest = bucketToContents
.get(destinationBucket);
if (source.containsKey(sourceObject)) {
S3Object object = source.get(sourceObject);
if (options.getIfMatch() != null) {
if (!Arrays.equals(object.getMetadata().getMd5(), S3Utils.fromHexString(options.getIfMatch().replaceAll("\"", ""))))
throwResponseException(412);
}
if (options.getIfNoneMatch() != null) {
if (Arrays.equals(object.getMetadata().getMd5(), S3Utils.fromHexString(options.getIfNoneMatch().replaceAll("\"", ""))))
throwResponseException(412);
}
if (options.getIfModifiedSince() != null) {
DateTime modifiedSince = dateService.dateTimeFromHeaderFormat(options.getIfModifiedSince());
if (modifiedSince.isAfter(object.getMetadata().getLastModified()))
throw new ExecutionException(new RuntimeException("after"));
}
if (options.getIfUnmodifiedSince() != null) {
DateTime unmodifiedSince = dateService.dateTimeFromHeaderFormat(options.getIfUnmodifiedSince());
if (unmodifiedSince.isAfter(object.getMetadata().getLastModified()))
throw new ExecutionException(new RuntimeException("after"));
}
S3Object sourceS3 = source.get(sourceObject);
S3Object.Metadata newMd = copy(sourceS3.getMetadata(), destinationObject);
if (options.getAcl() != null)
keyToAcl.put(destinationBucket + destinationObject, options.getAcl());
if (options.getMetadata() != null) {
newMd.setUserMetadata(options.getMetadata());
}
newMd.setLastModified(new DateTime());
dest.put(destinationObject, new S3Object(newMd,
sourceS3.getData()));
return copy(newMd);
}
return S3Object.Metadata.NOT_FOUND;
}
};
}
public Future<byte[]> putObject(String bucketName, S3Object object,
PutObjectOptions options) {
// TODO Auto-generated method stub
return null;
private void throwResponseException(int code) throws ExecutionException {
HttpResponse response = new HttpResponse();
response.setStatusCode(code);
throw new ExecutionException(
new HttpResponseException(createNiceMock(CopyObject.class), response));
}
public Future<S3Object> getObject(String bucketName, String key,
GetObjectOptions options) {
// TODO Auto-generated method stub
return null;
public Future<byte[]> putObject(final String bucketName, final S3Object object,
final PutObjectOptions options) {
if (!bucketToContents.containsKey(bucketName)) {
new RuntimeException(
"bucketName not found: " + bucketName);
}
try {
S3Object.Metadata newMd = copy(object.getMetadata());
newMd.setLastModified(new DateTime());
byte[] data = toByteArray(object.getData());
final byte[] md5 = S3Utils.md5(data);
newMd.setMd5(md5);
newMd.setContentType("binary/octet-stream");
if (options.getAcl() != null)
keyToAcl.put(bucketName + object, options.getAcl());
bucketToContents.get(bucketName).put(object.getKey(),
new S3Object(newMd, data));
return new FutureBase<byte[]>() {
public byte[] get() throws InterruptedException, ExecutionException {
return md5;
}
};
} catch (IOException e) {
throw new RuntimeException(e);
}
}
DateService dateService = new DateService();
public Future<S3Object> getObject(final String bucketName, final String key,
final GetObjectOptions options) {
return new FutureBase<S3Object>() {
public S3Object get() throws InterruptedException,
ExecutionException {
if (!bucketToContents.containsKey(bucketName))
return S3Object.NOT_FOUND;
Map<String, S3Object> realContents = bucketToContents
.get(bucketName);
if (!realContents.containsKey(key))
return S3Object.NOT_FOUND;
S3Object object = realContents.get(key);
if (options.getIfMatch() != null) {
if (!Arrays.equals(object.getMetadata().getMd5(), S3Utils.fromHexString(options.getIfMatch().replaceAll("\"", ""))))
throwResponseException(412);
}
if (options.getIfNoneMatch() != null) {
if (Arrays.equals(object.getMetadata().getMd5(), S3Utils.fromHexString(options.getIfNoneMatch().replaceAll("\"", ""))))
throwResponseException(304);
}
if (options.getIfModifiedSince() != null) {
DateTime modifiedSince = dateService.dateTimeFromHeaderFormat(options.getIfModifiedSince());
if (modifiedSince.isAfter(object.getMetadata().getLastModified()))
throw new ExecutionException(new RuntimeException("after"));
}
if (options.getIfUnmodifiedSince() != null) {
DateTime unmodifiedSince = dateService.dateTimeFromHeaderFormat(options.getIfUnmodifiedSince());
if (unmodifiedSince.isAfter(object.getMetadata().getLastModified()))
throw new ExecutionException(new RuntimeException("after"));
}
S3Object returnVal = new S3Object(copy(object.getMetadata()), object.getData());
if (options.getRange() != null) {
byte[] data = (byte[]) returnVal.getData();
ByteArrayOutputStream out = new ByteArrayOutputStream();
for (String s : options.getRange().replaceAll("bytes=", "").split(",")) {
if (s.startsWith("-")) {
int length = Integer.parseInt(s.replaceAll("\\-", ""));
out.write(data, data.length - length, length);
} else if (s.endsWith("-")) {
int offset = Integer.parseInt(s.replaceAll("\\-", ""));
out.write(data, offset, data.length - offset);
} else if (s.contains("-")) {
String[] firstLast = s.split("\\-");
int offset = Integer.parseInt(firstLast[0]);
int last = Integer.parseInt(firstLast[1]);
int length = (last < data.length) ? last + 1 : data.length - offset;
out.write(data, offset, length);
} else {
throw new IllegalArgumentException("first and last were null!");
}
}
returnVal.setData(out.toByteArray());
returnVal.setContentLength(out.size());
returnVal.getMetadata().setSize(data.length);
}
returnVal.setData(new ByteArrayInputStream((byte[]) returnVal.getData()));
return returnVal;
}
};
}
}

View File

@ -23,35 +23,35 @@
*/
package org.jclouds.aws.s3.commands;
import java.util.concurrent.TimeUnit;
import org.jclouds.aws.s3.S3IntegrationTest;
import org.testng.annotations.Test;
import org.testng.annotations.BeforeMethod;
import java.util.concurrent.TimeUnit;
/**
* Tests integrated functionality of all bucketExists commands.
* <p/>
* Each test uses a different bucket name, so it should be perfectly fine to run
* in parallel.
*
*
* @author Adrian Cole
*
*/
@Test(groups = "integration", testName = "s3.BucketExistsIntegrationTest")
@Test(groups = {"integration", "live"}, testName = "s3.BucketExistsIntegrationTest")
public class BucketExistsIntegrationTest extends S3IntegrationTest {
@Test()
@Test
void bucketDoesntExist() throws Exception {
String bucketName = bucketPrefix + "shouldntexist";
assert !client.bucketExists(bucketName).get(10, TimeUnit.SECONDS);
String bucketName= bucketPrefix+"be";
assert !client.bucketExists(bucketName).get(10, TimeUnit.SECONDS);
}
@Test()
@Test
void bucketExists() throws Exception {
String bucketName = bucketPrefix + "needstoexist";
assert client.putBucketIfNotExists(bucketName).get(10,
TimeUnit.SECONDS);
assert client.bucketExists(bucketName).get(10, TimeUnit.SECONDS);
String bucketName= bucketPrefix+"bde";
assert client.putBucketIfNotExists(bucketName).get(10,
TimeUnit.SECONDS);
assert client.bucketExists(bucketName).get(10, TimeUnit.SECONDS);
}
}

View File

@ -23,13 +23,18 @@
*/
package org.jclouds.aws.s3.commands;
import static org.jclouds.aws.s3.commands.options.CopyObjectOptions.Builder.ifSourceMd5DoesntMatch;
import static org.jclouds.aws.s3.commands.options.CopyObjectOptions.Builder.ifSourceMd5Matches;
import static org.jclouds.aws.s3.commands.options.CopyObjectOptions.Builder.ifSourceModifiedSince;
import static org.jclouds.aws.s3.commands.options.CopyObjectOptions.Builder.ifSourceUnmodifiedSince;
import static org.jclouds.aws.s3.commands.options.CopyObjectOptions.Builder.overrideAcl;
import static org.jclouds.aws.s3.commands.options.CopyObjectOptions.Builder.overrideMetadataWith;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;
import org.jclouds.aws.s3.S3IntegrationTest;
import static org.jclouds.aws.s3.commands.options.CopyObjectOptions.Builder.*;
import org.jclouds.aws.s3.domain.S3Object;
import org.jclouds.aws.s3.domain.acl.CannedAccessPolicy;
import org.jclouds.aws.s3.reference.S3Headers;
import org.jclouds.aws.s3.util.S3Utils;
import org.jclouds.http.HttpResponseException;
import org.joda.time.DateTime;
import static org.testng.Assert.assertEquals;
import org.testng.annotations.Test;
import java.io.IOException;
import java.net.URL;
@ -37,205 +42,166 @@ import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.jclouds.aws.s3.S3IntegrationTest;
import org.jclouds.aws.s3.domain.S3Object;
import org.jclouds.aws.s3.domain.acl.CannedAccessPolicy;
import org.jclouds.aws.s3.reference.S3Headers;
import org.jclouds.aws.s3.util.S3Utils;
import org.jclouds.http.HttpResponseException;
import org.joda.time.DateTime;
import org.testng.annotations.Test;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;
/**
* Tests integrated functionality of all copyObject commands.
* <p/>
* Each test uses a different bucket name, so it should be perfectly fine to run
* in parallel.
*
*
* @author Adrian Cole
*
*/
@Test(groups = "integration", testName = "s3.CopyObjectIntegrationTest")
@Test(testName = "s3.CopyObjectIntegrationTest")
public class CopyObjectIntegrationTest extends S3IntegrationTest {
String sourceKey = "apples";
String destinationKey = "pears";
@Test()
void testCannedAccessPolicyPublic() throws Exception {
String sourceBucket = bucketPrefix + "tcapp";
String destinationBucket = sourceBucket + "dest";
setupSourceBucket(sourceBucket, sourceKey);
createBucketAndEnsureEmpty(destinationBucket);
client.copyObject(sourceBucket, sourceKey, destinationBucket,
destinationKey,overrideAcl(CannedAccessPolicy.PUBLIC_READ)).get(10, TimeUnit.SECONDS);
validateContent(destinationBucket, destinationKey);
URL url = new URL(String.format("http://%1$s.s3.amazonaws.com/%2$s",
destinationBucket, destinationKey));
S3Utils.toStringAndClose(url.openStream());
}
@Test()
@Test(groups = {"integration","live"})
void testCopyObject() throws Exception {
String sourceBucket = bucketPrefix + "testcopyobject";
String destinationBucket = sourceBucket + "dest";
setupSourceBucket(sourceBucket, sourceKey);
String destinationBucket = bucketName + "dest";
createBucketAndEnsureEmpty(destinationBucket);
client.copyObject(sourceBucket, sourceKey, destinationBucket,
destinationKey).get(10, TimeUnit.SECONDS);
addToBucketAndValidate(bucketName, sourceKey);
validateContent(destinationBucket, destinationKey);
createBucketAndEnsureEmpty(destinationBucket);
client.copyObject(bucketName, sourceKey, destinationBucket,
destinationKey).get(10, TimeUnit.SECONDS);
validateContent(destinationBucket, destinationKey);
}
private void setupSourceBucket(String sourceBucket, String sourceKey)
throws InterruptedException, ExecutionException, TimeoutException,
IOException {
createBucketAndEnsureEmpty(sourceBucket);
addToBucketAndValidate(sourceBucket, sourceKey);
private void addToBucketAndValidate(String bucketName, String sourceKey)
throws InterruptedException, ExecutionException, TimeoutException,
IOException {
addObjectToBucket(bucketName, sourceKey);
validateContent(bucketName, sourceKey);
}
private void addToBucketAndValidate(String sourceBucket, String sourceKey)
throws InterruptedException, ExecutionException, TimeoutException,
IOException {
addObjectToBucket(sourceBucket, sourceKey);
validateContent(sourceBucket, sourceKey);
}
@Test
@Test(groups = {"integration","live"})
void testCopyIfModifiedSince() throws InterruptedException,
ExecutionException, TimeoutException, IOException {
String sourceBucket = bucketPrefix + "tcims";
String destinationBucket = sourceBucket + "dest";
ExecutionException, TimeoutException, IOException {
DateTime before = new DateTime();
setupSourceBucket(sourceBucket, sourceKey);
DateTime after = new DateTime().plusSeconds(1);
String destinationBucket = bucketName + "dest";
createBucketAndEnsureEmpty(destinationBucket);
client.copyObject(sourceBucket, sourceKey, destinationBucket,
destinationKey, ifSourceModifiedSince(before)).get(10,
TimeUnit.SECONDS);
validateContent(destinationBucket, destinationKey);
DateTime before = new DateTime();
addToBucketAndValidate(bucketName, sourceKey);
DateTime after = new DateTime().plusSeconds(1);
try {
client.copyObject(sourceBucket, sourceKey, destinationBucket,
destinationKey, ifSourceModifiedSince(after)).get(10,
TimeUnit.SECONDS);
} catch (ExecutionException e) {
HttpResponseException ex = (HttpResponseException) e.getCause();
assertEquals(ex.getResponse().getStatusCode(), 412);
}
createBucketAndEnsureEmpty(destinationBucket);
client.copyObject(bucketName, sourceKey, destinationBucket,
destinationKey, ifSourceModifiedSince(before)).get(10,
TimeUnit.SECONDS);
validateContent(destinationBucket, destinationKey);
try {
client.copyObject(bucketName, sourceKey, destinationBucket,
destinationKey, ifSourceModifiedSince(after)).get(10,
TimeUnit.SECONDS);
} catch (ExecutionException e) {
HttpResponseException ex = (HttpResponseException) e.getCause();
assertEquals(ex.getResponse().getStatusCode(), 412);
}
}
@Test
@Test(groups = {"integration","live"})
void testCopyIfUnmodifiedSince() throws InterruptedException,
ExecutionException, TimeoutException, IOException {
String sourceBucket = bucketPrefix + "tcius";
String destinationBucket = sourceBucket + "dest";
ExecutionException, TimeoutException, IOException {
DateTime before = new DateTime();
setupSourceBucket(sourceBucket, sourceKey);
DateTime after = new DateTime().plusSeconds(1);
String destinationBucket = bucketName + "dest";
createBucketAndEnsureEmpty(destinationBucket);
client.copyObject(sourceBucket, sourceKey, destinationBucket,
destinationKey, ifSourceUnmodifiedSince(after)).get(10,
TimeUnit.SECONDS);
validateContent(destinationBucket, destinationKey);
DateTime before = new DateTime();
addToBucketAndValidate(bucketName, sourceKey);
DateTime after = new DateTime().plusSeconds(1);
try {
client.copyObject(sourceBucket, sourceKey, destinationBucket,
destinationKey, ifSourceModifiedSince(before)).get(10,
TimeUnit.SECONDS);
} catch (ExecutionException e) {
HttpResponseException ex = (HttpResponseException) e.getCause();
assertEquals(ex.getResponse().getStatusCode(), 412);
}
createBucketAndEnsureEmpty(destinationBucket);
client.copyObject(bucketName, sourceKey, destinationBucket,
destinationKey, ifSourceUnmodifiedSince(after)).get(10,
TimeUnit.SECONDS);
validateContent(destinationBucket, destinationKey);
try {
client.copyObject(bucketName, sourceKey, destinationBucket,
destinationKey, ifSourceModifiedSince(before)).get(10,
TimeUnit.SECONDS);
} catch (ExecutionException e) {
HttpResponseException ex = (HttpResponseException) e.getCause();
assertEquals(ex.getResponse().getStatusCode(), 412);
}
}
@Test
@Test(groups = {"integration","live"})
void testCopyIfMatch() throws InterruptedException, ExecutionException,
TimeoutException, IOException {
String sourceBucket = bucketPrefix + "tcim";
TimeoutException, IOException {
String destinationBucket = sourceBucket + "dest";
setupSourceBucket(sourceBucket, sourceKey);
String destinationBucket = bucketName + "dest";
createBucketAndEnsureEmpty(destinationBucket);
client.copyObject(sourceBucket, sourceKey, destinationBucket,
destinationKey, ifSourceMd5Matches(goodMd5)).get(10,
TimeUnit.SECONDS);
validateContent(destinationBucket, destinationKey);
addToBucketAndValidate(bucketName, sourceKey);
try {
client.copyObject(sourceBucket, sourceKey, destinationBucket,
destinationKey, ifSourceMd5Matches(badMd5)).get(10,
TimeUnit.SECONDS);
} catch (ExecutionException e) {
HttpResponseException ex = (HttpResponseException) e.getCause();
assertEquals(ex.getResponse().getStatusCode(), 412);
}
createBucketAndEnsureEmpty(destinationBucket);
client.copyObject(bucketName, sourceKey, destinationBucket,
destinationKey, ifSourceMd5Matches(goodMd5)).get(10,
TimeUnit.SECONDS);
validateContent(destinationBucket, destinationKey);
try {
client.copyObject(bucketName, sourceKey, destinationBucket,
destinationKey, ifSourceMd5Matches(badMd5)).get(10,
TimeUnit.SECONDS);
} catch (ExecutionException e) {
HttpResponseException ex = (HttpResponseException) e.getCause();
assertEquals(ex.getResponse().getStatusCode(), 412);
}
}
@Test
@Test(groups = {"integration","live"})
void testCopyIfNoneMatch() throws IOException, InterruptedException,
ExecutionException, TimeoutException {
String sourceBucket = bucketPrefix + "tcinm";
ExecutionException, TimeoutException {
String destinationBucket = sourceBucket + "dest";
setupSourceBucket(sourceBucket, sourceKey);
String destinationBucket = bucketName + "dest";
createBucketAndEnsureEmpty(destinationBucket);
client.copyObject(sourceBucket, sourceKey, destinationBucket,
destinationKey, ifSourceMd5DoesntMatch(badMd5)).get(10,
TimeUnit.SECONDS);
validateContent(destinationBucket, destinationKey);
addToBucketAndValidate(bucketName, sourceKey);
try {
client.copyObject(sourceBucket, sourceKey, destinationBucket,
destinationKey, ifSourceMd5DoesntMatch(goodMd5)).get(10,
TimeUnit.SECONDS);
} catch (ExecutionException e) {
HttpResponseException ex = (HttpResponseException) e.getCause();
assertEquals(ex.getResponse().getStatusCode(), 412);
}
createBucketAndEnsureEmpty(destinationBucket);
client.copyObject(bucketName, sourceKey, destinationBucket,
destinationKey, ifSourceMd5DoesntMatch(badMd5)).get(10,
TimeUnit.SECONDS);
validateContent(destinationBucket, destinationKey);
try {
client.copyObject(bucketName, sourceKey, destinationBucket,
destinationKey, ifSourceMd5DoesntMatch(goodMd5)).get(10,
TimeUnit.SECONDS);
} catch (ExecutionException e) {
HttpResponseException ex = (HttpResponseException) e.getCause();
assertEquals(ex.getResponse().getStatusCode(), 412);
}
}
@Test
@Test(groups = {"integration","live"})
void testCopyWithMetadata() throws InterruptedException,
ExecutionException, TimeoutException, IOException {
String sourceBucket = bucketPrefix + "tcwm";
String destinationBucket = sourceBucket + "dest";
ExecutionException, TimeoutException, IOException {
setupSourceBucket(sourceBucket, sourceKey);
String destinationBucket = bucketName + "dest";
Multimap<String, String> metadata = HashMultimap.create();
metadata.put(S3Headers.USER_METADATA_PREFIX + "adrian", "cole");
addToBucketAndValidate(bucketName, sourceKey);
createBucketAndEnsureEmpty(destinationBucket);
client.copyObject(sourceBucket, sourceKey, destinationBucket,
destinationKey, overrideMetadataWith(metadata)).get(10,
TimeUnit.SECONDS);
Multimap<String, String> metadata = HashMultimap.create();
metadata.put(S3Headers.USER_METADATA_PREFIX + "adrian", "cole");
validateContent(destinationBucket, destinationKey);
createBucketAndEnsureEmpty(destinationBucket);
client.copyObject(bucketName, sourceKey, destinationBucket,
destinationKey, overrideMetadataWith(metadata)).get(10,
TimeUnit.SECONDS);
S3Object.Metadata objectMeta = client.headObject(destinationBucket,
destinationKey).get(10, TimeUnit.SECONDS);
validateContent(destinationBucket, destinationKey);
assertEquals(objectMeta.getUserMetadata(), metadata);
S3Object.Metadata objectMeta = client.headObject(destinationBucket,
destinationKey).get(10, TimeUnit.SECONDS);
assertEquals(objectMeta.getUserMetadata(), metadata);
}
}

View File

@ -0,0 +1,68 @@
/**
*
* Copyright (C) 2009 Adrian Cole <adrian@jclouds.org>
*
* ====================================================================
* 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.commands;
import org.jclouds.aws.s3.S3IntegrationTest;
import static org.jclouds.aws.s3.commands.options.CopyObjectOptions.Builder.overrideAcl;
import org.jclouds.aws.s3.domain.acl.CannedAccessPolicy;
import org.jclouds.aws.s3.util.S3Utils;
import org.testng.annotations.Test;
import java.net.URL;
import java.util.concurrent.TimeUnit;
/**
* Tests integrated functionality of all copyObject commands.
* <p/>
* Each test uses a different bucket name, so it should be perfectly fine to run
* in parallel.
*
* @author Adrian Cole
*/
@Test(testName = "s3.CopyObjectLiveTest")
public class CopyObjectLiveTest extends S3IntegrationTest {
String sourceKey = "apples";
String destinationKey = "pears";
@Test(groups = "live")
void testCannedAccessPolicyPublic() throws Exception {
String destinationBucket = bucketName + "dest";
addObjectToBucket(bucketName, sourceKey);
validateContent(bucketName, sourceKey);
createBucketAndEnsureEmpty(destinationBucket);
client.copyObject(bucketName, sourceKey, destinationBucket,
destinationKey, overrideAcl(CannedAccessPolicy.PUBLIC_READ)).get(10, TimeUnit.SECONDS);
validateContent(destinationBucket, destinationKey);
URL url = new URL(String.format("http://%1$s.s3.amazonaws.com/%2$s",
destinationBucket, destinationKey));
S3Utils.toStringAndClose(url.openStream());
}
}

View File

@ -23,42 +23,40 @@
*/
package org.jclouds.aws.s3.commands;
import java.util.concurrent.TimeUnit;
import org.jclouds.aws.s3.S3IntegrationTest;
import org.testng.annotations.Test;
import java.util.concurrent.TimeUnit;
/**
* Tests integrated functionality of all deleteBucket commands.
* <p/>
* Each test uses a different bucket name, so it should be perfectly fine to run
* in parallel.
*
*
* @author Adrian Cole
*
*/
@Test(groups = "integration", testName = "s3.DeleteBucketIntegrationTest")
@Test(groups = {"integration", "live"}, testName = "s3.DeleteBucketIntegrationTest")
public class DeleteBucketIntegrationTest extends S3IntegrationTest {
@Test()
@Test
/**
* this method overrides bucketName to ensure it isn't found
*/
void deleteBucketIfEmptyNotFound() throws Exception {
String bucketName = bucketPrefix + "dbienf";
assert client.deleteBucketIfEmpty(bucketName).get(10, TimeUnit.SECONDS);
String bucketName = bucketPrefix + "dbienf";
assert client.deleteBucketIfEmpty(bucketName).get(10, TimeUnit.SECONDS);
}
@Test()
void deleteBucketIfEmptyButHasContents() throws Exception {
String bucketName = bucketPrefix + "dbiebhc";
createBucketAndEnsureEmpty(bucketName);
addObjectToBucket(bucketName,"test");
assert !client.deleteBucketIfEmpty(bucketName).get(10, TimeUnit.SECONDS);
addObjectToBucket(bucketName, "test");
assert !client.deleteBucketIfEmpty(bucketName).get(10, TimeUnit.SECONDS);
}
@Test()
void deleteBucketIfEmpty() throws Exception {
String bucketName = bucketPrefix + "dbie";
createBucketAndEnsureEmpty(bucketName);
assert client.deleteBucketIfEmpty(bucketName).get(10, TimeUnit.SECONDS);
assert !client.bucketExists(bucketName).get(10, TimeUnit.SECONDS);
assert client.deleteBucketIfEmpty(bucketName).get(10, TimeUnit.SECONDS);
assert !client.bucketExists(bucketName).get(10, TimeUnit.SECONDS);
}
}

View File

@ -23,56 +23,55 @@
*/
package org.jclouds.aws.s3.commands;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import org.jclouds.aws.s3.S3IntegrationTest;
import org.jclouds.aws.s3.S3ResponseException;
import org.jclouds.aws.s3.domain.S3Object;
import org.testng.annotations.Test;
import static org.testng.Assert.assertEquals;
import org.testng.annotations.Test;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
/**
* Tests integrated functionality of all deleteObject commands.
* <p/>
* Each test uses a different bucket name, so it should be perfectly fine to run
* in parallel.
*
*
* @author Adrian Cole
*
*/
@Test(groups = "integration", testName = "s3.DeleteObjectIntegrationTest")
@Test(groups = {"integration", "live"}, testName = "s3.DeleteObjectIntegrationTest")
public class DeleteObjectIntegrationTest extends S3IntegrationTest {
@Test()
void deleteObjectNotFound() throws Exception {
String bucketName = bucketPrefix + "donf";
createBucketAndEnsureEmpty(bucketName);
addObjectToBucket(bucketName, "test");
assert client.deleteObject(bucketName, "test")
.get(10, TimeUnit.SECONDS);
String bucketName = bucketPrefix + "donf";
createBucketAndEnsureEmpty(bucketName);
addObjectToBucket(bucketName, "test");
assert client.deleteObject(bucketName, "test")
.get(10, TimeUnit.SECONDS);
}
@Test
void deleteObjectNoBucket() throws Exception {
String bucketName = bucketPrefix + "donb";
try {
client.deleteObject(bucketName, "test").get(10, TimeUnit.SECONDS);
} catch (ExecutionException e) {
assert e.getCause() instanceof S3ResponseException;
assertEquals(((S3ResponseException) e.getCause()).getResponse()
.getStatusCode(), 404);
}
String bucketName = bucketPrefix + "donb";
try {
client.deleteObject(bucketName, "test").get(10, TimeUnit.SECONDS);
} catch (ExecutionException e) {
assert e.getCause() instanceof S3ResponseException;
assertEquals(((S3ResponseException) e.getCause()).getResponse()
.getStatusCode(), 404);
}
}
@Test()
void deleteObject() throws Exception {
String bucketName = bucketPrefix + "do";
createBucketAndEnsureEmpty(bucketName);
addObjectToBucket(bucketName, "test");
assert client.deleteObject(bucketName, "test")
.get(10, TimeUnit.SECONDS);
assert client.headObject(bucketName, "test").get(10, TimeUnit.SECONDS) == S3Object.Metadata.NOT_FOUND;
String bucketName = bucketPrefix + "do";
createBucketAndEnsureEmpty(bucketName);
addObjectToBucket(bucketName, "test");
assert client.deleteObject(bucketName, "test")
.get(10, TimeUnit.SECONDS);
assert client.headObject(bucketName, "test").get(10, TimeUnit.SECONDS) == S3Object.Metadata.NOT_FOUND;
}
}

View File

@ -11,7 +11,7 @@
* "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
* 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
@ -23,212 +23,209 @@
*/
package org.jclouds.aws.s3.commands;
import org.jclouds.aws.s3.S3IntegrationTest;
import org.jclouds.aws.s3.S3ResponseException;
import static org.jclouds.aws.s3.commands.options.GetObjectOptions.Builder.*;
import org.jclouds.aws.s3.domain.S3Object;
import org.jclouds.aws.s3.util.S3Utils;
import org.jclouds.http.HttpResponseException;
import org.joda.time.DateTime;
import static org.testng.Assert.assertEquals;
import org.testng.annotations.Test;
import java.io.IOException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.jclouds.aws.s3.S3IntegrationTest;
import org.jclouds.aws.s3.domain.S3Object;
import org.jclouds.aws.s3.util.S3Utils;
import org.testng.annotations.Test;
/**
* Tests integrated functionality of all GetObject commands.
* <p/>
* Each test uses a different bucket name, so it should be perfectly fine to run
* in parallel.
*
*
* @author Adrian Cole
*
*/
@Test(groups = "integration", testName = "s3.GetObjectIntegrationTest")
@Test(groups = {"integration", "live"}, testName = "s3.GetObjectIntegrationTest")
public class GetObjectIntegrationTest extends S3IntegrationTest {
//
// @Test
// void testGetIfModifiedSince() throws InterruptedException,
// ExecutionException, TimeoutException, IOException {
// String bucket = bucketPrefix + "testGetIfModifiedSince".toLowerCase();
// String key = "apples";
//
// DateTime before = new DateTime();
// setUpBucket(bucket, key);
// DateTime after = new DateTime().plusSeconds(1);
//
// client.getObject(bucket, key, ifModifiedSince(before)).get(10,
// TimeUnit.SECONDS);
// validateContent(bucket, key);
//
// try {
// client.getObject(bucket, key, ifModifiedSince(after)).get(10,
// TimeUnit.SECONDS);
// validateContent(bucket, key);
// } catch (ExecutionException e) {
// if (e.getCause() instanceof HttpResponseException) {
// HttpResponseException ex = (HttpResponseException) e.getCause();
// assertEquals(ex.getResponse().getStatusCode(), 304);
// } else {
// throw e;
// }
// }
//
// }
//
//
// @Test
// void testGetIfUnmodifiedSince() throws InterruptedException,
// ExecutionException, TimeoutException, IOException {
// String bucket = bucketPrefix + "testGetIfUnmodifiedSince".toLowerCase();
// String key = "apples";
//
// DateTime before = new DateTime();
// setUpBucket(bucket, key);
// DateTime after = new DateTime().plusSeconds(1);
//
// client.getObject(bucket, key, ifUnmodifiedSince(after)).get(10,
// TimeUnit.SECONDS);
// validateContent(bucket, key);
//
// try {
// client.getObject(bucket, key, ifUnmodifiedSince(before)).get(10,
// TimeUnit.SECONDS);
// validateContent(bucket, key);
// } catch (ExecutionException e) {
// if (e.getCause() instanceof S3ResponseException) {
// S3ResponseException ex = (S3ResponseException) e.getCause();
// assertEquals(ex.getResponse().getStatusCode(), 412);
// } else {
// throw e;
// }
// }
//
// }
//
// @Test
// void testGetIfMatch() throws InterruptedException, ExecutionException,
// TimeoutException, IOException {
// String bucket = bucketPrefix + "testGetIfMatch".toLowerCase();
// String key = "apples";
//
// setUpBucket(bucket, key);
//
// client.getObject(bucket, key, ifMd5Matches(goodMd5)).get(10,
// TimeUnit.SECONDS);
// validateContent(bucket, key);
//
// try {
// client.getObject(bucket, key, ifMd5Matches(badMd5)).get(10,
// TimeUnit.SECONDS);
// validateContent(bucket, key);
// } catch (ExecutionException e) {
// if (e.getCause() instanceof S3ResponseException) {
// S3ResponseException ex = (S3ResponseException) e.getCause();
// assertEquals(ex.getResponse().getStatusCode(), 412);
// } else {
// throw e;
// }
// }
// }
//
// @Test
// void testGetIfNoneMatch() throws InterruptedException,
// ExecutionException,
// TimeoutException, IOException {
// String bucket = bucketPrefix + "testGetIfNoneMatch".toLowerCase();
// String key = "apples";
//
// setUpBucket(bucket, key);
//
// client.getObject(bucket, key, ifMd5DoesntMatch(badMd5)).get(10,
// TimeUnit.SECONDS);
// validateContent(bucket, key);
//
// try {
// client.getObject(bucket, key, ifMd5DoesntMatch(goodMd5)).get(10,
// TimeUnit.SECONDS);
// validateContent(bucket, key);
// } catch (ExecutionException e) {
// if (e.getCause() instanceof HttpResponseException) {
// HttpResponseException ex = (HttpResponseException) e.getCause();
// assertEquals(ex.getResponse().getStatusCode(), 304);
// } else {
// throw e;
// }
// }
// }
@Test
void testGetIfModifiedSince() throws InterruptedException,
ExecutionException, TimeoutException, IOException {
String key = "apples";
DateTime before = new DateTime();
addObjectAndValidateContent(bucketName, key);
DateTime after = new DateTime().plusSeconds(1);
client.getObject(bucketName, key, ifModifiedSince(before)).get(10,
TimeUnit.SECONDS);
validateContent(bucketName, key);
try {
client.getObject(bucketName, key, ifModifiedSince(after)).get(10,
TimeUnit.SECONDS);
validateContent(bucketName, key);
} catch (ExecutionException e) {
if (e.getCause() instanceof HttpResponseException) {
HttpResponseException ex = (HttpResponseException) e.getCause();
assertEquals(ex.getResponse().getStatusCode(), 304);
} else {
throw e;
}
}
}
@Test
void testGetIfUnmodifiedSince() throws InterruptedException,
ExecutionException, TimeoutException, IOException {
String key = "apples";
DateTime before = new DateTime();
addObjectAndValidateContent(bucketName, key);
DateTime after = new DateTime().plusSeconds(1);
client.getObject(bucketName, key, ifUnmodifiedSince(after)).get(10,
TimeUnit.SECONDS);
validateContent(bucketName, key);
try {
client.getObject(bucketName, key, ifUnmodifiedSince(before)).get(10,
TimeUnit.SECONDS);
validateContent(bucketName, key);
} catch (ExecutionException e) {
if (e.getCause() instanceof HttpResponseException) {
HttpResponseException ex = (HttpResponseException) e.getCause();
assertEquals(ex.getResponse().getStatusCode(), 412);
} else {
throw e;
}
}
}
@Test
void testGetIfMatch() throws InterruptedException, ExecutionException,
TimeoutException, IOException {
String key = "apples";
addObjectAndValidateContent(bucketName, key);
client.getObject(bucketName, key, ifMd5Matches(goodMd5)).get(10,
TimeUnit.SECONDS);
validateContent(bucketName, key);
try {
client.getObject(bucketName, key, ifMd5Matches(badMd5)).get(10,
TimeUnit.SECONDS);
validateContent(bucketName, key);
} catch (ExecutionException e) {
if (e.getCause() instanceof HttpResponseException) {
HttpResponseException ex = (HttpResponseException) e.getCause();
assertEquals(ex.getResponse().getStatusCode(), 412);
} else {
throw e;
}
}
}
@Test
void testGetIfNoneMatch() throws InterruptedException, ExecutionException,
TimeoutException, IOException {
String key = "apples";
addObjectAndValidateContent(bucketName, key);
client.getObject(bucketName, key, ifMd5DoesntMatch(badMd5)).get(10,
TimeUnit.SECONDS);
validateContent(bucketName, key);
try {
client.getObject(bucketName, key, ifMd5DoesntMatch(goodMd5)).get(10,
TimeUnit.SECONDS);
validateContent(bucketName, key);
} catch (ExecutionException e) {
if (e.getCause() instanceof HttpResponseException) {
HttpResponseException ex = (HttpResponseException) e.getCause();
assertEquals(ex.getResponse().getStatusCode(), 304);
} else {
throw e;
}
}
}
@Test
void testGetRange() throws InterruptedException, ExecutionException,
TimeoutException, IOException {
String bucket = bucketPrefix + "testGetRange".toLowerCase();
String key = "apples";
TimeoutException, IOException {
setUpBucket(bucket, key);
S3Object object1 = client.getObject(bucket, key, range(0, 5)).get(10,
TimeUnit.SECONDS);
assertEquals(S3Utils.getContentAsStringAndClose(object1), TEST_STRING
.substring(0, 6));
String key = "apples";
S3Object object2 = client.getObject(bucket, key,
range(5, TEST_STRING.length())).get(10, TimeUnit.SECONDS);
assertEquals(S3Utils.getContentAsStringAndClose(object2), TEST_STRING
.substring(5, TEST_STRING.length()));
addObjectAndValidateContent(bucketName, key);
S3Object object1 = client.getObject(bucketName, key, range(0, 5)).get(10,
TimeUnit.SECONDS);
assertEquals(S3Utils.getContentAsStringAndClose(object1), TEST_STRING
.substring(0, 6));
S3Object object2 = client.getObject(bucketName, key,
range(6, TEST_STRING.length())).get(10, TimeUnit.SECONDS);
assertEquals(S3Utils.getContentAsStringAndClose(object2), TEST_STRING
.substring(6, TEST_STRING.length()));
}
@Test
void testGetTwoRanges() throws InterruptedException, ExecutionException,
TimeoutException, IOException {
String bucket = bucketPrefix + "testGetTwoRanges".toLowerCase();
String key = "apples";
TimeoutException, IOException {
setUpBucket(bucket, key);
S3Object object = client.getObject(bucket, key,
range(0, 5).range(5, TEST_STRING.length())).get(10,
TimeUnit.SECONDS);
String key = "apples";
assertEquals(S3Utils.getContentAsStringAndClose(object), TEST_STRING);
addObjectAndValidateContent(bucketName, key);
S3Object object = client.getObject(bucketName, key,
range(0, 5).range(6, TEST_STRING.length())).get(10,
TimeUnit.SECONDS);
assertEquals(S3Utils.getContentAsStringAndClose(object), TEST_STRING);
}
@Test
void testGetTail() throws InterruptedException, ExecutionException,
TimeoutException, IOException {
String bucket = bucketPrefix + "testGetTail".toLowerCase();
String key = "apples";
TimeoutException, IOException {
setUpBucket(bucket, key);
S3Object object = client.getObject(bucket, key, tail(5)).get(10,
TimeUnit.SECONDS);
assertEquals(S3Utils.getContentAsStringAndClose(object), TEST_STRING
.substring(TEST_STRING.length() - 5));
assertEquals(object.getContentLength(), 5);
assertEquals(object.getMetadata().getSize(), TEST_STRING.length());
String key = "apples";
addObjectAndValidateContent(bucketName, key);
S3Object object = client.getObject(bucketName, key, tail(5)).get(10,
TimeUnit.SECONDS);
assertEquals(S3Utils.getContentAsStringAndClose(object), TEST_STRING
.substring(TEST_STRING.length() - 5));
assertEquals(object.getContentLength(), 5);
assertEquals(object.getMetadata().getSize(), TEST_STRING.length());
}
@Test
void testGetStartAt() throws InterruptedException, ExecutionException,
TimeoutException, IOException {
String bucket = bucketPrefix + "testGetStartAt".toLowerCase();
String key = "apples";
TimeoutException, IOException {
setUpBucket(bucket, key);
S3Object object = client.getObject(bucket, key, startAt(5)).get(10,
TimeUnit.SECONDS);
assertEquals(S3Utils.getContentAsStringAndClose(object), TEST_STRING
.substring(5, TEST_STRING.length()));
assertEquals(object.getContentLength(), TEST_STRING.length() - 5);
assertEquals(object.getMetadata().getSize(), TEST_STRING.length());
String key = "apples";
addObjectAndValidateContent(bucketName, key);
S3Object object = client.getObject(bucketName, key, startAt(5)).get(10,
TimeUnit.SECONDS);
assertEquals(S3Utils.getContentAsStringAndClose(object), TEST_STRING
.substring(5, TEST_STRING.length()));
assertEquals(object.getContentLength(), TEST_STRING.length() - 5);
assertEquals(object.getMetadata().getSize(), TEST_STRING.length());
}
private void setUpBucket(String sourceBucket, String sourceKey)
throws InterruptedException, ExecutionException, TimeoutException,
IOException {
createBucketAndEnsureEmpty(sourceBucket);
addObjectToBucket(sourceBucket, sourceKey);
validateContent(sourceBucket, sourceKey);
private void addObjectAndValidateContent(String sourcebucketName, String sourceKey)
throws InterruptedException, ExecutionException, TimeoutException,
IOException {
addObjectToBucket(sourcebucketName, sourceKey);
validateContent(sourcebucketName, sourceKey);
}
}

View File

@ -23,116 +23,112 @@
*/
package org.jclouds.aws.s3.commands;
import static org.jclouds.aws.s3.commands.options.ListBucketOptions.Builder.delimiter;
import static org.jclouds.aws.s3.commands.options.ListBucketOptions.Builder.afterMarker;
import static org.jclouds.aws.s3.commands.options.ListBucketOptions.Builder.withPrefix;
import static org.jclouds.aws.s3.commands.options.ListBucketOptions.Builder.maxResults;
import org.jclouds.aws.s3.S3IntegrationTest;
import static org.jclouds.aws.s3.commands.options.ListBucketOptions.Builder.*;
import org.jclouds.aws.s3.domain.S3Bucket;
import org.jclouds.aws.s3.domain.S3Object;
import static org.testng.Assert.assertEquals;
import org.testng.annotations.Test;
import java.io.UnsupportedEncodingException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.jclouds.aws.s3.S3IntegrationTest;
import org.jclouds.aws.s3.domain.S3Bucket;
import org.jclouds.aws.s3.domain.S3Object;
import org.testng.annotations.Test;
/**
* Tests integrated functionality of all getBucket commands.
* <p/>
* Each test uses a different bucket name, so it should be perfectly fine to run
* in parallel.
*
*
* @author Adrian Cole
*
*/
@Test(groups = "integration", testName = "s3.ListBucketIntegrationTest")
@Test(groups = {"integration", "live"}, testName = "s3.ListBucketIntegrationTest")
public class ListBucketIntegrationTest extends S3IntegrationTest {
@Test()
void testListBucketDelimiter() throws InterruptedException,
ExecutionException, TimeoutException, UnsupportedEncodingException {
String bucketName = bucketPrefix + "delimiter";
assert client.putBucketIfNotExists(bucketName).get(10,
TimeUnit.SECONDS);
String prefix = "apps";
addTenObjectsUnderPrefix(bucketName, prefix);
add15UnderRoot(bucketName);
S3Bucket bucket = client.listBucket(bucketName, delimiter("/")).get(10,
TimeUnit.SECONDS);
assertEquals(bucket.getDelimiter(), "/");
assertEquals(bucket.getContents().size(), 15);
assertEquals(bucket.getCommonPrefixes().size(), 1);
ExecutionException, TimeoutException, UnsupportedEncodingException {
String prefix = "apps";
addTenObjectsUnderPrefix(bucketName, prefix);
add15UnderRoot(bucketName);
S3Bucket bucket = client.listBucket(bucketName, delimiter("/")).get(10,
TimeUnit.SECONDS);
assertEquals(bucket.getDelimiter(), "/");
assert !bucket.isTruncated();
assertEquals(bucket.getContents().size(), 15);
assertEquals(bucket.getCommonPrefixes().size(), 1);
}
private void addAlphabetUnderRoot(String bucketName)
throws InterruptedException, ExecutionException, TimeoutException {
for (char letter = 'a'; letter <= 'z'; letter++) {
client.putObject(bucketName,
new S3Object(letter + "", letter + "content")).get(10,
TimeUnit.SECONDS);
}
throws InterruptedException, ExecutionException, TimeoutException {
for (char letter = 'a'; letter <= 'z'; letter++) {
client.putObject(bucketName,
new S3Object(letter + "", letter + "content")).get(10,
TimeUnit.SECONDS);
}
}
@Test
void testListBucketMarker() throws InterruptedException,
ExecutionException, TimeoutException, UnsupportedEncodingException {
String bucketName = bucketPrefix + "marker";
assert client.putBucketIfNotExists(bucketName).get(10,
TimeUnit.SECONDS);
addAlphabetUnderRoot(bucketName);
S3Bucket bucket = client.listBucket(bucketName, afterMarker("y")).get(
10, TimeUnit.SECONDS);
assertEquals(bucket.getMarker(), "y");
assertEquals(bucket.getContents().size(), 1);
ExecutionException, TimeoutException, UnsupportedEncodingException {
addAlphabetUnderRoot(bucketName);
S3Bucket bucket = client.listBucket(bucketName, afterMarker("y")).get(
10, TimeUnit.SECONDS);
assertEquals(bucket.getMarker(), "y");
assert !bucket.isTruncated();
assertEquals(bucket.getContents().size(), 1);
}
@Test
void testListBucketMaxResults() throws InterruptedException,
ExecutionException, TimeoutException, UnsupportedEncodingException {
String bucketName = bucketPrefix + "max";
assert client.putBucketIfNotExists(bucketName).get(10,
TimeUnit.SECONDS);
addAlphabetUnderRoot(bucketName);
S3Bucket bucket = client.listBucket(bucketName, maxResults(5)).get(10,
TimeUnit.SECONDS);
assertEquals(bucket.getMaxKeys(), 5);
assertEquals(bucket.getContents().size(), 5);
ExecutionException, TimeoutException, UnsupportedEncodingException {
addAlphabetUnderRoot(bucketName);
S3Bucket bucket = client.listBucket(bucketName, maxResults(5)).get(10,
TimeUnit.SECONDS);
assertEquals(bucket.getMaxKeys(), 5);
assert bucket.isTruncated();
assertEquals(bucket.getContents().size(), 5);
}
@Test()
void testListBucketPrefix() throws InterruptedException,
ExecutionException, TimeoutException, UnsupportedEncodingException {
String bucketName = bucketPrefix + "prefix";
assert client.putBucketIfNotExists(bucketName).get(10,
TimeUnit.SECONDS);
String prefix = "apps";
addTenObjectsUnderPrefix(bucketName, prefix);
add15UnderRoot(bucketName);
ExecutionException, TimeoutException, UnsupportedEncodingException {
String prefix = "apps";
addTenObjectsUnderPrefix(bucketName, prefix);
add15UnderRoot(bucketName);
S3Bucket bucket = client.listBucket(bucketName, withPrefix("apps/"))
.get(10, TimeUnit.SECONDS);
assertEquals(bucket.getContents().size(), 10);
assertEquals(bucket.getPrefix(), "apps/");
S3Bucket bucket = client.listBucket(bucketName, withPrefix("apps/"))
.get(10, TimeUnit.SECONDS);
assert !bucket.isTruncated();
assertEquals(bucket.getContents().size(), 10);
assertEquals(bucket.getPrefix(), "apps/");
}
@Test()
void testListBucket() throws InterruptedException,
ExecutionException, TimeoutException, UnsupportedEncodingException {
String prefix = "apps";
addTenObjectsUnderPrefix(bucketName, prefix);
S3Bucket bucket = client.listBucket(bucketName)
.get(10, TimeUnit.SECONDS);
assertEquals(bucket.getContents().size(), 10);
}
private void add15UnderRoot(String bucketName) throws InterruptedException,
ExecutionException, TimeoutException {
for (int i = 0; i < 15; i++)
client.putObject(bucketName, new S3Object(i + "", i + "content"))
.get(10, TimeUnit.SECONDS);
ExecutionException, TimeoutException {
for (int i = 0; i < 15; i++)
client.putObject(bucketName, new S3Object(i + "", i + "content"))
.get(10, TimeUnit.SECONDS);
}
private void addTenObjectsUnderPrefix(String bucketName, String prefix)
throws InterruptedException, ExecutionException, TimeoutException {
for (int i = 0; i < 10; i++)
client.putObject(bucketName,
new S3Object(prefix + "/" + i, i + "content")).get(10,
TimeUnit.SECONDS);
throws InterruptedException, ExecutionException, TimeoutException {
for (int i = 0; i < 10; i++)
client.putObject(bucketName,
new S3Object(prefix + "/" + i, i + "content")).get(10,
TimeUnit.SECONDS);
}
}

View File

@ -23,44 +23,43 @@
*/
package org.jclouds.aws.s3.commands;
import java.util.List;
import java.util.concurrent.TimeUnit;
import org.jclouds.aws.s3.S3IntegrationTest;
import org.jclouds.aws.s3.domain.S3Bucket;
import org.testng.annotations.Test;
import java.util.List;
import java.util.concurrent.TimeUnit;
/**
* Tests integrated functionality of all listOwnedBucket commands.
* <p/>
* Each test uses a different bucket name, so it should be perfectly fine to run
* in parallel.
*
*
* @author Adrian Cole
*
*/
@Test(groups = "integration", testName = "s3.ListOwnedBucketsIntegrationTest")
@Test(groups = {"integration", "live"}, testName = "s3.ListOwnedBucketsIntegrationTest")
public class ListOwnedBucketsIntegrationTest extends S3IntegrationTest {
@Test()
void bucketDoesntExist() throws Exception {
String bucketName = bucketPrefix + "shouldntexist";
List<S3Bucket.Metadata> list = client.listOwnedBuckets().get(10,
TimeUnit.SECONDS);
assert !list.contains(new S3Bucket(bucketName));
String bucketName = bucketPrefix + "shouldntexist";
List<S3Bucket.Metadata> list = client.listOwnedBuckets().get(10,
TimeUnit.SECONDS);
assert !list.contains(new S3Bucket(bucketName));
}
@Test()
void bucketExists() throws Exception {
String bucketName = bucketPrefix + "needstoexist";
assert client.putBucketIfNotExists(bucketName)
.get(10, TimeUnit.SECONDS);
List<S3Bucket.Metadata> list = client.listOwnedBuckets().get(10,
TimeUnit.SECONDS);
S3Bucket.Metadata firstBucket = list.get(0);
S3Bucket.Metadata toMatch = new S3Bucket.Metadata(bucketName);
toMatch.setOwner(firstBucket.getOwner());
String bucketName = bucketPrefix + "needstoexist";
assert client.putBucketIfNotExists(bucketName)
.get(10, TimeUnit.SECONDS);
List<S3Bucket.Metadata> list = client.listOwnedBuckets().get(10,
TimeUnit.SECONDS);
S3Bucket.Metadata firstBucket = list.get(0);
S3Bucket.Metadata toMatch = new S3Bucket.Metadata(bucketName);
toMatch.setOwner(firstBucket.getOwner());
assert list.contains(toMatch);
assert list.contains(toMatch);
}
}

View File

@ -23,64 +23,65 @@
*/
package org.jclouds.aws.s3.commands;
import org.jclouds.aws.s3.S3IntegrationTest;
import static org.jclouds.aws.s3.commands.options.PutBucketOptions.Builder.createIn;
import static org.jclouds.aws.s3.commands.options.PutBucketOptions.Builder.withBucketAcl;
import java.io.IOException;
import java.net.URL;
import java.util.concurrent.TimeUnit;
import org.jclouds.aws.s3.S3IntegrationTest;
import org.jclouds.aws.s3.domain.S3Bucket.Metadata.LocationConstraint;
import org.jclouds.aws.s3.domain.acl.CannedAccessPolicy;
import org.jclouds.aws.s3.util.S3Utils;
import org.testng.annotations.Test;
import java.io.IOException;
import java.net.URL;
import java.util.concurrent.TimeUnit;
/**
* Tests integrated functionality of all PutBucket commands.
* <p/>
* Each test uses a different bucket name, so it should be perfectly fine to run
* in parallel.
*
*
* @author Adrian Cole
*
*/
@Test(groups = "integration", testName = "s3.PutBucketIntegrationTest")
public class PutBucketIntegrationTest extends S3IntegrationTest {
@Test(testName = "s3.PutBucketLiveTest")
public class PutBucketLiveTest extends S3IntegrationTest {
@Test()
/**
* overriding bucketName as we are changing access permissions
*/
@Test(groups = {"live"})
void testPublicReadAccessPolicy() throws Exception {
String bucketName = bucketPrefix + "public";
String bucketName = bucketPrefix + "public";
client.putBucketIfNotExists(bucketName,
withBucketAcl(CannedAccessPolicy.PUBLIC_READ)).get(10,
TimeUnit.SECONDS);
URL url = new URL(String.format("http://%1$s.s3.amazonaws.com",
bucketName));
S3Utils.toStringAndClose(url.openStream());
client.putBucketIfNotExists(bucketName,
withBucketAcl(CannedAccessPolicy.PUBLIC_READ)).get(10,
TimeUnit.SECONDS);
URL url = new URL(String.format("http://%1$s.s3.amazonaws.com",
bucketName));
S3Utils.toStringAndClose(url.openStream());
}
@Test(expectedExceptions = IOException.class)
@Test(expectedExceptions = IOException.class, groups = {"live"})
void testDefaultAccessPolicy() throws Exception {
String bucketName = bucketPrefix + "private";
client.putBucketIfNotExists(bucketName).get(10, TimeUnit.SECONDS);
URL url = new URL(String.format("http://%1$s.s3.amazonaws.com",
bucketName));
S3Utils.toStringAndClose(url.openStream());
URL url = new URL(String.format("http://%1$s.s3.amazonaws.com",
bucketName));
S3Utils.toStringAndClose(url.openStream());
}
@Test()
/**
* overriding bucketName as we are changing location
*/
@Test(groups = "live")
void testEu() throws Exception {
String bucketName = (bucketPrefix + "wow").toLowerCase();
client.putBucketIfNotExists(
bucketName,
createIn(LocationConstraint.EU).withBucketAcl(
CannedAccessPolicy.PUBLIC_READ)).get(10,
TimeUnit.SECONDS);
String bucketName = (bucketPrefix + "wow").toLowerCase();
client.putBucketIfNotExists(
bucketName,
createIn(LocationConstraint.EU).withBucketAcl(
CannedAccessPolicy.PUBLIC_READ)).get(10,
TimeUnit.SECONDS);
URL url = new URL(String.format("http://%1$s.s3.amazonaws.com",
bucketName));
S3Utils.toStringAndClose(url.openStream());
URL url = new URL(String.format("http://%1$s.s3.amazonaws.com",
bucketName));
S3Utils.toStringAndClose(url.openStream());
}
}

View File

@ -23,9 +23,18 @@
*/
package org.jclouds.aws.s3.commands;
import org.apache.commons.io.IOUtils;
import org.jclouds.aws.s3.S3IntegrationTest;
import static org.jclouds.aws.s3.commands.options.PutBucketOptions.Builder.withBucketAcl;
import static org.jclouds.aws.s3.commands.options.PutObjectOptions.Builder.withAcl;
import org.jclouds.aws.s3.domain.S3Object;
import org.jclouds.aws.s3.domain.acl.CannedAccessPolicy;
import org.jclouds.aws.s3.reference.S3Headers;
import org.jclouds.aws.s3.util.S3Utils;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import java.io.File;
import java.io.FileInputStream;
@ -34,115 +43,85 @@ import java.io.InputStream;
import java.net.URL;
import java.util.concurrent.TimeUnit;
import org.apache.commons.io.IOUtils;
import org.jclouds.aws.s3.S3IntegrationTest;
import static org.jclouds.aws.s3.commands.options.PutObjectOptions.Builder.*;
import org.jclouds.aws.s3.domain.S3Object;
import org.jclouds.aws.s3.domain.acl.CannedAccessPolicy;
import org.jclouds.aws.s3.reference.S3Headers;
import org.jclouds.aws.s3.util.S3Utils;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
/**
* Tests integrated functionality of all PutObject commands.
* <p/>
* Each test uses a different bucket name, so it should be perfectly fine to run
* in parallel.
*
*
* @author Adrian Cole
*
*/
@Test(groups = "integration", testName = "s3.PutObjectIntegrationTest")
@Test(testName = "s3.PutObjectIntegrationTest")
public class PutObjectIntegrationTest extends S3IntegrationTest {
@DataProvider(name = "putTests")
public Object[][] createData1() throws IOException {
String realObject = IOUtils.toString(new FileInputStream("pom.xml"));
String realObject = IOUtils.toString(new FileInputStream("pom.xml"));
return new Object[][] {
{ "file", "text/xml", new File("pom.xml"), realObject },
{ "string", "text/xml", realObject, realObject },
{ "bytes", "application/octet-stream", realObject.getBytes(),
realObject } };
return new Object[][]{
{"file", "text/xml", new File("pom.xml"), realObject},
{"string", "text/xml", realObject, realObject},
{"bytes", "application/octet-stream", realObject.getBytes(),
realObject}};
}
@Test(dataProvider = "putTests")
@Test(dataProvider = "putTests", groups = {"integration", "live"})
void testPutObject(String key, String type, Object content,
Object realObject) throws Exception {
String bucketName = bucketPrefix + "tpo";
client.putBucketIfNotExists(bucketName).get(10, TimeUnit.SECONDS);
context.createS3ObjectMap(bucketName).clear();
assertEquals(client.listBucket(bucketName).get(10, TimeUnit.SECONDS)
.getContents().size(), 0);
S3Object object = new S3Object(key);
object.getMetadata().setContentType(type);
object.setData(content);
if (content instanceof InputStream) {
object.generateMd5();
}
assertNotNull(client.putObject(bucketName, object).get(10,
TimeUnit.SECONDS));
object = client.getObject(bucketName, object.getKey()).get(10,
TimeUnit.SECONDS);
String returnedString = S3Utils.getContentAsStringAndClose(object);
assertEquals(returnedString, realObject);
assertEquals(client.listBucket(bucketName).get(10, TimeUnit.SECONDS)
.getContents().size(), 1);
Object realObject) throws Exception {
String bucketName = bucketPrefix + "tpo";
client.putBucketIfNotExists(bucketName).get(10, TimeUnit.SECONDS);
context.createS3ObjectMap(bucketName).clear();
assertEquals(client.listBucket(bucketName).get(10, TimeUnit.SECONDS)
.getContents().size(), 0);
S3Object object = new S3Object(key);
object.getMetadata().setContentType(type);
object.setData(content);
if (content instanceof InputStream) {
object.generateMd5();
}
assertNotNull(client.putObject(bucketName, object).get(10,
TimeUnit.SECONDS));
object = client.getObject(bucketName, object.getKey()).get(10,
TimeUnit.SECONDS);
String returnedString = S3Utils.getContentAsStringAndClose(object);
assertEquals(returnedString, realObject);
assertEquals(client.listBucket(bucketName).get(10, TimeUnit.SECONDS)
.getContents().size(), 1);
}
@Test
@Test(groups = {"integration", "live"})
void testMetadata() throws Exception {
String bucketName = bucketPrefix + "tmd";
createBucketAndEnsureEmpty(bucketName);
String key = "hello";
String bucketName = bucketPrefix + "tmd";
createBucketAndEnsureEmpty(bucketName);
String key = "hello";
S3Object object = new S3Object(key, TEST_STRING);
object.getMetadata().setCacheControl("no-cache");
object.getMetadata().setContentType("text/plain");
object.getMetadata().setContentEncoding("x-compress");
object.getMetadata().setSize(TEST_STRING.length());
object.getMetadata().setContentDisposition(
"attachment; filename=hello.txt");
object.getMetadata().getUserMetadata().put(
S3Headers.USER_METADATA_PREFIX + "adrian", "powderpuff");
object.getMetadata().setMd5(S3Utils.md5(TEST_STRING.getBytes()));
S3Object object = new S3Object(key, TEST_STRING);
object.getMetadata().setCacheControl("no-cache");
object.getMetadata().setContentType("text/plain");
object.getMetadata().setContentEncoding("x-compress");
object.getMetadata().setSize(TEST_STRING.length());
object.getMetadata().setContentDisposition(
"attachment; filename=hello.txt");
object.getMetadata().getUserMetadata().put(
S3Headers.USER_METADATA_PREFIX + "adrian", "powderpuff");
object.getMetadata().setMd5(S3Utils.md5(TEST_STRING.getBytes()));
addObjectToBucket(bucketName, object);
S3Object newObject = validateContent(bucketName, key);
// TODO.. why does this come back as binary/octetstring
assertEquals(newObject.getMetadata().getContentType(),
"binary/octet-stream");
assertEquals(newObject.getMetadata().getContentEncoding(), "x-compress");
assertEquals(newObject.getMetadata().getContentDisposition(),
"attachment; filename=hello.txt");
assertEquals(newObject.getMetadata().getCacheControl(), "no-cache");
assertEquals(newObject.getMetadata().getSize(), TEST_STRING.length());
assertEquals(newObject.getMetadata().getUserMetadata().values()
.iterator().next(), "powderpuff");
assertEquals(newObject.getMetadata().getMd5(), S3Utils.md5(TEST_STRING
.getBytes()));
}
@Test()
void testCannedAccessPolicyPublic() throws Exception {
String bucketName = bucketPrefix + "tcapp";
createBucketAndEnsureEmpty(bucketName);
String key = "hello";
client.putBucketIfNotExists(bucketName,
withBucketAcl(CannedAccessPolicy.PUBLIC_READ)).get(10,
TimeUnit.SECONDS);
client.putObject(bucketName, new S3Object(key, TEST_STRING),
withAcl(CannedAccessPolicy.PUBLIC_READ)).get(10, TimeUnit.SECONDS);
URL url = new URL(String.format("http://%1$s.s3.amazonaws.com/%2$s",
bucketName, key));
S3Utils.toStringAndClose(url.openStream());
addObjectToBucket(bucketName, object);
S3Object newObject = validateContent(bucketName, key);
// TODO.. why does this come back as binary/octetstring
assertEquals(newObject.getMetadata().getContentType(),
"binary/octet-stream");
assertEquals(newObject.getMetadata().getContentEncoding(), "x-compress");
assertEquals(newObject.getMetadata().getContentDisposition(),
"attachment; filename=hello.txt");
assertEquals(newObject.getMetadata().getCacheControl(), "no-cache");
assertEquals(newObject.getMetadata().getSize(), TEST_STRING.length());
assertEquals(newObject.getMetadata().getUserMetadata().values()
.iterator().next(), "powderpuff");
assertEquals(newObject.getMetadata().getMd5(), S3Utils.md5(TEST_STRING
.getBytes()));
}
}

View File

@ -0,0 +1,69 @@
/**
*
* Copyright (C) 2009 Adrian Cole <adrian@jclouds.org>
*
* ====================================================================
* 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.commands;
import org.jclouds.aws.s3.S3IntegrationTest;
import static org.jclouds.aws.s3.commands.options.PutBucketOptions.Builder.withBucketAcl;
import static org.jclouds.aws.s3.commands.options.PutObjectOptions.Builder.withAcl;
import org.jclouds.aws.s3.domain.S3Object;
import org.jclouds.aws.s3.domain.acl.CannedAccessPolicy;
import org.jclouds.aws.s3.util.S3Utils;
import org.testng.annotations.Test;
import java.net.URL;
import java.util.concurrent.TimeUnit;
/**
* Tests integrated functionality of all PutObject commands.
* <p/>
* Each test uses a different bucket name, so it should be perfectly fine to run
* in parallel.
*
* @author Adrian Cole
*/
@Test(testName = "s3.PutObjectLiveTest")
public class PutObjectLiveTest extends S3IntegrationTest {
@Test(groups = {"live"})
void testCannedAccessPolicyPublic() throws Exception {
String bucketName = bucketPrefix + "tcapp";
createBucketAndEnsureEmpty(bucketName);
String key = "hello";
client.putBucketIfNotExists(bucketName,
withBucketAcl(CannedAccessPolicy.PUBLIC_READ)).get(10,
TimeUnit.SECONDS);
client.putObject(bucketName, new S3Object(key, TEST_STRING),
withAcl(CannedAccessPolicy.PUBLIC_READ)).get(10, TimeUnit.SECONDS);
URL url = new URL(String.format("http://%1$s.s3.amazonaws.com/%2$s",
bucketName, key));
S3Utils.toStringAndClose(url.openStream());
}
}

View File

@ -23,140 +23,131 @@
*/
package org.jclouds.aws.s3.commands;
import static org.easymock.EasyMock.expect;
import static org.easymock.classextension.EasyMock.createMock;
import static org.easymock.classextension.EasyMock.replay;
import org.jclouds.aws.s3.commands.config.S3CommandsModule;
import org.jclouds.aws.s3.commands.options.CopyObjectOptions;
import org.jclouds.aws.s3.commands.options.GetObjectOptions;
import org.jclouds.aws.s3.commands.options.ListBucketOptions;
import org.jclouds.aws.s3.commands.options.PutBucketOptions;
import org.jclouds.aws.s3.commands.options.PutObjectOptions;
import org.jclouds.aws.s3.domain.S3Object;
import org.jclouds.aws.s3.domain.S3Bucket.Metadata.LocationConstraint;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.name.Names;
import static org.easymock.EasyMock.expect;
import static org.easymock.classextension.EasyMock.createMock;
import static org.easymock.classextension.EasyMock.replay;
import org.jclouds.aws.s3.commands.config.S3CommandsModule;
import org.jclouds.aws.s3.commands.options.*;
import org.jclouds.aws.s3.domain.S3Bucket.Metadata.LocationConstraint;
import org.jclouds.aws.s3.domain.S3Object;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
/**
*
* @author Adrian Cole
*/
@Test
@Test(groups = {"unit"}, testName = "s3.S3CommandFactoryTest")
public class S3CommandFactoryTest {
Injector injector = null;
S3CommandFactory commandFactory = null;
public static final String listAllMyBucketsResult = "<ListAllMyBucketsResult xmlns=\"http://s3.amazonaws.com/doc/callables/\"><Owner ><ID>e1a5f66a480ca99a4fdfe8e318c3020446c9989d7004e7778029fbcc5d990fa0</ID></Owner><Buckets><Bucket><Name>adrianjbosstest</Name><CreationDate>2009-03-12T02:00:07.000Z</CreationDate></Bucket><Bucket><Name>adrianjbosstest2</Name><CreationDate>2009-03-12T02:00:09.000Z</CreationDate></Bucket></Buckets></ListAllMyBucketsResult>";
@BeforeMethod
void setUpInjector() {
injector = Guice.createInjector(new S3CommandsModule() {
@Override
protected void configure() {
bindConstant().annotatedWith(
Names.named("jclouds.http.address")).to("localhost");
super.configure();
}
});
commandFactory = injector.getInstance(S3CommandFactory.class);
injector = Guice.createInjector(new S3CommandsModule() {
@Override
protected void configure() {
bindConstant().annotatedWith(
Names.named("jclouds.http.address")).to("localhost");
super.configure();
}
});
commandFactory = injector.getInstance(S3CommandFactory.class);
}
@AfterMethod
void tearDownInjector() {
commandFactory = null;
injector = null;
commandFactory = null;
injector = null;
}
@Test
void testCreateCopyObject() {
assert commandFactory.createCopyObject("sourcebucket", "sourceObject",
"destbucket", "destObject", CopyObjectOptions.NONE) != null;
assert commandFactory.createCopyObject("sourcebucket", "sourceObject",
"destbucket", "destObject", CopyObjectOptions.NONE) != null;
}
@Test
void testCreateCopyObjectOptions() {
assert commandFactory.createCopyObject("sourcebucket", "sourceObject",
"destbucket", "destObject", new CopyObjectOptions()) != null;
assert commandFactory.createCopyObject("sourcebucket", "sourceObject",
"destbucket", "destObject", new CopyObjectOptions()) != null;
}
@Test
void testCreateDeleteBucket() {
assert commandFactory.createDeleteBucket("test") != null;
assert commandFactory.createDeleteBucket("test") != null;
}
@Test
void testCreateDeleteObject() {
assert commandFactory.createDeleteObject("test", "blah") != null;
assert commandFactory.createDeleteObject("test", "blah") != null;
}
@Test
void testCreateHeadBucket() {
assert commandFactory.createHeadBucket("test") != null;
assert commandFactory.createHeadBucket("test") != null;
}
@Test
void testCreatePutBucket() {
assert commandFactory.createPutBucket("test", PutBucketOptions.NONE) != null;
assert commandFactory.createPutBucket("test", PutBucketOptions.NONE) != null;
}
@Test
void testCreatePutBucketOptions() {
assert commandFactory.createPutBucket("test", PutBucketOptions.Builder
.createIn(LocationConstraint.EU)) != null;
assert commandFactory.createPutBucket("test", PutBucketOptions.Builder
.createIn(LocationConstraint.EU)) != null;
}
@Test
void testCreatePutObject() {
S3Object.Metadata metadata = createMock(S3Object.Metadata.class);
S3Object object = new S3Object(metadata);
expect(metadata.getSize()).andReturn(4L).atLeastOnce();
expect(metadata.getKey()).andReturn("rawr");
expect(metadata.getContentType()).andReturn("text/xml").atLeastOnce();
expect(metadata.getCacheControl()).andReturn("no-cache").atLeastOnce();
expect(metadata.getContentDisposition()).andReturn("disposition")
.atLeastOnce();
expect(metadata.getContentEncoding()).andReturn("encoding")
.atLeastOnce();
expect(metadata.getMd5()).andReturn("encoding".getBytes())
.atLeastOnce();
Multimap<String, String> userMdata = HashMultimap.create();
expect(metadata.getUserMetadata()).andReturn(userMdata).atLeastOnce();
S3Object.Metadata metadata = createMock(S3Object.Metadata.class);
S3Object object = new S3Object(metadata);
expect(metadata.getSize()).andReturn(4L).atLeastOnce();
expect(metadata.getKey()).andReturn("rawr");
expect(metadata.getContentType()).andReturn("text/xml").atLeastOnce();
expect(metadata.getCacheControl()).andReturn("no-cache").atLeastOnce();
expect(metadata.getContentDisposition()).andReturn("disposition")
.atLeastOnce();
expect(metadata.getContentEncoding()).andReturn("encoding")
.atLeastOnce();
expect(metadata.getMd5()).andReturn("encoding".getBytes())
.atLeastOnce();
Multimap<String, String> userMdata = HashMultimap.create();
expect(metadata.getUserMetadata()).andReturn(userMdata).atLeastOnce();
replay(metadata);
object.setData("<a></a>");
replay(metadata);
object.setData("<a></a>");
assert commandFactory.createPutObject("test", object,
PutObjectOptions.NONE) != null;
assert commandFactory.createPutObject("test", object,
PutObjectOptions.NONE) != null;
}
@Test
void testCreateGetObject() {
assert commandFactory.createGetObject("test", "blah",
GetObjectOptions.NONE) != null;
assert commandFactory.createGetObject("test", "blah",
GetObjectOptions.NONE) != null;
}
@Test
void testCreateHeadMetadata() {
assert commandFactory.createHeadMetadata("test", "blah") != null;
assert commandFactory.createHeadMetadata("test", "blah") != null;
}
@Test
void testCreateListAllMyBuckets() {
assert commandFactory.createGetMetadataForOwnedBuckets() != null;
assert commandFactory.createGetMetadataForOwnedBuckets() != null;
}
@Test
void testCreateListBucket() {
assert commandFactory.createListBucket("test", ListBucketOptions.NONE) != null;
assert commandFactory.createListBucket("test", ListBucketOptions.NONE) != null;
}
}

View File

@ -23,16 +23,8 @@
*/
package org.jclouds.aws.s3.commands;
import static org.testng.Assert.assertEquals;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.CompletionService;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorCompletionService;
import com.google.inject.Guice;
import com.google.inject.Injector;
import org.apache.commons.io.IOUtils;
import org.jclouds.aws.PerformanceTest;
import org.jclouds.aws.s3.domain.CanonicalUser;
@ -46,20 +38,26 @@ import org.jclouds.aws.s3.xml.config.S3ParserModule;
import org.jclouds.http.HttpException;
import org.jclouds.http.commands.callables.xml.ParseSax;
import org.joda.time.DateTime;
import static org.testng.Assert.assertEquals;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import org.xml.sax.SAXException;
import com.google.inject.Guice;
import com.google.inject.Injector;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.CompletionService;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorCompletionService;
/**
* Tests parsing of S3 responses
*
*
* @author Adrian Cole
*/
@Test(groups = "unit", sequential = true, testName = "s3.S3ParserTest")
@Test(groups = {"performance"}, testName = "s3.S3ParserTest")
public class S3ParserTest extends PerformanceTest {
Injector injector = null;
@ -69,136 +67,136 @@ public class S3ParserTest extends PerformanceTest {
@BeforeMethod
protected void setUpInjector() {
injector = Guice.createInjector(new S3ParserModule());
parserFactory = injector.getInstance(S3ParserFactory.class);
assert parserFactory != null;
injector = Guice.createInjector(new S3ParserModule());
parserFactory = injector.getInstance(S3ParserFactory.class);
assert parserFactory != null;
}
@AfterMethod
protected void tearDownInjector() {
parserFactory = null;
injector = null;
parserFactory = null;
injector = null;
}
@Test
void testParseListAllMyBucketsSerialResponseTime() throws HttpException {
for (int i = 0; i < LOOP_COUNT; i++)
runParseListAllMyBuckets();
for (int i = 0; i < LOOP_COUNT; i++)
runParseListAllMyBuckets();
}
private List<S3Bucket.Metadata> runParseListAllMyBuckets()
throws HttpException {
return parserFactory.createListBucketsParser().parse(
IOUtils.toInputStream(listAllMyBucketsResultOn200));
throws HttpException {
return parserFactory.createListBucketsParser().parse(
IOUtils.toInputStream(listAllMyBucketsResultOn200));
}
@Test
void testParseListAllMyBucketsParallelResponseTime()
throws InterruptedException, ExecutionException {
CompletionService<List<S3Bucket.Metadata>> completer = new ExecutorCompletionService<List<S3Bucket.Metadata>>(
exec);
for (int i = 0; i < LOOP_COUNT; i++)
completer.submit(new Callable<List<S3Bucket.Metadata>>() {
public List<S3Bucket.Metadata> call() throws IOException,
SAXException, HttpException {
return runParseListAllMyBuckets();
}
});
for (int i = 0; i < LOOP_COUNT; i++)
assert completer.take().get() != null;
throws InterruptedException, ExecutionException {
CompletionService<List<S3Bucket.Metadata>> completer = new ExecutorCompletionService<List<S3Bucket.Metadata>>(
exec);
for (int i = 0; i < LOOP_COUNT; i++)
completer.submit(new Callable<List<S3Bucket.Metadata>>() {
public List<S3Bucket.Metadata> call() throws IOException,
SAXException, HttpException {
return runParseListAllMyBuckets();
}
});
for (int i = 0; i < LOOP_COUNT; i++)
assert completer.take().get() != null;
}
@Test
public void testCanParseListAllMyBuckets() throws HttpException {
List<S3Bucket.Metadata> s3Buckets = runParseListAllMyBuckets();
S3Bucket.Metadata bucket1 = s3Buckets.get(0);
assert bucket1.getName().equals("adrianjbosstest");
DateTime expectedDate1 = new DateTime("2009-03-12T02:00:07.000Z");
DateTime date1 = bucket1.getCreationDate();
assert date1.equals(expectedDate1);
S3Bucket.Metadata bucket2 = s3Buckets.get(1);
assert bucket2.getName().equals("adrianjbosstest2");
DateTime expectedDate2 = new DateTime("2009-03-12T02:00:09.000Z");
DateTime date2 = bucket2.getCreationDate();
assert date2.equals(expectedDate2);
assert s3Buckets.size() == 2;
CanonicalUser owner = new CanonicalUser(
"e1a5f66a480ca99a4fdfe8e318c3020446c9989d7004e7778029fbcc5d990fa0");
assert bucket1.getOwner().equals(owner);
assert bucket2.getOwner().equals(owner);
List<S3Bucket.Metadata> s3Buckets = runParseListAllMyBuckets();
S3Bucket.Metadata bucket1 = s3Buckets.get(0);
assert bucket1.getName().equals("adrianjbosstest");
DateTime expectedDate1 = new DateTime("2009-03-12T02:00:07.000Z");
DateTime date1 = bucket1.getCreationDate();
assert date1.equals(expectedDate1);
S3Bucket.Metadata bucket2 = s3Buckets.get(1);
assert bucket2.getName().equals("adrianjbosstest2");
DateTime expectedDate2 = new DateTime("2009-03-12T02:00:09.000Z");
DateTime date2 = bucket2.getCreationDate();
assert date2.equals(expectedDate2);
assert s3Buckets.size() == 2;
CanonicalUser owner = new CanonicalUser(
"e1a5f66a480ca99a4fdfe8e318c3020446c9989d7004e7778029fbcc5d990fa0");
assert bucket1.getOwner().equals(owner);
assert bucket2.getOwner().equals(owner);
}
public static final String listBucketResult = "<ListBucketHandler xmlns=\"http://s3.amazonaws.com/doc/2006-03-01/\"><Name>adrianjbosstest</Name><Prefix></Prefix><Marker></Marker><MaxKeys>1000</MaxKeys><IsTruncated>false</IsTruncated><Contents><Key>3366</Key><LastModified>2009-03-12T02:00:13.000Z</LastModified><ETag>&quot;9d7bb64e8e18ee34eec06dd2cf37b766&quot;</ETag><Size>136</Size><Owner><ID>e1a5f66a480ca99a4fdfe8e318c3020446c9989d7004e7778029fbcc5d990fa0</ID><DisplayName>ferncam</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents></ListBucketHandler>";
public void testCanParseListBucketResult() throws HttpException,
UnsupportedEncodingException {
S3Bucket bucket = runParseListBucketResult();
assert bucket.isComplete();
assert bucket.getName().equals("adrianjbosstest");
assert bucket.getContents().size() == 1;
S3Object.Metadata object = bucket.getContents().iterator().next();
assert object.getKey().equals("3366");
DateTime expected = new DateTime("2009-03-12T02:00:13.000Z");
assert object.getLastModified().equals(expected) : String.format(
"expected %1$s, but got %1$s", expected, object
.getLastModified());
assertEquals(S3Utils.toHexString(object.getMd5()),
"9d7bb64e8e18ee34eec06dd2cf37b766");
assert object.getSize() == 136;
CanonicalUser owner = new CanonicalUser(
"e1a5f66a480ca99a4fdfe8e318c3020446c9989d7004e7778029fbcc5d990fa0");
owner.setDisplayName("ferncam");
assert object.getOwner().equals(owner);
assert object.getStorageClass().equals("STANDARD");
UnsupportedEncodingException {
S3Bucket bucket = runParseListBucketResult();
assert !bucket.isTruncated();
assert bucket.getName().equals("adrianjbosstest");
assert bucket.getContents().size() == 1;
S3Object.Metadata object = bucket.getContents().iterator().next();
assert object.getKey().equals("3366");
DateTime expected = new DateTime("2009-03-12T02:00:13.000Z");
assert object.getLastModified().equals(expected) : String.format(
"expected %1$s, but got %1$s", expected, object
.getLastModified());
assertEquals(S3Utils.toHexString(object.getMd5()),
"9d7bb64e8e18ee34eec06dd2cf37b766");
assert object.getSize() == 136;
CanonicalUser owner = new CanonicalUser(
"e1a5f66a480ca99a4fdfe8e318c3020446c9989d7004e7778029fbcc5d990fa0");
owner.setDisplayName("ferncam");
assert object.getOwner().equals(owner);
assert object.getStorageClass().equals("STANDARD");
}
private S3Bucket runParseListBucketResult() throws HttpException {
ParseSax<S3Bucket> parser = parserFactory.createListBucketParser();
ListBucketHandler handler = (ListBucketHandler) parser.getHandler();
handler.setBucketName("adrianjbosstest");
return parser.parse(IOUtils.toInputStream(listBucketResult));
ParseSax<S3Bucket> parser = parserFactory.createListBucketParser();
ListBucketHandler handler = (ListBucketHandler) parser.getHandler();
handler.setBucketName("adrianjbosstest");
return parser.parse(IOUtils.toInputStream(listBucketResult));
}
public static final String successfulCopyObject200 = "<CopyObjectResult xmlns=\"http://s3.amazonaws.com/doc/2006-03-01/\"><LastModified>2009-03-19T13:23:27.000Z</LastModified><ETag>\"92836a3ea45a6984d1b4d23a747d46bb\"</ETag></CopyObjectResult>";
private S3Object.Metadata runParseCopyObjectResult() throws HttpException {
ParseSax<S3Object.Metadata> parser = parserFactory
.createCopyObjectParser();
CopyObjectHandler handler = (CopyObjectHandler) parser.getHandler();
handler.setKey("adrianjbosstest");
return parser.parse(IOUtils.toInputStream(successfulCopyObject200));
ParseSax<S3Object.Metadata> parser = parserFactory
.createCopyObjectParser();
CopyObjectHandler handler = (CopyObjectHandler) parser.getHandler();
handler.setKey("adrianjbosstest");
return parser.parse(IOUtils.toInputStream(successfulCopyObject200));
}
public void testCanParseCopyObjectResult() throws HttpException,
UnsupportedEncodingException {
S3Object.Metadata metadata = runParseCopyObjectResult();
DateTime expected = new DateTime("2009-03-19T13:23:27.000Z");
assertEquals(metadata.getLastModified(), expected);
assertEquals(S3Utils.toHexString(metadata.getMd5()),
"92836a3ea45a6984d1b4d23a747d46bb");
assertEquals(metadata.getKey(), "adrianjbosstest");
UnsupportedEncodingException {
S3Object.Metadata metadata = runParseCopyObjectResult();
DateTime expected = new DateTime("2009-03-19T13:23:27.000Z");
assertEquals(metadata.getLastModified(), expected);
assertEquals(S3Utils.toHexString(metadata.getMd5()),
"92836a3ea45a6984d1b4d23a747d46bb");
assertEquals(metadata.getKey(), "adrianjbosstest");
}
@Test
void testParseListBucketResultSerialResponseTime() throws HttpException {
for (int i = 0; i < LOOP_COUNT; i++)
runParseListBucketResult();
for (int i = 0; i < LOOP_COUNT; i++)
runParseListBucketResult();
}
@Test
void testParseListBucketResultParallelResponseTime()
throws InterruptedException, ExecutionException {
CompletionService<S3Bucket> completer = new ExecutorCompletionService<S3Bucket>(
exec);
for (int i = 0; i < LOOP_COUNT; i++)
completer.submit(new Callable<S3Bucket>() {
public S3Bucket call() throws IOException, SAXException,
HttpException {
return runParseListBucketResult();
}
});
for (int i = 0; i < LOOP_COUNT; i++)
assert completer.take().get() != null;
throws InterruptedException, ExecutionException {
CompletionService<S3Bucket> completer = new ExecutorCompletionService<S3Bucket>(
exec);
for (int i = 0; i < LOOP_COUNT; i++)
completer.submit(new Callable<S3Bucket>() {
public S3Bucket call() throws IOException, SAXException,
HttpException {
return runParseListBucketResult();
}
});
for (int i = 0; i < LOOP_COUNT; i++)
assert completer.take().get() != null;
}
}

View File

@ -23,77 +23,74 @@
*/
package org.jclouds.aws.s3.commands.callables;
import static org.testng.Assert.*;
import static org.easymock.classextension.EasyMock.*;
import org.apache.commons.io.IOUtils;
import static org.easymock.classextension.EasyMock.*;
import org.jclouds.aws.s3.domain.S3Object;
import org.jclouds.aws.s3.domain.S3Object.Metadata;
import org.jclouds.http.HttpException;
import org.jclouds.http.HttpHeaders;
import org.jclouds.http.HttpResponse;
import static org.testng.Assert.assertEquals;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
/**
*
* @author Adrian Cole
*
*/
@Test
@Test(groups = "unit", testName = "s3.ParseObjectFromHeadersAndHttpContentTest")
public class ParseObjectFromHeadersAndHttpContentTest {
ParseObjectFromHeadersAndHttpContent callable;
ParseMetadataFromHeaders metadataParser;
@BeforeMethod
void setUp() {
metadataParser = createMock(ParseMetadataFromHeaders.class);
callable = new ParseObjectFromHeadersAndHttpContent(metadataParser);
metadataParser = createMock(ParseMetadataFromHeaders.class);
callable = new ParseObjectFromHeadersAndHttpContent(metadataParser);
}
@AfterMethod
void tearDown() {
callable = null;
callable = null;
}
@Test(expectedExceptions = IllegalStateException.class)
public void testCall() throws HttpException {
HttpResponse response = createMock(HttpResponse.class);
expect(response.getStatusCode()).andReturn(409).atLeastOnce();
expect(response.getContent()).andReturn(null);
replay(response);
callable.setResponse(response);
callable.call();
HttpResponse response = createMock(HttpResponse.class);
expect(response.getStatusCode()).andReturn(409).atLeastOnce();
expect(response.getContent()).andReturn(null);
replay(response);
callable.setResponse(response);
callable.call();
}
@Test
public void testParseContentLengthWhenContentRangeSet()
throws HttpException {
HttpResponse response = createMock(HttpResponse.class);
metadataParser.setResponse(response);
Metadata meta = createMock(Metadata.class);
expect(metadataParser.call()).andReturn(meta);
expect(meta.getSize()).andReturn(-1l);
meta.setSize(-1l);
expect(response.getFirstHeaderOrNull(HttpHeaders.CONTENT_LENGTH))
.andReturn("10485760").atLeastOnce();
expect(response.getFirstHeaderOrNull(HttpHeaders.CONTENT_RANGE))
.andReturn("0-10485759/20232760").atLeastOnce();
meta.setSize(20232760l);
expect(meta.getSize()).andReturn(20232760l);
throws HttpException {
HttpResponse response = createMock(HttpResponse.class);
metadataParser.setResponse(response);
Metadata meta = createMock(Metadata.class);
expect(metadataParser.call()).andReturn(meta);
expect(meta.getSize()).andReturn(-1l);
meta.setSize(-1l);
expect(response.getFirstHeaderOrNull(HttpHeaders.CONTENT_LENGTH))
.andReturn("10485760").atLeastOnce();
expect(response.getFirstHeaderOrNull(HttpHeaders.CONTENT_RANGE))
.andReturn("0-10485759/20232760").atLeastOnce();
meta.setSize(20232760l);
expect(meta.getSize()).andReturn(20232760l);
expect(response.getStatusCode()).andReturn(200).atLeastOnce();
expect(response.getContent()).andReturn(IOUtils.toInputStream("test"));
replay(response);
replay(metadataParser);
replay(meta);
expect(response.getStatusCode()).andReturn(200).atLeastOnce();
expect(response.getContent()).andReturn(IOUtils.toInputStream("test"));
replay(response);
replay(metadataParser);
replay(meta);
callable.setResponse(response);
S3Object object = callable.call();
assertEquals(object.getContentLength(), 10485760);
assertEquals(object.getMetadata().getSize(), 20232760);
assertEquals(object.getContentRange(), "0-10485759/20232760");
callable.setResponse(response);
S3Object object = callable.call();
assertEquals(object.getContentLength(), 10485760);
assertEquals(object.getMetadata().getSize(), 20232760);
assertEquals(object.getContentRange(), "0-10485759/20232760");
}

View File

@ -23,34 +23,26 @@
*/
package org.jclouds.aws.s3.commands.options;
import static org.jclouds.aws.s3.commands.options.CopyObjectOptions.Builder.ifSourceMd5DoesntMatch;
import static org.jclouds.aws.s3.commands.options.CopyObjectOptions.Builder.ifSourceMd5Matches;
import static org.jclouds.aws.s3.commands.options.CopyObjectOptions.Builder.ifSourceModifiedSince;
import static org.jclouds.aws.s3.commands.options.CopyObjectOptions.Builder.ifSourceUnmodifiedSince;
import static org.jclouds.aws.s3.commands.options.CopyObjectOptions.Builder.overrideAcl;
import static org.jclouds.aws.s3.commands.options.CopyObjectOptions.Builder.overrideMetadataWith;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNull;
import static org.testng.Assert.assertTrue;
import java.io.UnsupportedEncodingException;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;
import static org.jclouds.aws.s3.commands.options.CopyObjectOptions.Builder.*;
import org.jclouds.aws.s3.domain.acl.CannedAccessPolicy;
import org.jclouds.aws.s3.reference.S3Headers;
import org.jclouds.aws.s3.util.DateService;
import org.jclouds.aws.s3.util.S3Utils;
import org.joda.time.DateTime;
import static org.testng.Assert.*;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;
import java.io.UnsupportedEncodingException;
/**
* Tests possible uses of CopyObjectOptions and CopyObjectOptions.Builder.*
*
*
* @author Adrian Cole
*/
@Test(groups = "unit", testName = "s3.CopyObjectOptionsTest")
public class CopyObjectOptionsTest {
private byte[] testBytes;
@ -61,279 +53,279 @@ public class CopyObjectOptionsTest {
@BeforeMethod
void setUp() {
goodMeta = HashMultimap.create();
goodMeta.put("x-amz-meta-adrian", "foo");
badMeta = HashMultimap.create();
badMeta.put("x-google-meta-adrian", "foo");
goodMeta = HashMultimap.create();
goodMeta.put("x-amz-meta-adrian", "foo");
badMeta = HashMultimap.create();
badMeta.put("x-google-meta-adrian", "foo");
now = new DateTime();
nowExpected = new DateService().toHeaderString(now);
testBytes = new byte[] { 0, 1, 2, 3, 4, 5, 6, 7 };
now = new DateTime();
nowExpected = new DateService().toHeaderString(now);
testBytes = new byte[]{0, 1, 2, 3, 4, 5, 6, 7};
}
@Test
void testGoodMetaStatic() {
CopyObjectOptions options = overrideMetadataWith(goodMeta);
assertGoodMeta(options);
CopyObjectOptions options = overrideMetadataWith(goodMeta);
assertGoodMeta(options);
}
@Test(expectedExceptions = NullPointerException.class)
public void testMetaNPE() {
overrideMetadataWith(null);
overrideMetadataWith(null);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void testBadMeta() {
overrideMetadataWith(badMeta);
overrideMetadataWith(badMeta);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void testBadMetaStatic() {
overrideMetadataWith(badMeta);
overrideMetadataWith(badMeta);
}
private void assertGoodMeta(CopyObjectOptions options) {
assert options != null;
assert options.getMetadata() != null;
Multimap<String,String> headers = options.buildRequestHeaders();
assertEquals(headers.size(), 2);
assertEquals(headers.get(
"x-amz-metadata-directive").iterator().next(),
"REPLACE");
assertEquals(options.getMetadata().size(), 1);
assertEquals(headers.get("x-amz-meta-adrian").iterator()
.next(), "foo");
assertEquals(options.getMetadata().get("x-amz-meta-adrian").iterator()
.next(), "foo");
assert options != null;
assert options.getMetadata() != null;
Multimap<String, String> headers = options.buildRequestHeaders();
assertEquals(headers.size(), 2);
assertEquals(headers.get(
"x-amz-metadata-directive").iterator().next(),
"REPLACE");
assertEquals(options.getMetadata().size(), 1);
assertEquals(headers.get("x-amz-meta-adrian").iterator()
.next(), "foo");
assertEquals(options.getMetadata().get("x-amz-meta-adrian").iterator()
.next(), "foo");
}
@Test
void testGoodMeta() {
CopyObjectOptions options = new CopyObjectOptions();
options.overrideMetadataWith(goodMeta);
assertGoodMeta(options);
CopyObjectOptions options = new CopyObjectOptions();
options.overrideMetadataWith(goodMeta);
assertGoodMeta(options);
}
@Test
public void testIfModifiedSince() {
CopyObjectOptions options = new CopyObjectOptions();
options.ifSourceModifiedSince(now);
assertEquals(options.getIfModifiedSince(), nowExpected);
CopyObjectOptions options = new CopyObjectOptions();
options.ifSourceModifiedSince(now);
assertEquals(options.getIfModifiedSince(), nowExpected);
}
@Test
public void testNullIfModifiedSince() {
CopyObjectOptions options = new CopyObjectOptions();
assertNull(options.getIfModifiedSince());
CopyObjectOptions options = new CopyObjectOptions();
assertNull(options.getIfModifiedSince());
}
@Test
public void testIfModifiedSinceStatic() {
CopyObjectOptions options = ifSourceModifiedSince(now);
assertEquals(options.getIfModifiedSince(), nowExpected);
CopyObjectOptions options = ifSourceModifiedSince(now);
assertEquals(options.getIfModifiedSince(), nowExpected);
}
@Test(expectedExceptions = NullPointerException.class)
public void testIfModifiedSinceNPE() {
ifSourceModifiedSince(null);
ifSourceModifiedSince(null);
}
@Test
public void testIfUnmodifiedSince() {
CopyObjectOptions options = new CopyObjectOptions();
options.ifSourceUnmodifiedSince(now);
isNowExpected(options);
CopyObjectOptions options = new CopyObjectOptions();
options.ifSourceUnmodifiedSince(now);
isNowExpected(options);
}
@Test
public void testNullIfUnmodifiedSince() {
CopyObjectOptions options = new CopyObjectOptions();
assertNull(options.getIfUnmodifiedSince());
CopyObjectOptions options = new CopyObjectOptions();
assertNull(options.getIfUnmodifiedSince());
}
@Test
public void testIfUnmodifiedSinceStatic() {
CopyObjectOptions options = ifSourceUnmodifiedSince(now);
isNowExpected(options);
CopyObjectOptions options = ifSourceUnmodifiedSince(now);
isNowExpected(options);
}
private void isNowExpected(CopyObjectOptions options) {
assertEquals(options.getIfUnmodifiedSince(), nowExpected);
assertEquals(options.getIfUnmodifiedSince(), nowExpected);
}
@Test(expectedExceptions = NullPointerException.class)
public void testIfUnmodifiedSinceNPE() {
ifSourceUnmodifiedSince(null);
ifSourceUnmodifiedSince(null);
}
@Test
public void testIfMd5Matches() throws UnsupportedEncodingException {
CopyObjectOptions options = new CopyObjectOptions();
options.ifSourceMd5Matches(testBytes);
matchesHex(options.getIfMatch());
CopyObjectOptions options = new CopyObjectOptions();
options.ifSourceMd5Matches(testBytes);
matchesHex(options.getIfMatch());
}
@Test
public void testNullIfMd5Matches() {
CopyObjectOptions options = new CopyObjectOptions();
assertNull(options.getIfMatch());
CopyObjectOptions options = new CopyObjectOptions();
assertNull(options.getIfMatch());
}
@Test
public void testIfMd5MatchesStatic() throws UnsupportedEncodingException {
CopyObjectOptions options = ifSourceMd5Matches(testBytes);
matchesHex(options.getIfMatch());
CopyObjectOptions options = ifSourceMd5Matches(testBytes);
matchesHex(options.getIfMatch());
}
@Test(expectedExceptions = NullPointerException.class)
public void testIfMd5MatchesNPE() throws UnsupportedEncodingException {
ifSourceMd5Matches(null);
ifSourceMd5Matches(null);
}
@Test
public void testIfMd5DoesntMatch() throws UnsupportedEncodingException {
CopyObjectOptions options = new CopyObjectOptions();
options.ifSourceMd5DoesntMatch(testBytes);
matchesHex(options.getIfNoneMatch());
CopyObjectOptions options = new CopyObjectOptions();
options.ifSourceMd5DoesntMatch(testBytes);
matchesHex(options.getIfNoneMatch());
}
@Test
public void testNullIfMd5DoesntMatch() {
CopyObjectOptions options = new CopyObjectOptions();
assertNull(options.getIfNoneMatch());
CopyObjectOptions options = new CopyObjectOptions();
assertNull(options.getIfNoneMatch());
}
@Test
public void testIfMd5DoesntMatchStatic()
throws UnsupportedEncodingException {
CopyObjectOptions options = ifSourceMd5DoesntMatch(testBytes);
matchesHex(options.getIfNoneMatch());
throws UnsupportedEncodingException {
CopyObjectOptions options = ifSourceMd5DoesntMatch(testBytes);
matchesHex(options.getIfNoneMatch());
}
@Test(expectedExceptions = NullPointerException.class)
public void testIfMd5DoesntMatchNPE() throws UnsupportedEncodingException {
ifSourceMd5DoesntMatch(null);
ifSourceMd5DoesntMatch(null);
}
private void matchesHex(String match) throws UnsupportedEncodingException {
String expected = "\"" + S3Utils.toHexString(testBytes) + "\"";
assertEquals(match, expected);
String expected = "\"" + S3Utils.toHexString(testBytes) + "\"";
assertEquals(match, expected);
}
@Test(expectedExceptions = IllegalStateException.class)
public void testIfUnmodifiedAfterModified() {
ifSourceModifiedSince(now).ifSourceUnmodifiedSince(now);
ifSourceModifiedSince(now).ifSourceUnmodifiedSince(now);
}
public void testIfUnmodifiedAfterMd5Matches()
throws UnsupportedEncodingException {
ifSourceMd5Matches(testBytes).ifSourceUnmodifiedSince(now);
throws UnsupportedEncodingException {
ifSourceMd5Matches(testBytes).ifSourceUnmodifiedSince(now);
}
@Test(expectedExceptions = IllegalStateException.class)
public void testIfUnmodifiedAfterMd5DoesntMatch()
throws UnsupportedEncodingException {
ifSourceMd5DoesntMatch(testBytes).ifSourceUnmodifiedSince(now);
throws UnsupportedEncodingException {
ifSourceMd5DoesntMatch(testBytes).ifSourceUnmodifiedSince(now);
}
@Test(expectedExceptions = IllegalStateException.class)
public void testIfModifiedAfterUnmodified() {
ifSourceUnmodifiedSince(now).ifSourceModifiedSince(now);
ifSourceUnmodifiedSince(now).ifSourceModifiedSince(now);
}
@Test(expectedExceptions = IllegalStateException.class)
public void testIfModifiedAfterMd5Matches()
throws UnsupportedEncodingException {
ifSourceMd5Matches(testBytes).ifSourceModifiedSince(now);
throws UnsupportedEncodingException {
ifSourceMd5Matches(testBytes).ifSourceModifiedSince(now);
}
public void testIfModifiedAfterMd5DoesntMatch()
throws UnsupportedEncodingException {
ifSourceMd5DoesntMatch(testBytes).ifSourceModifiedSince(now);
throws UnsupportedEncodingException {
ifSourceMd5DoesntMatch(testBytes).ifSourceModifiedSince(now);
}
@Test(expectedExceptions = IllegalStateException.class)
public void testMd5MatchesAfterIfModified()
throws UnsupportedEncodingException {
ifSourceModifiedSince(now).ifSourceMd5Matches(testBytes);
throws UnsupportedEncodingException {
ifSourceModifiedSince(now).ifSourceMd5Matches(testBytes);
}
public void testMd5MatchesAfterIfUnmodified()
throws UnsupportedEncodingException {
ifSourceUnmodifiedSince(now).ifSourceMd5Matches(testBytes);
throws UnsupportedEncodingException {
ifSourceUnmodifiedSince(now).ifSourceMd5Matches(testBytes);
}
@Test(expectedExceptions = IllegalStateException.class)
public void testMd5MatchesAfterMd5DoesntMatch()
throws UnsupportedEncodingException {
ifSourceMd5DoesntMatch(testBytes).ifSourceMd5Matches(testBytes);
throws UnsupportedEncodingException {
ifSourceMd5DoesntMatch(testBytes).ifSourceMd5Matches(testBytes);
}
public void testMd5DoesntMatchAfterIfModified()
throws UnsupportedEncodingException {
ifSourceModifiedSince(now).ifSourceMd5DoesntMatch(testBytes);
throws UnsupportedEncodingException {
ifSourceModifiedSince(now).ifSourceMd5DoesntMatch(testBytes);
}
@Test(expectedExceptions = IllegalStateException.class)
public void testMd5DoesntMatchAfterIfUnmodified()
throws UnsupportedEncodingException {
ifSourceUnmodifiedSince(now).ifSourceMd5DoesntMatch(testBytes);
throws UnsupportedEncodingException {
ifSourceUnmodifiedSince(now).ifSourceMd5DoesntMatch(testBytes);
}
@Test(expectedExceptions = IllegalStateException.class)
public void testMd5DoesntMatchAfterMd5Matches()
throws UnsupportedEncodingException {
ifSourceMd5Matches(testBytes).ifSourceMd5DoesntMatch(testBytes);
throws UnsupportedEncodingException {
ifSourceMd5Matches(testBytes).ifSourceMd5DoesntMatch(testBytes);
}
@Test
void testBuildRequestHeadersWhenMetadataNull()
throws UnsupportedEncodingException {
assert new CopyObjectOptions().buildRequestHeaders() != null;
throws UnsupportedEncodingException {
assert new CopyObjectOptions().buildRequestHeaders() != null;
}
@Test
void testBuildRequestHeaders() throws UnsupportedEncodingException {
Multimap<String, String> headers = ifSourceModifiedSince(now)
.ifSourceMd5DoesntMatch(testBytes).overrideMetadataWith(
goodMeta).buildRequestHeaders();
assertEquals(headers.get("x-amz-copy-source-if-modified-since")
.iterator().next(), new DateService().toHeaderString(now));
assertEquals(headers.get("x-amz-copy-source-if-none-match").iterator()
.next(), "\"" + S3Utils.toHexString(testBytes) + "\"");
for (String value : goodMeta.values())
assertTrue(headers.containsValue(value));
Multimap<String, String> headers = ifSourceModifiedSince(now)
.ifSourceMd5DoesntMatch(testBytes).overrideMetadataWith(
goodMeta).buildRequestHeaders();
assertEquals(headers.get("x-amz-copy-source-if-modified-since")
.iterator().next(), new DateService().toHeaderString(now));
assertEquals(headers.get("x-amz-copy-source-if-none-match").iterator()
.next(), "\"" + S3Utils.toHexString(testBytes) + "\"");
for (String value : goodMeta.values())
assertTrue(headers.containsValue(value));
}
@Test
public void testAclDefault() {
CopyObjectOptions options = new CopyObjectOptions();
assertEquals(options.getAcl(), CannedAccessPolicy.PRIVATE);
CopyObjectOptions options = new CopyObjectOptions();
assertEquals(options.getAcl(), CannedAccessPolicy.PRIVATE);
}
@Test
public void testAclStatic() {
CopyObjectOptions options = overrideAcl(CannedAccessPolicy.AUTHENTICATED_READ);
assertEquals(options.getAcl(), CannedAccessPolicy.AUTHENTICATED_READ);
CopyObjectOptions options = overrideAcl(CannedAccessPolicy.AUTHENTICATED_READ);
assertEquals(options.getAcl(), CannedAccessPolicy.AUTHENTICATED_READ);
}
@Test
void testBuildRequestHeadersACL() throws UnsupportedEncodingException {
Multimap<String, String> headers = overrideAcl(
CannedAccessPolicy.AUTHENTICATED_READ).buildRequestHeaders();
assertEquals(headers.get(S3Headers.CANNED_ACL).iterator().next(),
CannedAccessPolicy.AUTHENTICATED_READ.toString());
Multimap<String, String> headers = overrideAcl(
CannedAccessPolicy.AUTHENTICATED_READ).buildRequestHeaders();
assertEquals(headers.get(S3Headers.CANNED_ACL).iterator().next(),
CannedAccessPolicy.AUTHENTICATED_READ.toString());
}
}

View File

@ -23,29 +23,23 @@
*/
package org.jclouds.aws.s3.commands.options;
import static org.jclouds.aws.s3.commands.options.GetObjectOptions.Builder.startAt;
import static org.jclouds.aws.s3.commands.options.GetObjectOptions.Builder.tail;
import static org.jclouds.aws.s3.commands.options.GetObjectOptions.Builder.ifMd5DoesntMatch;
import static org.jclouds.aws.s3.commands.options.GetObjectOptions.Builder.ifMd5Matches;
import static org.jclouds.aws.s3.commands.options.GetObjectOptions.Builder.ifModifiedSince;
import static org.jclouds.aws.s3.commands.options.GetObjectOptions.Builder.ifUnmodifiedSince;
import static org.jclouds.aws.s3.commands.options.GetObjectOptions.Builder.range;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNull;
import java.io.UnsupportedEncodingException;
import static org.jclouds.aws.s3.commands.options.GetObjectOptions.Builder.*;
import org.jclouds.aws.s3.util.DateService;
import org.jclouds.aws.s3.util.S3Utils;
import org.joda.time.DateTime;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNull;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
import java.io.UnsupportedEncodingException;
/**
* Tests possible uses of GetObjectOptions and GetObjectOptions.Builder.*
*
*
* @author Adrian Cole
*/
@Test(groups = "unit", testName = "s3.GetObjectOptionsTest")
public class GetObjectOptionsTest {
private byte[] testBytes;
@ -54,287 +48,287 @@ public class GetObjectOptionsTest {
@BeforeTest
void setUp() {
now = new DateTime();
nowExpected = new DateService().toHeaderString(now);
testBytes = new byte[] { 0, 1, 2, 3, 4, 5, 6, 7 };
now = new DateTime();
nowExpected = new DateService().toHeaderString(now);
testBytes = new byte[]{0, 1, 2, 3, 4, 5, 6, 7};
}
@Test
public void testIfModifiedSince() {
GetObjectOptions options = new GetObjectOptions();
options.ifModifiedSince(now);
assertEquals(options.getIfModifiedSince(), nowExpected);
GetObjectOptions options = new GetObjectOptions();
options.ifModifiedSince(now);
assertEquals(options.getIfModifiedSince(), nowExpected);
}
@Test
public void testNullIfModifiedSince() {
GetObjectOptions options = new GetObjectOptions();
assertNull(options.getIfModifiedSince());
GetObjectOptions options = new GetObjectOptions();
assertNull(options.getIfModifiedSince());
}
@Test
public void testIfModifiedSinceStatic() {
GetObjectOptions options = ifModifiedSince(now);
assertEquals(options.getIfModifiedSince(), nowExpected);
GetObjectOptions options = ifModifiedSince(now);
assertEquals(options.getIfModifiedSince(), nowExpected);
}
@Test(expectedExceptions = NullPointerException.class)
public void testIfModifiedSinceNPE() {
ifModifiedSince(null);
ifModifiedSince(null);
}
@Test
public void testIfUnmodifiedSince() {
GetObjectOptions options = new GetObjectOptions();
options.ifUnmodifiedSince(now);
isNowExpected(options);
GetObjectOptions options = new GetObjectOptions();
options.ifUnmodifiedSince(now);
isNowExpected(options);
}
@Test
public void testNullIfUnmodifiedSince() {
GetObjectOptions options = new GetObjectOptions();
assertNull(options.getIfUnmodifiedSince());
GetObjectOptions options = new GetObjectOptions();
assertNull(options.getIfUnmodifiedSince());
}
@Test
public void testIfUnmodifiedSinceStatic() {
GetObjectOptions options = ifUnmodifiedSince(now);
isNowExpected(options);
GetObjectOptions options = ifUnmodifiedSince(now);
isNowExpected(options);
}
private void isNowExpected(GetObjectOptions options) {
assertEquals(options.getIfUnmodifiedSince(), nowExpected);
assertEquals(options.getIfUnmodifiedSince(), nowExpected);
}
@Test(expectedExceptions = NullPointerException.class)
public void testIfUnmodifiedSinceNPE() {
ifUnmodifiedSince(null);
ifUnmodifiedSince(null);
}
public void testModifiedSinceAndRange() {
GetObjectOptions options = new GetObjectOptions();
options.ifModifiedSince(now);
options.range(0, 1024);
isNowExpected(options);
bytes1to1024(options);
GetObjectOptions options = new GetObjectOptions();
options.ifModifiedSince(now);
options.range(0, 1024);
assertEquals(options.getIfModifiedSince(), nowExpected);
bytes1to1024(options);
}
@Test
public void testRange() {
GetObjectOptions options = new GetObjectOptions();
options.range(0, 1024);
bytes1to1024(options);
GetObjectOptions options = new GetObjectOptions();
options.range(0, 1024);
bytes1to1024(options);
}
private void bytes1to1024(GetObjectOptions options) {
assertEquals(options.getRange(), "bytes=0-1024");
assertEquals(options.getRange(), "bytes=0-1024");
}
@Test
public void testRangeZeroToFive() {
GetObjectOptions options = new GetObjectOptions();
options.range(0, 5);
assertEquals(options.getRange(), "bytes=0-5");
GetObjectOptions options = new GetObjectOptions();
options.range(0, 5);
assertEquals(options.getRange(), "bytes=0-5");
}
@Test
public void testTail() {
GetObjectOptions options = new GetObjectOptions();
options.tail(100);
assertEquals(options.getRange(), "bytes=-100");
GetObjectOptions options = new GetObjectOptions();
options.tail(100);
assertEquals(options.getRange(), "bytes=-100");
}
@Test
public void testTailStatic() {
GetObjectOptions options = tail(100);
assertEquals(options.getRange(), "bytes=-100");
GetObjectOptions options = tail(100);
assertEquals(options.getRange(), "bytes=-100");
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void testTailFail() {
GetObjectOptions options = new GetObjectOptions();
options.tail(0);
GetObjectOptions options = new GetObjectOptions();
options.tail(0);
}
@Test
public void testStartAt() {
GetObjectOptions options = new GetObjectOptions();
options.startAt(100);
assertEquals(options.getRange(), "bytes=100-");
GetObjectOptions options = new GetObjectOptions();
options.startAt(100);
assertEquals(options.getRange(), "bytes=100-");
}
@Test
public void testStartAtStatic() {
GetObjectOptions options = startAt(100);
assertEquals(options.getRange(), "bytes=100-");
GetObjectOptions options = startAt(100);
assertEquals(options.getRange(), "bytes=100-");
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void testStartAtFail() {
GetObjectOptions options = new GetObjectOptions();
options.startAt(-1);
GetObjectOptions options = new GetObjectOptions();
options.startAt(-1);
}
@Test
public void testRangeZeroToFiveAnd10through100() {
GetObjectOptions options = new GetObjectOptions();
options.range(0, 5).range(10, 100);
assertEquals(options.getRange(), "bytes=0-5,10-100");
GetObjectOptions options = new GetObjectOptions();
options.range(0, 5).range(10, 100);
assertEquals(options.getRange(), "bytes=0-5,10-100");
}
@Test
public void testNullRange() {
GetObjectOptions options = new GetObjectOptions();
assertNull(options.getRange());
GetObjectOptions options = new GetObjectOptions();
assertNull(options.getRange());
}
@Test
public void testRangeStatic() {
GetObjectOptions options = range(0, 1024);
bytes1to1024(options);
GetObjectOptions options = range(0, 1024);
bytes1to1024(options);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void testRangeNegative1() {
range(-1, 0);
range(-1, 0);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void testRangeNegative2() {
range(0, -1);
range(0, -1);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void testRangeNegative() {
range(-1, -1);
range(-1, -1);
}
@Test
public void testIfMd5Matches() throws UnsupportedEncodingException {
GetObjectOptions options = new GetObjectOptions();
options.ifMd5Matches(testBytes);
matchesHex(options.getIfMatch());
GetObjectOptions options = new GetObjectOptions();
options.ifMd5Matches(testBytes);
matchesHex(options.getIfMatch());
}
@Test
public void testNullIfMd5Matches() {
GetObjectOptions options = new GetObjectOptions();
assertNull(options.getIfMatch());
GetObjectOptions options = new GetObjectOptions();
assertNull(options.getIfMatch());
}
@Test
public void testIfMd5MatchesStatic() throws UnsupportedEncodingException {
GetObjectOptions options = ifMd5Matches(testBytes);
matchesHex(options.getIfMatch());
GetObjectOptions options = ifMd5Matches(testBytes);
matchesHex(options.getIfMatch());
}
@Test(expectedExceptions = NullPointerException.class)
public void testIfMd5MatchesNPE() throws UnsupportedEncodingException {
ifMd5Matches(null);
ifMd5Matches(null);
}
@Test
public void testIfMd5DoesntMatch() throws UnsupportedEncodingException {
GetObjectOptions options = new GetObjectOptions();
options.ifMd5DoesntMatch(testBytes);
matchesHex(options.getIfNoneMatch());
GetObjectOptions options = new GetObjectOptions();
options.ifMd5DoesntMatch(testBytes);
matchesHex(options.getIfNoneMatch());
}
@Test
public void testNullIfMd5DoesntMatch() {
GetObjectOptions options = new GetObjectOptions();
assertNull(options.getIfNoneMatch());
GetObjectOptions options = new GetObjectOptions();
assertNull(options.getIfNoneMatch());
}
@Test
public void testIfMd5DoesntMatchStatic()
throws UnsupportedEncodingException {
GetObjectOptions options = ifMd5DoesntMatch(testBytes);
matchesHex(options.getIfNoneMatch());
throws UnsupportedEncodingException {
GetObjectOptions options = ifMd5DoesntMatch(testBytes);
matchesHex(options.getIfNoneMatch());
}
@Test(expectedExceptions = NullPointerException.class)
public void testIfMd5DoesntMatchNPE() throws UnsupportedEncodingException {
ifMd5DoesntMatch(null);
ifMd5DoesntMatch(null);
}
private void matchesHex(String match) throws UnsupportedEncodingException {
String expected = "\"" + S3Utils.toHexString(testBytes) + "\"";
assertEquals(match, expected);
String expected = "\"" + S3Utils.toHexString(testBytes) + "\"";
assertEquals(match, expected);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void testIfUnmodifiedAfterModified() {
ifModifiedSince(now).ifUnmodifiedSince(now);
ifModifiedSince(now).ifUnmodifiedSince(now);
}
public void testIfUnmodifiedAfterMd5Matches()
throws UnsupportedEncodingException {
ifMd5Matches(testBytes).ifUnmodifiedSince(now);
throws UnsupportedEncodingException {
ifMd5Matches(testBytes).ifUnmodifiedSince(now);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void testIfUnmodifiedAfterMd5DoesntMatch()
throws UnsupportedEncodingException {
ifMd5DoesntMatch(testBytes).ifUnmodifiedSince(now);
throws UnsupportedEncodingException {
ifMd5DoesntMatch(testBytes).ifUnmodifiedSince(now);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void testIfModifiedAfterUnmodified() {
ifUnmodifiedSince(now).ifModifiedSince(now);
ifUnmodifiedSince(now).ifModifiedSince(now);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void testIfModifiedAfterMd5Matches()
throws UnsupportedEncodingException {
ifMd5Matches(testBytes).ifModifiedSince(now);
throws UnsupportedEncodingException {
ifMd5Matches(testBytes).ifModifiedSince(now);
}
public void testIfModifiedAfterMd5DoesntMatch()
throws UnsupportedEncodingException {
ifMd5DoesntMatch(testBytes).ifModifiedSince(now);
throws UnsupportedEncodingException {
ifMd5DoesntMatch(testBytes).ifModifiedSince(now);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void testMd5MatchesAfterIfModified()
throws UnsupportedEncodingException {
ifModifiedSince(now).ifMd5Matches(testBytes);
throws UnsupportedEncodingException {
ifModifiedSince(now).ifMd5Matches(testBytes);
}
public void testMd5MatchesAfterIfUnmodified()
throws UnsupportedEncodingException {
ifUnmodifiedSince(now).ifMd5Matches(testBytes);
throws UnsupportedEncodingException {
ifUnmodifiedSince(now).ifMd5Matches(testBytes);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void testMd5MatchesAfterMd5DoesntMatch()
throws UnsupportedEncodingException {
ifMd5DoesntMatch(testBytes).ifMd5Matches(testBytes);
throws UnsupportedEncodingException {
ifMd5DoesntMatch(testBytes).ifMd5Matches(testBytes);
}
public void testMd5DoesntMatchAfterIfModified()
throws UnsupportedEncodingException {
ifModifiedSince(now).ifMd5DoesntMatch(testBytes);
throws UnsupportedEncodingException {
ifModifiedSince(now).ifMd5DoesntMatch(testBytes);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void testMd5DoesntMatchAfterIfUnmodified()
throws UnsupportedEncodingException {
ifUnmodifiedSince(now).ifMd5DoesntMatch(testBytes);
throws UnsupportedEncodingException {
ifUnmodifiedSince(now).ifMd5DoesntMatch(testBytes);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void testMd5DoesntMatchAfterMd5Matches()
throws UnsupportedEncodingException {
ifMd5Matches(testBytes).ifMd5DoesntMatch(testBytes);
throws UnsupportedEncodingException {
ifMd5Matches(testBytes).ifMd5DoesntMatch(testBytes);
}
}

View File

@ -82,7 +82,7 @@ public class ListBucketOptionsTest {
public void testPrefixAndDelimiterUrlEncodingQueryString()
throws UnsupportedEncodingException {
ListBucketOptions options = new ListBucketOptions();
options.withPrefix("/test").setDelimiter("/");
options.withPrefix("/test").delimiter("/");
String query = options.buildQueryString();
checkEncodedQuery(query);
checkEncodedQuery(checkNotNull(query));
@ -165,7 +165,7 @@ public class ListBucketOptionsTest {
@Test
public void testDelimiter() throws UnsupportedEncodingException {
ListBucketOptions options = new ListBucketOptions();
options.setDelimiter("test");
options.delimiter("test");
assertEquals(options.getDelimiter(), "test");
}

View File

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

View File

@ -23,43 +23,41 @@
*/
package org.jclouds.aws.s3.commands.options;
import com.google.common.collect.Multimap;
import static org.jclouds.aws.s3.commands.options.PutObjectOptions.Builder.withAcl;
import org.jclouds.aws.s3.domain.acl.CannedAccessPolicy;
import org.jclouds.aws.s3.reference.S3Headers;
import static org.testng.Assert.assertEquals;
import org.testng.annotations.Test;
import java.io.UnsupportedEncodingException;
import org.jclouds.aws.s3.domain.acl.CannedAccessPolicy;
import org.jclouds.aws.s3.reference.S3Headers;
import org.testng.annotations.Test;
import com.google.common.collect.Multimap;
/**
* Tests possible uses of PutObjectOptions and PutObjectOptions.Builder.*
*
*
* @author Adrian Cole
*/
@Test(groups = "unit", testName = "s3.PutObjectOptionsTest")
public class PutObjectOptionsTest {
@Test
public void testAclDefault() {
PutObjectOptions options = new PutObjectOptions();
assertEquals(options.getAcl(), CannedAccessPolicy.PRIVATE);
PutObjectOptions options = new PutObjectOptions();
assertEquals(options.getAcl(), CannedAccessPolicy.PRIVATE);
}
@Test
public void testAclStatic() {
PutObjectOptions options = withAcl(CannedAccessPolicy.AUTHENTICATED_READ);
assertEquals(options.getAcl(), CannedAccessPolicy.AUTHENTICATED_READ);
PutObjectOptions options = withAcl(CannedAccessPolicy.AUTHENTICATED_READ);
assertEquals(options.getAcl(), CannedAccessPolicy.AUTHENTICATED_READ);
}
@Test
void testBuildRequestHeaders() throws UnsupportedEncodingException {
Multimap<String, String> headers = withAcl(
CannedAccessPolicy.AUTHENTICATED_READ).buildRequestHeaders();
assertEquals(headers.get(S3Headers.CANNED_ACL).iterator().next(),
CannedAccessPolicy.AUTHENTICATED_READ.toString());
Multimap<String, String> headers = withAcl(
CannedAccessPolicy.AUTHENTICATED_READ).buildRequestHeaders();
assertEquals(headers.get(S3Headers.CANNED_ACL).iterator().next(),
CannedAccessPolicy.AUTHENTICATED_READ.toString());
}
}

View File

@ -23,8 +23,10 @@
*/
package org.jclouds.aws.s3.config;
import static org.testng.Assert.assertEquals;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.name.Names;
import org.jclouds.aws.s3.handlers.ParseS3ErrorFromXmlContent;
import org.jclouds.aws.s3.reference.S3Constants;
import org.jclouds.http.HttpResponseHandler;
@ -33,94 +35,88 @@ import org.jclouds.http.annotation.RedirectHandler;
import org.jclouds.http.annotation.ServerErrorHandler;
import org.jclouds.http.config.JavaUrlHttpFutureCommandClientModule;
import org.jclouds.http.handlers.CloseContentAndSetExceptionHandler;
import static org.testng.Assert.assertEquals;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.name.Names;
/**
*
* @author Adrian Cole
*/
@Test
@Test(groups = "unit", testName = "s3.S3ContextModuleTest")
public class S3ContextModuleTest {
Injector injector = null;
@BeforeMethod
void setUpInjector() {
injector = Guice.createInjector(new S3ContextModule() {
@Override
protected void configure() {
bindConstant().annotatedWith(
Names.named(S3Constants.PROPERTY_AWS_ACCESSKEYID)).to(
"localhost");
bindConstant().annotatedWith(
Names.named(S3Constants.PROPERTY_AWS_SECRETACCESSKEY))
.to("localhost");
bindConstant().annotatedWith(
Names.named(S3Constants.PROPERTY_HTTP_ADDRESS)).to(
"localhost");
bindConstant().annotatedWith(
Names.named(S3Constants.PROPERTY_HTTP_PORT)).to("1000");
bindConstant().annotatedWith(
Names.named(S3Constants.PROPERTY_HTTP_SECURE)).to(
"false");
super.configure();
}
}, new JavaUrlHttpFutureCommandClientModule());
injector = Guice.createInjector(new LiveS3ConnectionModule(), new S3ContextModule() {
@Override
protected void configure() {
bindConstant().annotatedWith(
Names.named(S3Constants.PROPERTY_AWS_ACCESSKEYID)).to(
"localhost");
bindConstant().annotatedWith(
Names.named(S3Constants.PROPERTY_AWS_SECRETACCESSKEY))
.to("localhost");
bindConstant().annotatedWith(
Names.named(S3Constants.PROPERTY_HTTP_ADDRESS)).to(
"localhost");
bindConstant().annotatedWith(
Names.named(S3Constants.PROPERTY_HTTP_PORT)).to("1000");
bindConstant().annotatedWith(
Names.named(S3Constants.PROPERTY_HTTP_SECURE)).to(
"false");
super.configure();
}
}, new JavaUrlHttpFutureCommandClientModule());
}
@AfterMethod
void tearDownInjector() {
injector = null;
injector = null;
}
private static class ClientErrorHandlerTest {
@Inject
@ClientErrorHandler
HttpResponseHandler errorHandler;
@Inject
@ClientErrorHandler
HttpResponseHandler errorHandler;
}
@Test
void testClientErrorHandler() {
ClientErrorHandlerTest error = injector
.getInstance(ClientErrorHandlerTest.class);
assertEquals(error.errorHandler.getClass(),
ParseS3ErrorFromXmlContent.class);
ClientErrorHandlerTest error = injector
.getInstance(ClientErrorHandlerTest.class);
assertEquals(error.errorHandler.getClass(),
ParseS3ErrorFromXmlContent.class);
}
private static class ServerErrorHandlerTest {
@Inject
@ServerErrorHandler
HttpResponseHandler errorHandler;
@Inject
@ServerErrorHandler
HttpResponseHandler errorHandler;
}
@Test
void testServerErrorHandler() {
ServerErrorHandlerTest error = injector
.getInstance(ServerErrorHandlerTest.class);
assertEquals(error.errorHandler.getClass(),
ParseS3ErrorFromXmlContent.class);
ServerErrorHandlerTest error = injector
.getInstance(ServerErrorHandlerTest.class);
assertEquals(error.errorHandler.getClass(),
ParseS3ErrorFromXmlContent.class);
}
private static class RedirectHandlerTest {
@Inject
@RedirectHandler
HttpResponseHandler errorHandler;
@Inject
@RedirectHandler
HttpResponseHandler errorHandler;
}
@Test
void testRedirectHandler() {
RedirectHandlerTest error = injector
.getInstance(RedirectHandlerTest.class);
assertEquals(error.errorHandler.getClass(),
CloseContentAndSetExceptionHandler.class);
RedirectHandlerTest error = injector
.getInstance(RedirectHandlerTest.class);
assertEquals(error.errorHandler.getClass(),
CloseContentAndSetExceptionHandler.class);
}
}

View File

@ -0,0 +1,17 @@
package org.jclouds.aws.s3.config;
import com.google.inject.AbstractModule;
import org.jclouds.aws.s3.S3Connection;
import org.jclouds.aws.s3.StubS3Connection;
/**
* // TODO: Adrian: Document this!
*
* @author Adrian Cole
*/
@S3ConnectionModule
public class StubS3ConnectionModule extends AbstractModule {
protected void configure() {
bind(S3Connection.class).to(StubS3Connection.class);
}
}

View File

@ -23,23 +23,21 @@
*/
package org.jclouds.aws.s3.domain;
import java.io.File;
import static org.testng.Assert.*;
import org.jclouds.aws.s3.domain.S3Object;
import org.jclouds.http.ContentTypes;
import static org.testng.Assert.assertEquals;
import org.testng.annotations.Test;
@Test
import java.io.File;
@Test(groups = "unit", testName = "s3.S3ObjectTest")
public class S3ObjectTest {
@Test
void testSetNoContentType() {
S3Object object = new S3Object("test");
File file = new File("hello.txt");
object.setData(file);
assertEquals(object.getMetadata().getContentType(),
ContentTypes.BINARY);
S3Object object = new S3Object("test");
File file = new File("hello.txt");
object.setData(file);
assertEquals(object.getMetadata().getContentType(),
ContentTypes.BINARY);
}
}

View File

@ -26,14 +26,12 @@ package org.jclouds.aws.s3.filters;
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.name.Names;
import org.jclouds.aws.s3.reference.S3Constants;
import org.jclouds.aws.s3.util.DateService;
import org.testng.annotations.Test;
@Test(groups = "unit", sequential = true, testName = "s3.RequestAuthorizeSignatureTest")
@Test(groups = "unit", testName = "s3.RequestAuthorizeSignatureTest")
public class RequestAuthorizeSignatureTest {
RequestAuthorizeSignature filter = null;

View File

@ -23,20 +23,19 @@
*/
package org.jclouds.aws.s3.xml;
import com.google.inject.Guice;
import com.google.inject.Injector;
import org.jclouds.aws.s3.xml.config.S3ParserModule;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import com.google.inject.Guice;
import com.google.inject.Injector;
public class BaseHandlerTest {
protected S3ParserFactory parserFactory = null;
private Injector injector;
public BaseHandlerTest() {
super();
super();
}
@BeforeMethod

View File

@ -23,43 +23,42 @@
*/
package org.jclouds.aws.s3.xml;
import static org.testng.Assert.assertEquals;
import org.apache.commons.io.IOUtils;
import org.jclouds.aws.s3.domain.S3Error;
import org.jclouds.http.HttpException;
import org.jclouds.http.commands.callables.xml.ParseSax;
import static org.testng.Assert.assertEquals;
import org.testng.annotations.Test;
@Test
@Test(groups = "unit", testName = "s3.ErrorHandlerTest")
public class ErrorHandlerTest extends BaseHandlerTest {
public static final String errorFromAmazonIfYouDontRemoveTransferEncodingHeader = "<Error><Code>NotImplemented</Code><Message>A header you provided implies functionality that is not implemented</Message><Header>Transfer-Encoding</Header><RequestId>7C59925D75D15561</RequestId><HostId>fbskVU51OZJg2yZS/wNIxoE2PmCf0ZqFd0iH6Vrzw0uKG3KmokswBytL/Bfp/GWb</HostId></Error>";
@Test
public void testErrorFromAmazonIfYouDontRemoveTransferEncodingHeader()
throws HttpException {
ParseSax<S3Error> parser = parserFactory.createErrorParser();
S3Error error = parser
.parse(IOUtils
.toInputStream(errorFromAmazonIfYouDontRemoveTransferEncodingHeader));
assertEquals(error.getCode(), "NotImplemented");
assertEquals(error.getMessage(),
"A header you provided implies functionality that is not implemented");
assertEquals(error.getDetails().get("Header"), "Transfer-Encoding");
assertEquals(error.getRequestId(), "7C59925D75D15561");
assertEquals(error.getDetails().get("HostId"),
"fbskVU51OZJg2yZS/wNIxoE2PmCf0ZqFd0iH6Vrzw0uKG3KmokswBytL/Bfp/GWb");
throws HttpException {
ParseSax<S3Error> parser = parserFactory.createErrorParser();
S3Error error = parser
.parse(IOUtils
.toInputStream(errorFromAmazonIfYouDontRemoveTransferEncodingHeader));
assertEquals(error.getCode(), "NotImplemented");
assertEquals(error.getMessage(),
"A header you provided implies functionality that is not implemented");
assertEquals(error.getDetails().get("Header"), "Transfer-Encoding");
assertEquals(error.getRequestId(), "7C59925D75D15561");
assertEquals(error.getDetails().get("HostId"),
"fbskVU51OZJg2yZS/wNIxoE2PmCf0ZqFd0iH6Vrzw0uKG3KmokswBytL/Bfp/GWb");
}
public static final String badRequestWhenSourceIsDestBucketOnCopy400 = "<Error><Code>InvalidRequest</Code><Message>The Source and Destination may not be the same when the MetadataDirective is Copy.</Message><RequestId>54C77CAF4D42474B</RequestId><HostId>SJecknEUUUx88/65VAKbCdKSOCkpuVTeu7ZG9in9x9NTNglGnoxdbALCfS4k/DUZ</HostId></Error>";
public static final String noSuchSourceKeyOrBucketOnCopy404 = "<Error><Code>NoSuchKey</Code><Message>The specified key does not exist.</Message><Key>null</Key><RequestId>9CCDF1DACA78B36F</RequestId><HostId>63cqk9YsTFBVfBfks840JVGsepPEdQM42mU+r7HN35sF4Nk5xAcWDEUPaQpK2eFU</HostId></Error>";
public static final String noSuchDestinationBucketOnCopy404 = "<Error><Code>NoSuchBucket</Code><Message>The specified bucket does not exist</Message><BucketName>copydestination</BucketName><RequestId>4F0CF319C5535975</RequestId><HostId>hdZyHOm7VK+JI2UCdye3d6TVkKhRBIoWflldXVDTKbgipYlamy8HgPBzHrUAVQNJ</HostId></Error>";
public static final String noSuchDestinationBucketOnCopy404 = "<Error><Code>NoSuchBucket</Code><Message>The specified bucketName does not exist</Message><BucketName>copydestination</BucketName><RequestId>4F0CF319C5535975</RequestId><HostId>hdZyHOm7VK+JI2UCdye3d6TVkKhRBIoWflldXVDTKbgipYlamy8HgPBzHrUAVQNJ</HostId></Error>";
public static final String badSign403 = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+ "<Error><Code>SignatureDoesNotMatch</Code><Message>The operation signature we calculated does not match the signature you provided. Check your key and signing method.</Message><StringToSignBytes>47 45 54 0a 0a 0a 54 68 75 2c 20 31 39 20 4d 61 72 20 32 30 30 39 20 31 37 3a 34 38 3a 30 31 20 47 4d 54 0a 2f 61 64 72 69 61 6e 63 6f 6c 65 2e 73 33 2e 61 6d 61 7a 6f 6e 73 33 74 65 73 74 2e 66 69 6c 65 74 65 73 74 73 66 6f 72 61 64 72 69 61 6e 2f 66 69 6c 65</StringToSignBytes><RequestId>514AA22EB75A6E42</RequestId><HostId>H5nqnZkGjuKvB+seutvx5hnp1P+WAuC9c3Y7MdQCcYDr1TGwNX/mt+FHstK0pVld</HostId><SignatureProvided>Qm6Wss7e5e/eNXV50AxChH+xkLI=</SignatureProvided><StringToSign>GET\n"
+ "\n"
+ "\n"
+ "Thu, 19 Mar 2009 17:48:01 GMT\n"
+ "/adriancole.s3.amazons3test.filetestsforadrian/file</StringToSign><AWSAccessKeyId>0101100101001001</AWSAccessKeyId></Error>";
+ "<Error><Code>SignatureDoesNotMatch</Code><Message>The operation signature we calculated does not match the signature you provided. Check your key and signing method.</Message><StringToSignBytes>47 45 54 0a 0a 0a 54 68 75 2c 20 31 39 20 4d 61 72 20 32 30 30 39 20 31 37 3a 34 38 3a 30 31 20 47 4d 54 0a 2f 61 64 72 69 61 6e 63 6f 6c 65 2e 73 33 2e 61 6d 61 7a 6f 6e 73 33 74 65 73 74 2e 66 69 6c 65 74 65 73 74 73 66 6f 72 61 64 72 69 61 6e 2f 66 69 6c 65</StringToSignBytes><RequestId>514AA22EB75A6E42</RequestId><HostId>H5nqnZkGjuKvB+seutvx5hnp1P+WAuC9c3Y7MdQCcYDr1TGwNX/mt+FHstK0pVld</HostId><SignatureProvided>Qm6Wss7e5e/eNXV50AxChH+xkLI=</SignatureProvided><StringToSign>GET\n"
+ "\n"
+ "\n"
+ "Thu, 19 Mar 2009 17:48:01 GMT\n"
+ "/adriancole.s3.amazons3test.filetestsforadrian/file</StringToSign><AWSAccessKeyId>0101100101001001</AWSAccessKeyId></Error>";
public static final String amazonHadAnError500 = "<Error><Code>InternalError</Code><Message>We encountered an internal error. Please try again.</Message><RequestId>EF6FA7A639CAFF15</RequestId><HostId>tBkX23mIeq2riHsNw2YShupMlZ9+iy3V/uN+lRhqCR4qHTE07ujFeyAUPTowvuH/</HostId></Error>";
}

View File

@ -23,16 +23,15 @@
*/
package org.jclouds.aws.s3.xml;
import static org.testng.Assert.assertEquals;
import org.apache.commons.io.IOUtils;
import org.jclouds.aws.s3.domain.S3Bucket;
import org.jclouds.http.HttpException;
import org.jclouds.http.commands.callables.xml.ParseSax;
import static org.testng.Assert.assertEquals;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
@Test
@Test(groups = "unit", testName = "s3.ListBucketHandlerTest")
public class ListBucketHandlerTest extends BaseHandlerTest {
public static final String listBucketWithPrefixAppsSlash = "<ListBucketResult xmlns=\"http://s3.amazonaws.com/doc/2006-03-01/\"><Name>adriancole.org.jclouds.aws.s3.amazons3testdelimiter</Name><Prefix>apps/</Prefix><Marker></Marker><MaxKeys>1000</MaxKeys><IsTruncated>false</IsTruncated><Contents><Key>apps/0</Key><LastModified>2009-05-07T18:27:08.000Z</LastModified><ETag>&quot;c82e6a0025c31c5de5947fda62ac51ab&quot;</ETag><Size>8</Size><Owner><ID>e1a5f66a480ca99a4fdfe8e318c3020446c9989d7004e7778029fbcc5d990fa0</ID><DisplayName>ferncam</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>apps/1</Key><LastModified>2009-05-07T18:27:09.000Z</LastModified><ETag>&quot;944fab2c5a9a6bacf07db5e688310d7a&quot;</ETag><Size>8</Size><Owner><ID>e1a5f66a480ca99a4fdfe8e318c3020446c9989d7004e7778029fbcc5d990fa0</ID><DisplayName>ferncam</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>apps/2</Key><LastModified>2009-05-07T18:27:09.000Z</LastModified><ETag>&quot;a227b8888045c8fd159fb495214000f0&quot;</ETag><Size>8</Size><Owner><ID>e1a5f66a480ca99a4fdfe8e318c3020446c9989d7004e7778029fbcc5d990fa0</ID><DisplayName>ferncam</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>apps/3</Key><LastModified>2009-05-07T18:27:09.000Z</LastModified><ETag>&quot;c9caa76c3dec53e2a192608ce73eef03&quot;</ETag><Size>8</Size><Owner><ID>e1a5f66a480ca99a4fdfe8e318c3020446c9989d7004e7778029fbcc5d990fa0</ID><DisplayName>ferncam</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>apps/4</Key><LastModified>2009-05-07T18:27:09.000Z</LastModified><ETag>&quot;1ce5d0dcc6154a647ea90c7bdf82a224&quot;</ETag><Size>8</Size><Owner><ID>e1a5f66a480ca99a4fdfe8e318c3020446c9989d7004e7778029fbcc5d990fa0</ID><DisplayName>ferncam</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>apps/5</Key><LastModified>2009-05-07T18:27:09.000Z</LastModified><ETag>&quot;79433524d87462ee05708a8ef894ed55&quot;</ETag><Size>8</Size><Owner><ID>e1a5f66a480ca99a4fdfe8e318c3020446c9989d7004e7778029fbcc5d990fa0</ID><DisplayName>ferncam</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>apps/6</Key><LastModified>2009-05-07T18:27:10.000Z</LastModified><ETag>&quot;dd00a060b28ddca8bc5a21a49e306f67&quot;</ETag><Size>8</Size><Owner><ID>e1a5f66a480ca99a4fdfe8e318c3020446c9989d7004e7778029fbcc5d990fa0</ID><DisplayName>ferncam</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>apps/7</Key><LastModified>2009-05-07T18:27:10.000Z</LastModified><ETag>&quot;8cd06eca6e819a927b07a285d750b100&quot;</ETag><Size>8</Size><Owner><ID>e1a5f66a480ca99a4fdfe8e318c3020446c9989d7004e7778029fbcc5d990fa0</ID><DisplayName>ferncam</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>apps/8</Key><LastModified>2009-05-07T18:27:10.000Z</LastModified><ETag>&quot;174495094d0633b92cbe46603eee6bad&quot;</ETag><Size>8</Size><Owner><ID>e1a5f66a480ca99a4fdfe8e318c3020446c9989d7004e7778029fbcc5d990fa0</ID><DisplayName>ferncam</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>apps/9</Key><LastModified>2009-05-07T18:27:10.000Z</LastModified><ETag>&quot;cd8a19b26fea8a827276df0ad11c580d&quot;</ETag><Size>8</Size><Owner><ID>e1a5f66a480ca99a4fdfe8e318c3020446c9989d7004e7778029fbcc5d990fa0</ID><DisplayName>ferncam</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents></ListBucketResult>";
public static final String listBucketWithSlashDelimiterAndCommonPrefixApps = "<ListBucketResult xmlns=\"http://s3.amazonaws.com/doc/2006-03-01/\"> <Delimiter>/</Delimiter> <CommonPrefixes><Prefix>apps/</Prefix></CommonPrefixes></ListBucketResult>";
@ -40,29 +39,29 @@ public class ListBucketHandlerTest extends BaseHandlerTest {
@BeforeMethod
void setUpParser() {
parser = parserFactory.createListBucketParser();
((ListBucketHandler) parser.getHandler()).setBucketName("test");
parser = parserFactory.createListBucketParser();
((ListBucketHandler) parser.getHandler()).setBucketName("test");
}
@Test
public void testListMyBucketsWithDelimiterSlashAndCommonPrefixesAppsSlash()
throws HttpException {
throws HttpException {
S3Bucket bucket = parser.parse(IOUtils
.toInputStream(listBucketWithSlashDelimiterAndCommonPrefixApps));
assertEquals(bucket.getCommonPrefixes().iterator().next(), "apps/");
assertEquals(bucket.getDelimiter(), "/");
assert bucket.getMarker() == null;
S3Bucket bucket = parser.parse(IOUtils
.toInputStream(listBucketWithSlashDelimiterAndCommonPrefixApps));
assertEquals(bucket.getCommonPrefixes().iterator().next(), "apps/");
assertEquals(bucket.getDelimiter(), "/");
assert bucket.getMarker() == null;
}
@Test
public void testListMyBucketsWithPrefixAppsSlash() throws HttpException {
S3Bucket bucket = parser.parse(IOUtils
.toInputStream(listBucketWithPrefixAppsSlash));
assertEquals(bucket.getPrefix(), "apps/");
assertEquals(bucket.getMaxKeys(), 1000);
assert bucket.getMarker() == null;
S3Bucket bucket = parser.parse(IOUtils
.toInputStream(listBucketWithPrefixAppsSlash));
assertEquals(bucket.getPrefix(), "apps/");
assertEquals(bucket.getMaxKeys(), 1000);
assert bucket.getMarker() == null;
}

View File

@ -23,19 +23,17 @@
*/
package org.jclouds.aws.s3.xml;
import com.google.inject.Guice;
import com.google.inject.Injector;
import org.jclouds.aws.s3.xml.config.S3ParserModule;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import com.google.inject.Guice;
import com.google.inject.Injector;
/**
*
* @author Adrian Cole
*/
@Test
@Test(groups = "unit", testName = "s3.S3ParserFactoryTest")
public class S3ParserFactoryTest {
Injector injector = null;
@ -43,34 +41,34 @@ public class S3ParserFactoryTest {
@BeforeMethod
void setUpInjector() {
injector = Guice.createInjector(new S3ParserModule());
parserFactory = injector.getInstance(S3ParserFactory.class);
injector = Guice.createInjector(new S3ParserModule());
parserFactory = injector.getInstance(S3ParserFactory.class);
}
@AfterMethod
void tearDownInjector() {
parserFactory = null;
injector = null;
parserFactory = null;
injector = null;
}
@Test
void testCreateListBucketsParser() {
assert parserFactory.createListBucketsParser() != null;
assert parserFactory.createListBucketsParser() != null;
}
@Test
void testCreateListBucketParser() {
assert parserFactory.createListBucketParser() != null;
assert parserFactory.createListBucketParser() != null;
}
@Test
void testCreateCopyObjectParser() {
assert parserFactory.createCopyObjectParser() != null;
assert parserFactory.createCopyObjectParser() != null;
}
@Test
void testCreateErrorParser() {
assert parserFactory.createErrorParser() != null;
assert parserFactory.createErrorParser() != null;
}
}

View File

@ -23,6 +23,13 @@
*/
package com.amazon.s3;
import org.jclouds.aws.s3.reference.S3Constants;
import org.testng.ITestContext;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Optional;
import org.testng.annotations.Parameters;
import org.testng.annotations.Test;
import java.io.File;
import java.io.InputStream;
import java.util.Arrays;
@ -31,100 +38,94 @@ import java.util.Map;
import java.util.TreeMap;
import java.util.concurrent.ExecutionException;
import org.jclouds.aws.s3.reference.S3Constants;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Optional;
import org.testng.annotations.Parameters;
import org.testng.annotations.Test;
/**
* Runs operations that amazon s3 sample code is capable of performing.
*
*
* @author Adrian Cole
*/
@Test(sequential = true, timeOut = 2 * 60 * 1000, testName = "s3.AmazonPerformance")
public class AmazonPerformanceTest extends BasePerformance {
@Test(sequential = true, timeOut = 2 * 60 * 1000, testName = "s3.AmazonPerformanceLiveTest", groups = {"live"})
public class AmazonPerformanceLiveTest extends BasePerformance {
private AWSAuthConnection amzClient;
@Override
@BeforeTest
@Parameters( { S3Constants.PROPERTY_AWS_ACCESSKEYID,
S3Constants.PROPERTY_AWS_SECRETACCESSKEY })
protected void setUpClient(@Optional String AWSAccessKeyId,
@Optional String AWSSecretAccessKey) throws Exception {
super.setUpClient(AWSAccessKeyId, AWSSecretAccessKey);
amzClient = new AWSAuthConnection(AWSAccessKeyId, AWSSecretAccessKey,
false);
@Parameters({S3Constants.PROPERTY_AWS_ACCESSKEYID,
S3Constants.PROPERTY_AWS_SECRETACCESSKEY})
protected void setUpCredentials(@Optional String AWSAccessKeyId,
@Optional String AWSSecretAccessKey, ITestContext context) throws Exception {
super.setUpCredentials(AWSAccessKeyId, AWSSecretAccessKey, context);
amzClient = new AWSAuthConnection(AWSAccessKeyId, AWSSecretAccessKey,
false);
}
@Override
@Test(enabled = false)
public void testPutFileSerial() throws Exception {
throw new UnsupportedOperationException();
throw new UnsupportedOperationException();
}
@Override
@Test(enabled = false)
public void testPutFileParallel() throws InterruptedException,
ExecutionException {
throw new UnsupportedOperationException();
ExecutionException {
throw new UnsupportedOperationException();
}
@Override
@Test(enabled = false)
public void testPutInputStreamSerial() throws Exception {
throw new UnsupportedOperationException();
throw new UnsupportedOperationException();
}
@Override
@Test(enabled = false)
public void testPutInputStreamParallel() throws InterruptedException,
ExecutionException {
throw new UnsupportedOperationException();
ExecutionException {
throw new UnsupportedOperationException();
}
@Override
@Test(enabled = false)
public void testPutStringSerial() throws Exception {
throw new UnsupportedOperationException();
throw new UnsupportedOperationException();
}
@Override
@Test(enabled = false)
public void testPutStringParallel() throws InterruptedException,
ExecutionException {
throw new UnsupportedOperationException();
ExecutionException {
throw new UnsupportedOperationException();
}
@Override
protected boolean putByteArray(String bucket, String key, byte[] data,
String contentType) throws Exception {
com.amazon.s3.S3Object object = new com.amazon.s3.S3Object(data, null);
Map<String, List<String>> headers = new TreeMap<String, List<String>>();
headers
.put("Content-Type", Arrays
.asList(new String[] { contentType }));
return amzClient.put(bucket, key, object, headers).connection
.getResponseMessage() != null;
String contentType) throws Exception {
com.amazon.s3.S3Object object = new com.amazon.s3.S3Object(data, null);
Map<String, List<String>> headers = new TreeMap<String, List<String>>();
headers
.put("Content-Type", Arrays
.asList(new String[]{contentType}));
return amzClient.put(bucket, key, object, headers).connection
.getResponseMessage() != null;
}
@Override
protected boolean putFile(String bucket, String key, File data,
String contentType) throws Exception {
throw new UnsupportedOperationException();
String contentType) throws Exception {
throw new UnsupportedOperationException();
}
@Override
protected boolean putInputStream(String bucket, String key,
InputStream data, String contentType) throws Exception {
throw new UnsupportedOperationException();
InputStream data, String contentType) throws Exception {
throw new UnsupportedOperationException();
}
@Override
protected boolean putString(String bucket, String key, String data,
String contentType) throws Exception {
throw new UnsupportedOperationException();
String contentType) throws Exception {
throw new UnsupportedOperationException();
}
}

View File

@ -29,7 +29,7 @@ import java.util.concurrent.TimeUnit;
/**
* // TODO: Adrian: Document this!
*
*
* @author Adrian Cole
*/
public abstract class BaseJCloudsPerformance extends BasePerformance {
@ -53,42 +53,42 @@ public abstract class BaseJCloudsPerformance extends BasePerformance {
@Override
protected boolean putByteArray(String bucket, String key, byte[] data,
String contentType) throws Exception {
org.jclouds.aws.s3.domain.S3Object object = new org.jclouds.aws.s3.domain.S3Object(
key);
object.getMetadata().setContentType(contentType);
object.setData(data);
return client.putObject(bucket, object).get(120, TimeUnit.SECONDS) != null;
String contentType) throws Exception {
org.jclouds.aws.s3.domain.S3Object object = new org.jclouds.aws.s3.domain.S3Object(
key);
object.getMetadata().setContentType(contentType);
object.setData(data);
return client.putObject(bucket, object).get(120, TimeUnit.SECONDS) != null;
}
@Override
protected boolean putFile(String bucket, String key, File data,
String contentType) throws Exception {
org.jclouds.aws.s3.domain.S3Object object = new org.jclouds.aws.s3.domain.S3Object(
key);
object.getMetadata().setContentType(contentType);
object.setData(data);
return client.putObject(bucket, object).get(120, TimeUnit.SECONDS) != null;
String contentType) throws Exception {
org.jclouds.aws.s3.domain.S3Object object = new org.jclouds.aws.s3.domain.S3Object(
key);
object.getMetadata().setContentType(contentType);
object.setData(data);
return client.putObject(bucket, object).get(120, TimeUnit.SECONDS) != null;
}
@Override
protected boolean putInputStream(String bucket, String key,
InputStream data, String contentType) throws Exception {
org.jclouds.aws.s3.domain.S3Object object = new org.jclouds.aws.s3.domain.S3Object(
key);
object.getMetadata().setContentType(contentType);
object.setData(data);
object.getMetadata().setSize(data.available());
return client.putObject(bucket, object).get(120, TimeUnit.SECONDS) != null;
InputStream data, String contentType) throws Exception {
org.jclouds.aws.s3.domain.S3Object object = new org.jclouds.aws.s3.domain.S3Object(
key);
object.getMetadata().setContentType(contentType);
object.setData(data);
object.getMetadata().setSize(data.available());
return client.putObject(bucket, object).get(120, TimeUnit.SECONDS) != null;
}
@Override
protected boolean putString(String bucket, String key, String data,
String contentType) throws Exception {
org.jclouds.aws.s3.domain.S3Object object = new org.jclouds.aws.s3.domain.S3Object(
key);
object.getMetadata().setContentType(contentType);
object.setData(data);
return client.putObject(bucket, object).get(120, TimeUnit.SECONDS) != null;
String contentType) throws Exception {
org.jclouds.aws.s3.domain.S3Object object = new org.jclouds.aws.s3.domain.S3Object(
key);
object.getMetadata().setContentType(contentType);
object.setData(data);
return client.putObject(bucket, object).get(120, TimeUnit.SECONDS) != null;
}
}

View File

@ -23,39 +23,28 @@
*/
package com.amazon.s3;
import com.google.inject.Provider;
import org.jclouds.aws.s3.S3IntegrationTest;
import org.testng.ITestContext;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.InputStream;
import java.util.concurrent.Callable;
import java.util.concurrent.CompletionService;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
import org.jclouds.aws.s3.S3IntegrationTest;
import org.jclouds.aws.s3.reference.S3Constants;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Optional;
import org.testng.annotations.Parameters;
import org.testng.annotations.Test;
import com.google.inject.Provider;
/**
* // TODO: Adrian: Document this!
*
*
* @author Adrian Cole
*/
@Test
@Test(groups = {"live"})
public abstract class BasePerformance extends S3IntegrationTest {
protected boolean debugEnabled() {
return false;
return false;
}
protected static int LOOP_COUNT = 100;
@ -65,8 +54,8 @@ public abstract class BasePerformance extends S3IntegrationTest {
protected final String BUCKET_INPUTSTREAM = bucketPrefix + "-inputstream";
protected final String BUCKET_STRING = bucketPrefix + "-string";
protected final String BUCKET_FILE = bucketPrefix + "-file";
protected final String[] BUCKETS = { BUCKET_BYTES, BUCKET_INPUTSTREAM,
BUCKET_STRING, BUCKET_FILE };
protected final String[] BUCKETS = {BUCKET_BYTES, BUCKET_INPUTSTREAM,
BUCKET_STRING, BUCKET_FILE};
protected PutBytesCallable putBytesCallable;
protected PutFileCallable putFileCallable;
protected PutInputStreamCallable putInputStreamCallable;
@ -76,163 +65,160 @@ public abstract class BasePerformance extends S3IntegrationTest {
@BeforeTest
protected void setUpCallables() {
putBytesCallable = new PutBytesCallable();
putFileCallable = new PutFileCallable();
putInputStreamCallable = new PutInputStreamCallable();
putStringCallable = new PutStringCallable();
exec = Executors.newCachedThreadPool();
completer = new ExecutorCompletionService<Boolean>(exec);
putBytesCallable = new PutBytesCallable();
putFileCallable = new PutFileCallable();
putInputStreamCallable = new PutInputStreamCallable();
putStringCallable = new PutStringCallable();
exec = Executors.newCachedThreadPool();
completer = new ExecutorCompletionService<Boolean>(exec);
}
@Override
@BeforeTest
@Parameters( { S3Constants.PROPERTY_AWS_ACCESSKEYID,
S3Constants.PROPERTY_AWS_SECRETACCESSKEY })
protected void setUpClient(@Optional String AWSAccessKeyId,
@Optional String AWSSecretAccessKey) throws Exception {
super.setUpClient(AWSAccessKeyId, AWSSecretAccessKey);
for (String bucket : BUCKETS) {
client.putBucketIfNotExists(bucket).get(10, TimeUnit.SECONDS);
}
protected void setUpClient(ITestContext context) throws Exception {
super.setUpClient(context);
for (String bucket : BUCKETS) {
client.putBucketIfNotExists(bucket).get(10, TimeUnit.SECONDS);
}
}
@AfterTest
protected void tearDownExecutor() throws Exception {
exec.shutdownNow();
exec = null;
exec.shutdownNow();
exec = null;
}
@Test(enabled = true)
public void testPutBytesSerial() throws Exception {
doSerial(putBytesCallable, LOOP_COUNT / 10);
doSerial(putBytesCallable, LOOP_COUNT / 10);
}
@Test(enabled = true)
public void testPutBytesParallel() throws InterruptedException,
ExecutionException, TimeoutException {
doParallel(putBytesCallable, LOOP_COUNT);
ExecutionException, TimeoutException {
doParallel(putBytesCallable, LOOP_COUNT);
}
@Test(enabled = true)
public void testPutFileSerial() throws Exception {
doSerial(putFileCallable, LOOP_COUNT / 10);
doSerial(putFileCallable, LOOP_COUNT / 10);
}
@Test(enabled = true)
public void testPutFileParallel() throws InterruptedException,
ExecutionException, TimeoutException {
doParallel(putFileCallable, LOOP_COUNT);
ExecutionException, TimeoutException {
doParallel(putFileCallable, LOOP_COUNT);
}
@Test(enabled = true)
public void testPutInputStreamSerial() throws Exception {
doSerial(putInputStreamCallable, LOOP_COUNT / 10);
doSerial(putInputStreamCallable, LOOP_COUNT / 10);
}
@Test(enabled = true)
public void testPutInputStreamParallel() throws InterruptedException,
ExecutionException, TimeoutException {
doParallel(putInputStreamCallable, LOOP_COUNT);
ExecutionException, TimeoutException {
doParallel(putInputStreamCallable, LOOP_COUNT);
}
@Test(enabled = true)
public void testPutStringSerial() throws Exception {
doSerial(putStringCallable, LOOP_COUNT / 10);
doSerial(putStringCallable, LOOP_COUNT / 10);
}
@Test(enabled = true)
public void testPutStringParallel() throws InterruptedException,
ExecutionException, TimeoutException {
doParallel(putStringCallable, LOOP_COUNT);
ExecutionException, TimeoutException {
doParallel(putStringCallable, LOOP_COUNT);
}
private void doSerial(Provider<Callable<Boolean>> provider, int loopCount)
throws Exception, ExecutionException {
for (int i = 0; i < loopCount; i++)
assert provider.get().call();
throws Exception, ExecutionException {
for (int i = 0; i < loopCount; i++)
assert provider.get().call();
}
private void doParallel(Provider<Callable<Boolean>> provider, int loopCount)
throws InterruptedException, ExecutionException, TimeoutException {
for (int i = 0; i < loopCount; i++)
completer.submit(provider.get());
for (int i = 0; i < loopCount; i++)
assert completer.take().get(10, TimeUnit.SECONDS);
throws InterruptedException, ExecutionException, TimeoutException {
for (int i = 0; i < loopCount; i++)
completer.submit(provider.get());
for (int i = 0; i < loopCount; i++)
assert completer.take().get(10, TimeUnit.SECONDS);
}
class PutBytesCallable implements Provider<Callable<Boolean>> {
final AtomicInteger key = new AtomicInteger(0);
protected byte[] test = new byte[1024 * 2];
final AtomicInteger key = new AtomicInteger(0);
protected byte[] test = new byte[1024 * 2];
public Callable<Boolean> get() {
return new Callable<Boolean>() {
public Boolean call() throws Exception {
return putByteArray(BUCKET_BYTES, key.getAndIncrement()
+ "", test, "application/octetstring");
}
};
public Callable<Boolean> get() {
return new Callable<Boolean>() {
public Boolean call() throws Exception {
return putByteArray(BUCKET_BYTES, key.getAndIncrement()
+ "", test, "application/octetstring");
}
};
}
}
}
class PutFileCallable implements Provider<Callable<Boolean>> {
final AtomicInteger key = new AtomicInteger(0);
protected File file = new File("pom.xml");
final AtomicInteger key = new AtomicInteger(0);
protected File file = new File("pom.xml");
public Callable<Boolean> get() {
return new Callable<Boolean>() {
public Boolean call() throws Exception {
return putFile(BUCKET_FILE, key.getAndIncrement() + "",
file, "text/xml");
}
};
public Callable<Boolean> get() {
return new Callable<Boolean>() {
public Boolean call() throws Exception {
return putFile(BUCKET_FILE, key.getAndIncrement() + "",
file, "text/xml");
}
};
}
}
}
class PutInputStreamCallable extends PutBytesCallable {
final AtomicInteger key = new AtomicInteger(0);
final AtomicInteger key = new AtomicInteger(0);
@Override
public Callable<Boolean> get() {
return new Callable<Boolean>() {
public Boolean call() throws Exception {
return putInputStream(BUCKET_INPUTSTREAM, key
.getAndIncrement()
+ "", new ByteArrayInputStream(test),
"application/octetstring");
}
};
@Override
public Callable<Boolean> get() {
return new Callable<Boolean>() {
public Boolean call() throws Exception {
return putInputStream(BUCKET_INPUTSTREAM, key
.getAndIncrement()
+ "", new ByteArrayInputStream(test),
"application/octetstring");
}
};
}
}
}
class PutStringCallable implements Provider<Callable<Boolean>> {
final AtomicInteger key = new AtomicInteger(0);
protected String testString = "hello world!";
final AtomicInteger key = new AtomicInteger(0);
protected String testString = "hello world!";
public Callable<Boolean> get() {
return new Callable<Boolean>() {
public Boolean call() throws Exception {
return putString(BUCKET_STRING, key.getAndIncrement() + "",
testString, "text/plain");
}
};
public Callable<Boolean> get() {
return new Callable<Boolean>() {
public Boolean call() throws Exception {
return putString(BUCKET_STRING, key.getAndIncrement() + "",
testString, "text/plain");
}
};
}
}
}
protected abstract boolean putByteArray(String bucket, String key,
byte[] data, String contentType) throws Exception;
byte[] data, String contentType) throws Exception;
protected abstract boolean putFile(String bucket, String key, File data,
String contentType) throws Exception;
String contentType) throws Exception;
protected abstract boolean putInputStream(String bucket, String key,
InputStream data, String contentType) throws Exception;
InputStream data, String contentType) throws Exception;
protected abstract boolean putString(String bucket, String key,
String data, String contentType) throws Exception;
String data, String contentType) throws Exception;
// private class BucketDeleter implements Callable<Boolean> {
// private BucketDeleter(S3Bucket bucket) {

View File

@ -24,20 +24,19 @@
package com.amazon.s3;
import java.util.Properties;
import com.google.inject.Module;
import org.jclouds.http.httpnio.config.HttpNioConnectionPoolClientModule;
import org.testng.annotations.Test;
import com.google.inject.Module;
import java.util.Properties;
@Test(sequential=true, testName = "s3.JCloudsNioPerformance")
public class JCloudsNioPerformanceTest extends BaseJCloudsPerformance {
@Test(sequential = true, testName = "s3.JCloudsNioPerformanceLiveTest", groups = {"live"})
public class JCloudsNioPerformanceLiveTest extends BaseJCloudsPerformance {
@Override
protected Properties buildS3Properties(String AWSAccessKeyId,
String AWSSecretAccessKey) {
Properties properties = super.buildS3Properties(AWSAccessKeyId, AWSSecretAccessKey);
String AWSSecretAccessKey) {
Properties properties = super.buildS3Properties(AWSAccessKeyId, AWSSecretAccessKey);
properties.setProperty("jclouds.http.pool.max_connection_reuse", "75");
properties.setProperty("jclouds.http.pool.max_session_failures", "2");
properties.setProperty("jclouds.http.pool.request_invoker_threads", "1");

View File

@ -31,7 +31,7 @@ import org.testng.annotations.Test;
* @author Adrian Cole
*
*/
@Test(sequential = true, timeOut = 2 * 60 * 1000, testName = "s3.JCloudsPerformance")
public class JCloudsPerformanceTest extends BaseJCloudsPerformance {
@Test(sequential = true, timeOut = 2 * 60 * 1000, testName = "s3.JCloudsPerformanceLiveTest", groups = {"live"})
public class JCloudsPerformanceLiveTest extends BaseJCloudsPerformance {
}

View File

@ -23,107 +23,108 @@
*/
package com.amazon.s3;
import org.jets3t.service.S3Service;
import org.jets3t.service.impl.rest.httpclient.RestS3Service;
import org.jets3t.service.security.AWSCredentials;
import org.testng.ITestContext;
import org.testng.annotations.Test;
import java.io.File;
import java.io.InputStream;
import java.util.concurrent.ExecutionException;
import org.jets3t.service.S3Service;
import org.jets3t.service.impl.rest.httpclient.RestS3Service;
import org.jets3t.service.security.AWSCredentials;
import org.testng.annotations.Test;
/**
* Runs operations that jets3t is capable of performing.
*
*
* @author Adrian Cole
*/
@Test(sequential = true, timeOut = 2 * 60 * 1000, testName = "s3.Jets3tPerformance")
public class Jets3tPerformanceTest extends BasePerformance {
@Test(sequential = true, timeOut = 2 * 60 * 1000, testName = "s3.Jets3tPerformanceLiveTest", groups = {"live"})
public class Jets3tPerformanceLiveTest extends BasePerformance {
private S3Service jetClient;
@Override
protected void setUpClient(String AWSAccessKeyId, String AWSSecretAccessKey)
throws Exception {
super.setUpClient(AWSAccessKeyId, AWSSecretAccessKey);
jetClient = new RestS3Service(new AWSCredentials(AWSAccessKeyId,
AWSSecretAccessKey));
protected void setUpCredentials(String AWSAccessKeyId, String AWSSecretAccessKey, ITestContext context)
throws Exception {
super.setUpCredentials(AWSAccessKeyId, AWSSecretAccessKey, context);
jetClient = new RestS3Service(new AWSCredentials(AWSAccessKeyId,
AWSSecretAccessKey));
}
@Override
@Test(enabled = false)
public void testPutStringSerial() throws Exception {
throw new UnsupportedOperationException();
throw new UnsupportedOperationException();
}
@Override
@Test(enabled = false)
public void testPutBytesSerial() throws Exception {
throw new UnsupportedOperationException();
throw new UnsupportedOperationException();
}
@Override
@Test(enabled = false)
public void testPutStringParallel() throws InterruptedException,
ExecutionException {
throw new UnsupportedOperationException();
ExecutionException {
throw new UnsupportedOperationException();
}
@Override
@Test(enabled = false)
public void testPutBytesParallel() throws InterruptedException,
ExecutionException {
throw new UnsupportedOperationException();
ExecutionException {
throw new UnsupportedOperationException();
}
@Override
@Test(enabled = false)
public void testPutInputStreamParallel() throws InterruptedException,
ExecutionException {
throw new UnsupportedOperationException();
ExecutionException {
throw new UnsupportedOperationException();
}
@Override
@Test(enabled = false)
public void testPutFileParallel() throws InterruptedException,
ExecutionException {
throw new UnsupportedOperationException();
ExecutionException {
throw new UnsupportedOperationException();
}
@Override
@Test(enabled = false)
protected boolean putByteArray(String bucket, String key, byte[] data,
String contentType) throws Exception {
throw new UnsupportedOperationException();
String contentType) throws Exception {
throw new UnsupportedOperationException();
}
@Override
protected boolean putFile(String bucket, String key, File data,
String contentType) throws Exception {
org.jets3t.service.model.S3Object object = new org.jets3t.service.model.S3Object(
key);
object.setContentType(contentType);
object.setDataInputFile(data);
object.setContentLength(data.length());
return jetClient.putObject(bucket, object) != null;
String contentType) throws Exception {
org.jets3t.service.model.S3Object object = new org.jets3t.service.model.S3Object(
key);
object.setContentType(contentType);
object.setDataInputFile(data);
object.setContentLength(data.length());
return jetClient.putObject(bucket, object) != null;
}
@Override
protected boolean putInputStream(String bucket, String key,
InputStream data, String contentType) throws Exception {
org.jets3t.service.model.S3Object object = new org.jets3t.service.model.S3Object(
key);
object.setContentType(contentType);
object.setDataInputStream(data);
object.setContentLength(data.available());
return jetClient.putObject(bucket, object) != null;
InputStream data, String contentType) throws Exception {
org.jets3t.service.model.S3Object object = new org.jets3t.service.model.S3Object(
key);
object.setContentType(contentType);
object.setDataInputStream(data);
object.setContentLength(data.available());
return jetClient.putObject(bucket, object) != null;
}
@Override
protected boolean putString(String bucket, String key, String data,
String contentType) throws Exception {
throw new UnsupportedOperationException();
String contentType) throws Exception {
throw new UnsupportedOperationException();
}
}

48
pom.xml
View File

@ -38,25 +38,23 @@
<packaging>pom</packaging>
<name>jclouds</name>
<modules>
<module>project</module>
<module>project</module>
<module>core</module>
<module>extensions/httpnio</module>
<module>extensions/log4j</module>
<module>extensions/gae</module>
<module>s3</module>
<module>extensions</module>
<module>aws</module>
</modules>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<configuration>
<quiet>true</quiet>
<links>
<link>http://java.sun.com/j2se/1.5.0/docs/api/</link>
<link>http://java.sun.com/javaee/5/docs/api/</link>
</links>
<footer><![CDATA[
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<configuration>
<quiet>true</quiet>
<links>
<link>http://java.sun.com/j2se/1.5.0/docs/api/</link>
<link>http://java.sun.com/javaee/5/docs/api/</link>
</links>
<footer><![CDATA[
<!-- Google Analytics -->
<script type='text/javascript'>
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
@ -68,17 +66,17 @@ var pageTracker = _gat._getTracker("UA-8638379-1");
pageTracker._trackPageview();
} catch(err) {}</script>
]]></footer>
</configuration>
<executions>
<execution>
<id>javadoc</id>
<phase>package</phase>
<goals>
<goal>aggregate</goal>
</goals>
</configuration>
<executions>
<execution>
<id>javadoc</id>
<phase>package</phase>
<goals>
<goal>aggregate</goal>
</goals>
</execution>
</executions>
</plugin>
</plugin>
<plugin>
<groupId>com.google.code.maven-license-plugin</groupId>
<artifactId>maven-license-plugin</artifactId>

View File

@ -95,10 +95,10 @@
</repositories>
<distributionManagement>
<repository>
<uniqueVersion>false</uniqueVersion>
<id>jclouds-googlecode-deploy</id>
<url>svn:https://jclouds.googlecode.com/svn/repo</url>
<repository>
<uniqueVersion>false</uniqueVersion>
<id>jclouds-googlecode-deploy</id>
<url>svn:https://jclouds.googlecode.com/svn/repo</url>
</repository>
<site>
<id>website</id>
@ -148,46 +148,82 @@
<classifier>jdk15</classifier>
</dependency>
<dependency>
<groupId>org.easymock</groupId>
<artifactId>easymockclassextension</artifactId>
<version>2.4</version>
<scope>test</scope>
<groupId>org.easymock</groupId>
<artifactId>easymockclassextension</artifactId>
<version>2.4</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<!-- Make sure we generate src jars too -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<inherited>true</inherited>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<executions>
<execution>
<id>javadoc</id>
<phase>package</phase>
<goals>
<goal>jar</goal>
</goals>
<configuration>
<quiet>true</quiet>
<links>
<link>http://java.sun.com/j2se/1.5.0/docs/api/</link>
<link>http://java.sun.com/javaee/5/docs/api/</link>
</links>
<footer><![CDATA[
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<executions>
<execution>
<id>integration</id>
<phase>integration-test</phase>
<goals>
<goal>test</goal>
</goals>
<configuration>
<!-- note that the groups/excluded groups don't work due to some problem
in surefire or testng. instead, we have to exclude via file path
<groups>integration</groups>
<excludedGroups>unit,performance,live</excludedGroups> -->
<excludes>
<exclude>**/*LiveTest.java</exclude>
</excludes>
<includes>
<include>**/*IntegrationTest.java</include>
</includes>
</configuration>
</execution>
</executions>
<configuration>
<!-- note that the groups/excluded groups don't work due to some problem
in surefire or testng. instead, we have to exclude via file path
<groups>unit,performance</groups>
<excludedGroups>integration,live</excludedGroups> -->
<excludes>
<exclude>**/*IntegrationTest.java</exclude>
<exclude>**/*LiveTest.java</exclude>
</excludes>
</configuration>
</plugin>
<!-- Make sure we generate src jars too -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<inherited>true</inherited>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<executions>
<execution>
<id>javadoc</id>
<phase>package</phase>
<goals>
<goal>jar</goal>
</goals>
<configuration>
<quiet>true</quiet>
<links>
<link>http://java.sun.com/j2se/1.5.0/docs/api/</link>
<link>http://java.sun.com/javaee/5/docs/api/</link>
</links>
<footer><![CDATA[
<!-- Google Analytics -->
<script type='text/javascript'>
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
@ -199,10 +235,10 @@ var pageTracker = _gat._getTracker("UA-8638379-1");
pageTracker._trackPageview();
} catch(err) {}</script>
]]></footer>
</configuration>
</execution>
</executions>
</plugin>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
@ -235,11 +271,11 @@ pageTracker._trackPageview();
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>test-jar</goal>
</goals>
</execution>
<execution>
<goals>
<goal>test-jar</goal>
</goals>
</execution>
</executions>
<configuration>
<archive>
@ -261,26 +297,26 @@ pageTracker._trackPageview();
</plugin>
<!-- enforce java 1.5 and maven 2.1.0 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<executions>
<execution>
<id>enforce-java</id>
<goals>
<goal>enforce</goal>
</goals>
<configuration>
<rules>
<requireJavaVersion>
<version>[1.5,)</version>
</requireJavaVersion>
<requireMavenVersion>
<version>[2.1.0,)</version>
</requireMavenVersion>
</rules>
</configuration>
</execution>
</executions>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<executions>
<execution>
<id>enforce-java</id>
<goals>
<goal>enforce</goal>
</goals>
<configuration>
<rules>
<requireJavaVersion>
<version>[1.5,)</version>
</requireJavaVersion>
<requireMavenVersion>
<version>[2.1.0,)</version>
</requireMavenVersion>
</rules>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
<extensions>