Issue 61: refactored core S3 to allow different error handling and xml parsing

git-svn-id: http://jclouds.googlecode.com/svn/trunk@1428 3d8758e0-26b5-11de-8745-db77d3ebf521
This commit is contained in:
adrian.f.cole 2009-06-12 16:47:40 +00:00
parent ac8210c90a
commit 09ba1d1360
6 changed files with 129 additions and 129 deletions

View File

@ -44,6 +44,7 @@ import java.util.Properties;
import org.jclouds.aws.s3.config.LiveS3ConnectionModule;
import org.jclouds.aws.s3.config.S3ConnectionModule;
import org.jclouds.aws.s3.config.S3ContextModule;
import org.jclouds.aws.s3.xml.config.S3ParserModule;
import org.jclouds.http.config.HttpFutureCommandClientModule;
import org.jclouds.http.config.JavaUrlHttpFutureCommandClientModule;
import org.jclouds.logging.config.LoggingModule;
@ -73,13 +74,13 @@ import com.google.inject.name.Names;
* @see S3Context
*/
public class S3ContextFactory {
private static final String DEFAULT_SECURE_HTTP_PORT = "443";
private static final String DEFAULT_NON_SECURE_HTTP_PORT = "80";
private final Properties properties;
private final Properties properties;
private final List<Module> modules = new ArrayList<Module>(3);
private S3ContextFactory(Properties properties) {
this.properties = properties;
}
@ -87,9 +88,11 @@ public class S3ContextFactory {
public static S3ContextFactory createContext(String awsAccessKeyId, String awsSecretAccessKey) {
Properties properties = new Properties();
properties.setProperty(PROPERTY_AWS_ACCESSKEYID, checkNotNull(awsAccessKeyId, "awsAccessKeyId"));
properties.setProperty(PROPERTY_AWS_SECRETACCESSKEY, checkNotNull(awsSecretAccessKey,"awsSecretAccessKey"));
properties.setProperty(PROPERTY_AWS_ACCESSKEYID, checkNotNull(awsAccessKeyId,
"awsAccessKeyId"));
properties.setProperty(PROPERTY_AWS_SECRETACCESSKEY, checkNotNull(awsSecretAccessKey,
"awsSecretAccessKey"));
properties.setProperty(PROPERTY_HTTP_ADDRESS, "s3.amazonaws.com");
properties.setProperty(PROPERTY_HTTP_SECURE, "true");
properties.setProperty(PROPERTY_HTTP_MAX_RETRIES, "5");
@ -98,89 +101,68 @@ public class S3ContextFactory {
properties.setProperty(PROPERTY_POOL_REQUEST_INVOKER_THREADS, "1");
properties.setProperty(PROPERTY_POOL_IO_WORKER_THREADS, "2");
properties.setProperty(PROPERTY_POOL_MAX_CONNECTIONS, "12");
return new S3ContextFactory(properties);
}
public S3Context build() {
return createInjector().getInstance(S3Context.class);
}
public static Injector createInjector(String awsAccessKeyId, String awsSecretAccessKey,
Module... modules) {
return createContext(awsAccessKeyId, awsSecretAccessKey)
.withModules(modules)
return createContext(awsAccessKeyId, awsSecretAccessKey).withModules(modules)
.createInjector();
}
public static S3Context createS3Context(String awsAccessKeyId, String awsSecretAccessKey,
Module... modules) {
return createContext(awsAccessKeyId, awsSecretAccessKey)
.withModules(modules)
.build();
return createContext(awsAccessKeyId, awsSecretAccessKey).withModules(modules).build();
}
public static Injector createInjector(String awsAccessKeyId, String awsSecretAccessKey,
boolean isSecure, Module... modules) {
return createContext(awsAccessKeyId, awsSecretAccessKey)
.withModules(modules)
.withHttpSecure(isSecure)
.createInjector();
return createContext(awsAccessKeyId, awsSecretAccessKey).withModules(modules).withHttpSecure(
isSecure).createInjector();
}
public static S3Context createS3Context(String awsAccessKeyId, String awsSecretAccessKey,
boolean isSecure, Module... modules) {
return createContext(awsAccessKeyId, awsSecretAccessKey)
.withModules(modules)
.withHttpSecure(isSecure)
.build();
return createContext(awsAccessKeyId, awsSecretAccessKey).withModules(modules).withHttpSecure(
isSecure).build();
}
public static Injector createInjector(String awsAccessKeyId, String awsSecretAccessKey,
boolean isSecure, String server, Module... modules) {
return createContext(awsAccessKeyId, awsSecretAccessKey)
.withModules(modules)
.withHttpSecure(isSecure)
.withHttpAddress(server)
.createInjector();
return createContext(awsAccessKeyId, awsSecretAccessKey).withModules(modules).withHttpSecure(
isSecure).withHttpAddress(server).createInjector();
}
public static S3Context createS3Context(String awsAccessKeyId, String awsSecretAccessKey,
boolean isSecure, String server, Module... modules) {
return createContext(awsAccessKeyId, awsSecretAccessKey)
.withModules(modules)
.withHttpSecure(isSecure)
.withHttpAddress(server)
.build();
return createContext(awsAccessKeyId, awsSecretAccessKey).withModules(modules).withHttpSecure(
isSecure).withHttpAddress(server).build();
}
public static S3Context createS3Context(String awsAccessKeyId, String awsSecretAccessKey,
boolean isSecure, String server, int port, Module... modules) {
return createContext(awsAccessKeyId, awsSecretAccessKey)
.withModules(modules)
.withHttpSecure(isSecure)
.withHttpAddress(server)
.withHttpPort(port)
.build();
return createContext(awsAccessKeyId, awsSecretAccessKey).withModules(modules).withHttpSecure(
isSecure).withHttpAddress(server).withHttpPort(port).build();
}
public static Injector createInjector(String awsAccessKeyId, String awsSecretAccessKey,
boolean isSecure, String server, int port, Module... modules) {
return createContext(awsAccessKeyId, awsSecretAccessKey)
.withModules(modules)
.withHttpSecure(isSecure)
.withHttpAddress(server)
.withHttpPort(port)
.createInjector();
return createContext(awsAccessKeyId, awsSecretAccessKey).withModules(modules).withHttpSecure(
isSecure).withHttpAddress(server).withHttpPort(port).createInjector();
}
public S3ContextFactory withHttpAddress(String httpAddress) {
properties.setProperty(PROPERTY_HTTP_ADDRESS, httpAddress);
return this;
}
public S3ContextFactory withHttpMaxRetries(int httpMaxRetries) {
properties.setProperty(PROPERTY_HTTP_MAX_RETRIES, Integer.toString(httpMaxRetries));
return this;
@ -197,25 +179,29 @@ public class S3ContextFactory {
}
public S3ContextFactory withPoolMaxConnectionReuse(int poolMaxConnectionReuse) {
properties.setProperty(PROPERTY_POOL_MAX_CONNECTION_REUSE, Integer.toString(poolMaxConnectionReuse));
properties.setProperty(PROPERTY_POOL_MAX_CONNECTION_REUSE, Integer
.toString(poolMaxConnectionReuse));
return this;
}
public S3ContextFactory withPoolMaxSessionFailures(int poolMaxSessionFailures) {
properties.setProperty(PROPERTY_POOL_MAX_SESSION_FAILURES, Integer.toString(poolMaxSessionFailures));
properties.setProperty(PROPERTY_POOL_MAX_SESSION_FAILURES, Integer
.toString(poolMaxSessionFailures));
return this;
}
public S3ContextFactory withPoolRequestInvokerThreads(int poolRequestInvokerThreads) {
properties.setProperty(PROPERTY_POOL_REQUEST_INVOKER_THREADS, Integer.toString(poolRequestInvokerThreads));
properties.setProperty(PROPERTY_POOL_REQUEST_INVOKER_THREADS, Integer
.toString(poolRequestInvokerThreads));
return this;
}
public S3ContextFactory withPoolIoWorkerThreads(int poolIoWorkerThreads) {
properties.setProperty(PROPERTY_POOL_IO_WORKER_THREADS, Integer.toString(poolIoWorkerThreads));
properties
.setProperty(PROPERTY_POOL_IO_WORKER_THREADS, Integer.toString(poolIoWorkerThreads));
return this;
}
@ -224,30 +210,32 @@ public class S3ContextFactory {
properties.setProperty(PROPERTY_POOL_MAX_CONNECTIONS, Integer.toString(poolMaxConnections));
return this;
}
public S3ContextFactory withModule(Module module) {
modules.add(module);
return this;
}
public S3ContextFactory withModules(Module... modules) {
this.modules.addAll(Arrays.asList(modules));
return this;
}
private Injector createInjector() {
/* Use 80 or 443 as the default port if one hasn't been set? */
if(!properties.containsKey(PROPERTY_HTTP_PORT)) {
if(Boolean.parseBoolean(properties.getProperty(PROPERTY_HTTP_SECURE))) {
if (!properties.containsKey(PROPERTY_HTTP_PORT)) {
if (Boolean.parseBoolean(properties.getProperty(PROPERTY_HTTP_SECURE))) {
properties.setProperty(PROPERTY_HTTP_PORT, DEFAULT_SECURE_HTTP_PORT);
} else {
properties.setProperty(PROPERTY_HTTP_PORT, DEFAULT_NON_SECURE_HTTP_PORT);
}
}
addLoggingModuleIfNotPresent(modules);
addS3ParserModuleIfNotPresent(modules);
addS3ConnectionModuleIfNotPresent(modules);
addHttpModuleIfNeededAndNotPresent(modules);
@ -262,6 +250,16 @@ public class S3ContextFactory {
}, new S3ContextModule());
}
@VisibleForTesting
static void addS3ParserModuleIfNotPresent(List<Module> modules) {
if (!Iterables.any(modules, new Predicate<Module>() {
public boolean apply(Module input) {
return input instanceof S3ParserModule;
}
}))
modules.add(new S3ParserModule());
}
@VisibleForTesting
static void addHttpModuleIfNeededAndNotPresent(final List<Module> modules) {

View File

@ -31,7 +31,6 @@ import org.jclouds.aws.s3.commands.HeadObject;
import org.jclouds.aws.s3.commands.PutBucket;
import org.jclouds.aws.s3.commands.PutObject;
import org.jclouds.aws.s3.commands.S3CommandFactory;
import org.jclouds.aws.s3.xml.config.S3ParserModule;
import com.google.inject.AbstractModule;
import com.google.inject.assistedinject.FactoryProvider;
@ -42,45 +41,40 @@ import com.google.inject.assistedinject.FactoryProvider;
* @author Adrian Cole
*/
public class S3CommandsModule extends AbstractModule {
@Override
protected void configure() {
install(new S3ParserModule());
@Override
protected void configure() {
bind(S3CommandFactory.DeleteBucketFactory.class).toProvider(
FactoryProvider.newFactory(
S3CommandFactory.DeleteBucketFactory.class,
DeleteBucket.class));
bind(S3CommandFactory.DeleteBucketFactory.class).toProvider(
FactoryProvider.newFactory(S3CommandFactory.DeleteBucketFactory.class,
DeleteBucket.class));
bind(S3CommandFactory.DeleteObjectFactory.class).toProvider(
FactoryProvider.newFactory(
S3CommandFactory.DeleteObjectFactory.class,
DeleteObject.class));
bind(S3CommandFactory.DeleteObjectFactory.class).toProvider(
FactoryProvider.newFactory(S3CommandFactory.DeleteObjectFactory.class,
DeleteObject.class));
bind(S3CommandFactory.BucketExistsFactory.class).toProvider(
FactoryProvider.newFactory(
S3CommandFactory.BucketExistsFactory.class,
BucketExists.class));
bind(S3CommandFactory.BucketExistsFactory.class).toProvider(
FactoryProvider.newFactory(S3CommandFactory.BucketExistsFactory.class,
BucketExists.class));
bind(S3CommandFactory.PutBucketFactory.class).toProvider(
FactoryProvider.newFactory(
S3CommandFactory.PutBucketFactory.class,
PutBucket.class));
bind(S3CommandFactory.PutBucketFactory.class)
.toProvider(
FactoryProvider.newFactory(S3CommandFactory.PutBucketFactory.class,
PutBucket.class));
bind(S3CommandFactory.PutObjectFactory.class).toProvider(
FactoryProvider.newFactory(
S3CommandFactory.PutObjectFactory.class,
PutObject.class));
bind(S3CommandFactory.PutObjectFactory.class)
.toProvider(
FactoryProvider.newFactory(S3CommandFactory.PutObjectFactory.class,
PutObject.class));
bind(S3CommandFactory.GetObjectFactory.class).toProvider(
FactoryProvider.newFactory(
S3CommandFactory.GetObjectFactory.class,
GetObject.class));
bind(S3CommandFactory.GetObjectFactory.class)
.toProvider(
FactoryProvider.newFactory(S3CommandFactory.GetObjectFactory.class,
GetObject.class));
bind(S3CommandFactory.HeadMetadataFactory.class).toProvider(
FactoryProvider.newFactory(
S3CommandFactory.HeadMetadataFactory.class,
HeadObject.class));
bind(S3CommandFactory.HeadMetadataFactory.class).toProvider(
FactoryProvider.newFactory(S3CommandFactory.HeadMetadataFactory.class,
HeadObject.class));
}
}
}

View File

@ -73,17 +73,22 @@ public class LiveS3ConnectionModule extends AbstractModule {
@Override
protected void configure() {
bindResponseHandlers();
bind(S3Connection.class).to(LiveS3Connection.class).in(Scopes.SINGLETON);
bind(HttpRetryHandler.class).annotatedWith(RetryHandler.class).to(
BackoffLimitedRetryHandler.class).in(Scopes.SINGLETON);
requestInjection(this);
logger.info("S3 Context = %1$s://%2$s:%3$s", (isSecure ? "https" : "http"), address, port);
}
protected void bindResponseHandlers() {
bind(HttpResponseHandler.class).annotatedWith(RedirectHandler.class).to(
CloseContentAndSetExceptionHandler.class).in(Scopes.SINGLETON);
bind(HttpResponseHandler.class).annotatedWith(ClientErrorHandler.class).to(
ParseAWSErrorFromXmlContent.class).in(Scopes.SINGLETON);
bind(HttpResponseHandler.class).annotatedWith(ServerErrorHandler.class).to(
ParseAWSErrorFromXmlContent.class).in(Scopes.SINGLETON);
bind(HttpRetryHandler.class).annotatedWith(RetryHandler.class).to(
BackoffLimitedRetryHandler.class).in(Scopes.SINGLETON);
requestInjection(this);
logger.info("S3 Context = %1$s://%2$s:%3$s", (isSecure ? "https" : "http"), address, port);
}
@Provides

View File

@ -48,34 +48,30 @@ import com.google.inject.assistedinject.FactoryProvider;
* @author Adrian Cole
*/
public class S3ParserModule extends AbstractModule {
private final TypeLiteral<S3ParserFactory.GenericParseFactory
<List<S3Bucket.Metadata>>> listBucketsTypeLiteral =
new TypeLiteral<S3ParserFactory.GenericParseFactory<List<S3Bucket.Metadata>>>() {
protected final TypeLiteral<S3ParserFactory.GenericParseFactory<AWSError>> errorTypeLiteral = new TypeLiteral<S3ParserFactory.GenericParseFactory<AWSError>>() {
};
private final TypeLiteral<S3ParserFactory.GenericParseFactory
<S3Bucket>> bucketTypeLiteral =
new TypeLiteral<S3ParserFactory.GenericParseFactory<S3Bucket>>() {
protected final TypeLiteral<S3ParserFactory.GenericParseFactory<List<S3Bucket.Metadata>>> listBucketsTypeLiteral = new TypeLiteral<S3ParserFactory.GenericParseFactory<List<S3Bucket.Metadata>>>() {
};
private final TypeLiteral<S3ParserFactory.GenericParseFactory
<S3Object.Metadata>> objectMetadataTypeLiteral =
new TypeLiteral<S3ParserFactory.GenericParseFactory<S3Object.Metadata>>() {
protected final TypeLiteral<S3ParserFactory.GenericParseFactory<S3Bucket>> bucketTypeLiteral = new TypeLiteral<S3ParserFactory.GenericParseFactory<S3Bucket>>() {
};
private final TypeLiteral<S3ParserFactory.GenericParseFactory
<AWSError>> errorTypeLiteral =
new TypeLiteral<S3ParserFactory.GenericParseFactory<AWSError>>() {
protected final TypeLiteral<S3ParserFactory.GenericParseFactory<S3Object.Metadata>> objectMetadataTypeLiteral = new TypeLiteral<S3ParserFactory.GenericParseFactory<S3Object.Metadata>>() {
};
private final TypeLiteral<S3ParserFactory.GenericParseFactory
<AccessControlList>> accessControlListTypeLiteral =
new TypeLiteral<S3ParserFactory.GenericParseFactory<AccessControlList>>() {
protected final TypeLiteral<S3ParserFactory.GenericParseFactory<AccessControlList>> accessControlListTypeLiteral = new TypeLiteral<S3ParserFactory.GenericParseFactory<AccessControlList>>() {
};
@Override
protected void configure() {
install(new SaxModule());
bindErrorHandler();
bindCallablesThatReturnParseResults();
bindParserImplementationsToReturnTypes();
}
protected void bindErrorHandler() {
bind(new TypeLiteral<ParseSax.HandlerWithResult<AWSError>>() {
}).to(ErrorHandler.class);
}
private void bindParserImplementationsToReturnTypes() {
bind(new TypeLiteral<ParseSax.HandlerWithResult<List<S3Bucket.Metadata>>>() {
}).to(ListAllMyBucketsHandler.class);
@ -83,8 +79,6 @@ public class S3ParserModule extends AbstractModule {
}).to(ListBucketHandler.class);
bind(new TypeLiteral<ParseSax.HandlerWithResult<S3Object.Metadata>>() {
}).to(CopyObjectHandler.class);
bind(new TypeLiteral<ParseSax.HandlerWithResult<AWSError>>() {
}).to(ErrorHandler.class);
bind(new TypeLiteral<ParseSax.HandlerWithResult<AccessControlList>>() {
}).to(AccessControlListHandler.class);
}
@ -101,12 +95,13 @@ public class S3ParserModule extends AbstractModule {
FactoryProvider.newFactory(objectMetadataTypeLiteral,
new TypeLiteral<ParseSax<S3Object.Metadata>>() {
}));
bind(accessControlListTypeLiteral).toProvider(
FactoryProvider.newFactory(accessControlListTypeLiteral,
new TypeLiteral<ParseSax<AccessControlList>>() {
}));
bind(errorTypeLiteral).toProvider(
FactoryProvider.newFactory(errorTypeLiteral, new TypeLiteral<ParseSax<AWSError>>() {
}));
bind(accessControlListTypeLiteral).toProvider(
FactoryProvider.newFactory(accessControlListTypeLiteral,
new TypeLiteral<ParseSax<AccessControlList>>() {}));
}
}

View File

@ -35,6 +35,7 @@ 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.jclouds.aws.s3.xml.config.S3ParserModule;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
@ -56,7 +57,7 @@ public class S3CommandFactoryTest {
@BeforeTest
void setUpInjector() {
injector = Guice.createInjector(new S3CommandsModule() {
injector = Guice.createInjector(new S3ParserModule(), new S3CommandsModule() {
@Override
protected void configure() {
bindConstant().annotatedWith(Names.named("jclouds.http.address")).to("localhost");

View File

@ -27,6 +27,7 @@ import static org.testng.Assert.assertEquals;
import org.jclouds.aws.s3.handlers.ParseAWSErrorFromXmlContent;
import org.jclouds.aws.s3.reference.S3Constants;
import org.jclouds.aws.s3.xml.config.S3ParserModule;
import org.jclouds.http.HttpResponseHandler;
import org.jclouds.http.HttpRetryHandler;
import org.jclouds.http.annotation.ClientErrorHandler;
@ -50,21 +51,27 @@ import com.google.inject.name.Names;
public class S3ContextModuleTest {
Injector createInjector() {
return 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");
bindConstant().annotatedWith(Names.named(S3Constants.PROPERTY_HTTP_MAX_RETRIES)).to("5");
super.configure();
}
}, new JavaUrlHttpFutureCommandClientModule());
return Guice.createInjector(new LiveS3ConnectionModule(), new S3ParserModule(),
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");
bindConstant().annotatedWith(
Names.named(S3Constants.PROPERTY_HTTP_MAX_RETRIES)).to("5");
super.configure();
}
}, new JavaUrlHttpFutureCommandClientModule());
}
private static class ClientErrorHandlerTest {