Issue 73: created module for object storage

git-svn-id: http://jclouds.googlecode.com/svn/trunk@1604 3d8758e0-26b5-11de-8745-db77d3ebf521
This commit is contained in:
adrian.f.cole 2009-07-05 21:24:22 +00:00
parent e5bc2dd5e7
commit f86e06f3d8
38 changed files with 1091 additions and 598 deletions

View File

@ -23,11 +23,13 @@
*/
package org.jclouds.aws.s3;
import org.jclouds.cloud.CloudContext;
/**
* Represents an authenticated context to S3.
*
* <h2>Note</h2> Please issue {@link #close()} when you are finished with this
* context in order to release resources.
* <h2>Note</h2> Please issue {@link #close()} when you are finished with this context in order to
* release resources.
*
*
* @see S3Connection
@ -36,18 +38,10 @@ package org.jclouds.aws.s3;
* @author Adrian Cole
*
*/
public interface S3Context {
public interface S3Context extends CloudContext<S3Connection> {
/**
* low-level api to S3. Threadsafe implementations will return a singleton.
*
* @return a connection to S3
*/
S3Connection getConnection();
/**
* Creates a <code>Map<String,InputStream></code> view of the specified
* bucket.
* Creates a <code>Map<String,InputStream></code> view of the specified bucket.
*
* @param bucket
*/
@ -60,9 +54,4 @@ public interface S3Context {
*/
S3ObjectMap createS3ObjectMap(String bucket);
/**
* Closes all connections to S3.
*/
void close();
}

View File

@ -0,0 +1,113 @@
/**
*
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*/
package org.jclouds.aws.s3;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.jclouds.aws.reference.AWSConstants.PROPERTY_AWS_ACCESSKEYID;
import static org.jclouds.aws.reference.AWSConstants.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_MAX_REDIRECTS;
import static org.jclouds.http.HttpConstants.PROPERTY_HTTP_MAX_RETRIES;
import static org.jclouds.http.HttpConstants.PROPERTY_HTTP_SECURE;
import static org.jclouds.http.HttpConstants.PROPERTY_SAX_DEBUG;
import java.util.List;
import java.util.Properties;
import org.jclouds.aws.s3.config.LiveS3ConnectionModule;
import org.jclouds.aws.s3.config.S3ContextModule;
import org.jclouds.aws.s3.xml.config.S3ParserModule;
import org.jclouds.cloud.CloudContextBuilder;
import org.jclouds.http.config.JavaUrlHttpFutureCommandClientModule;
import org.jclouds.logging.jdk.config.JDKLoggingModule;
import com.google.inject.Injector;
import com.google.inject.Module;
/**
* Creates {@link S3Context} or {@link Injector} instances based on the most commonly requested
* arguments.
* <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.
*
* @author Adrian Cole, Andrew Newdigate
* @see S3Context
*/
public class S3ContextBuilder extends CloudContextBuilder<S3Connection, S3Context> {
public S3ContextBuilder(Properties props) {
super(props);
}
public static S3ContextBuilder newBuilder(String id, String secret) {
Properties properties = new Properties();
properties.setProperty(PROPERTY_HTTP_ADDRESS, "s3.amazonaws.com");
properties.setProperty(PROPERTY_SAX_DEBUG, "false");
properties.setProperty(PROPERTY_HTTP_SECURE, "true");
properties.setProperty(PROPERTY_HTTP_MAX_RETRIES, "5");
properties.setProperty(PROPERTY_HTTP_MAX_REDIRECTS, "5");
properties.setProperty(PROPERTY_POOL_MAX_CONNECTION_REUSE, "75");
properties.setProperty(PROPERTY_POOL_MAX_SESSION_FAILURES, "2");
properties.setProperty(PROPERTY_POOL_REQUEST_INVOKER_THREADS, "1");
properties.setProperty(PROPERTY_POOL_IO_WORKER_THREADS, "2");
properties.setProperty(PROPERTY_POOL_MAX_CONNECTIONS, "12");
S3ContextBuilder builder = new S3ContextBuilder(properties);
builder.authenticate(id, secret);
return builder;
}
public void authenticate(String id, String secret) {
properties.setProperty(PROPERTY_AWS_ACCESSKEYID, checkNotNull(id, "awsAccessKeyId"));
properties.setProperty(PROPERTY_AWS_SECRETACCESSKEY, checkNotNull(secret,
"awsSecretAccessKey"));
}
public S3Context buildContext() {
return buildInjector().getInstance(S3Context.class);
}
protected void addParserModule(List<Module> modules) {
modules.add(new S3ParserModule());
}
protected void addContextModule(List<Module> modules) {
modules.add(new S3ContextModule());
}
protected void addConnectionModule(List<Module> modules) {
modules.add(new LiveS3ConnectionModule());
}
}

View File

@ -23,47 +23,13 @@
*/
package org.jclouds.aws.s3;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.jclouds.aws.reference.AWSConstants.PROPERTY_AWS_ACCESSKEYID;
import static org.jclouds.aws.reference.AWSConstants.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_MAX_REDIRECTS;
import static org.jclouds.http.HttpConstants.PROPERTY_HTTP_MAX_RETRIES;
import static org.jclouds.http.HttpConstants.PROPERTY_HTTP_PORT;
import static org.jclouds.http.HttpConstants.PROPERTY_HTTP_SECURE;
import static org.jclouds.http.HttpConstants.PROPERTY_SAX_DEBUG;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
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;
import org.jclouds.logging.jdk.config.JDKLoggingModule;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.collect.Iterables;
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Module;
import com.google.inject.name.Names;
/**
* Creates {@link S3Context} or {@link Injector} instances based on the most commonly requested
* Creates {@link S3Context} instances based on the most commonly requested
* arguments.
* <p/>
* Note that Threadsafe objects will be bound as singletons to the Injector or Context provided.
@ -77,245 +43,10 @@ import com.google.inject.name.Names;
*/
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 List<Module> modules = new ArrayList<Module>(3);
private S3ContextFactory(Properties properties) {
this.properties = properties;
}
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_SAX_DEBUG, "false");
properties.setProperty(PROPERTY_HTTP_ADDRESS, "s3.amazonaws.com");
properties.setProperty(PROPERTY_HTTP_SECURE, "true");
properties.setProperty(PROPERTY_HTTP_MAX_RETRIES, "5");
properties.setProperty(PROPERTY_HTTP_MAX_REDIRECTS, "5");
properties.setProperty(PROPERTY_POOL_MAX_CONNECTION_REUSE, "75");
properties.setProperty(PROPERTY_POOL_MAX_SESSION_FAILURES, "2");
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)
.createInjector();
}
public static S3Context createS3Context(String awsAccessKeyId, String awsSecretAccessKey,
Module... modules) {
return createContext(awsAccessKeyId, awsSecretAccessKey).withModules(modules).build();
return S3ContextBuilder.newBuilder(awsAccessKeyId, awsSecretAccessKey).withModules(modules)
.buildContext();
}
public static Injector createInjector(String awsAccessKeyId, String awsSecretAccessKey,
boolean isSecure, Module... modules) {
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();
}
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();
}
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();
}
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();
}
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();
}
public S3ContextFactory withHttpAddress(String httpAddress) {
properties.setProperty(PROPERTY_HTTP_ADDRESS, httpAddress);
return this;
}
public S3ContextFactory withSaxDebug() {
properties.setProperty(PROPERTY_SAX_DEBUG, "true");
return this;
}
public S3ContextFactory withHttpMaxRetries(int httpMaxRetries) {
properties.setProperty(PROPERTY_HTTP_MAX_RETRIES, Integer.toString(httpMaxRetries));
return this;
}
public S3ContextFactory withHttpMaxRedirects(int httpMaxRedirects) {
properties.setProperty(PROPERTY_HTTP_MAX_REDIRECTS, Integer.toString(httpMaxRedirects));
return this;
}
public S3ContextFactory withHttpPort(int httpPort) {
properties.setProperty(PROPERTY_HTTP_PORT, Integer.toString(httpPort));
return this;
}
public S3ContextFactory withHttpSecure(boolean httpSecure) {
properties.setProperty(PROPERTY_HTTP_SECURE, Boolean.toString(httpSecure));
return this;
}
public S3ContextFactory withPoolMaxConnectionReuse(int 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));
return this;
}
public S3ContextFactory withPoolRequestInvokerThreads(int 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));
return this;
}
public S3ContextFactory withPoolMaxConnections(int poolMaxConnections) {
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() {
useDefaultPortIfNotPresent(properties);
addLoggingModuleIfNotPresent(modules);
addS3ParserModuleIfNotPresent(modules);
addS3ConnectionModuleIfNotPresent(modules);
addHttpModuleIfNeededAndNotPresent(modules);
modules.add(new AbstractModule() {
@Override
protected void configure() {
Names.bindProperties(binder(), checkNotNull(properties, "properties"));
}
});
modules.add(new S3ContextModule());
return Guice.createInjector(modules);
}
private void useDefaultPortIfNotPresent(Properties properties) {
/* 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))) {
properties.setProperty(PROPERTY_HTTP_PORT, DEFAULT_SECURE_HTTP_PORT);
} else {
properties.setProperty(PROPERTY_HTTP_PORT, DEFAULT_NON_SECURE_HTTP_PORT);
}
}
}
@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) {
if (Iterables.any(modules, new Predicate<Module>() {
public boolean apply(Module input) {
return input instanceof LiveS3ConnectionModule;
}
}) && (!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(0, new LiveS3ConnectionModule());
}
}
@VisibleForTesting
static void addLoggingModuleIfNotPresent(final List<Module> modules) {
if (!Iterables.any(modules, Predicates.instanceOf(LoggingModule.class)))
modules.add(new JDKLoggingModule());
}
@VisibleForTesting
Properties getProperties() {
return properties;
}
}

View File

@ -36,10 +36,12 @@ import org.jclouds.aws.s3.handlers.AWSClientErrorRetryHandler;
import org.jclouds.aws.s3.handlers.AWSRedirectionRetryHandler;
import org.jclouds.aws.s3.handlers.ParseAWSErrorFromXmlContent;
import org.jclouds.aws.s3.internal.LiveS3Connection;
import org.jclouds.cloud.ConfiguresCloudConnection;
import org.jclouds.http.HttpConstants;
import org.jclouds.http.HttpErrorHandler;
import org.jclouds.http.HttpRequestFilter;
import org.jclouds.http.HttpRetryHandler;
import org.jclouds.http.RequiresHttp;
import org.jclouds.http.annotation.ClientError;
import org.jclouds.http.annotation.Redirection;
import org.jclouds.http.annotation.ServerError;
@ -57,7 +59,8 @@ import com.google.inject.name.Named;
*
* @author Adrian Cole
*/
@S3ConnectionModule
@ConfiguresCloudConnection
@RequiresHttp
public class LiveS3ConnectionModule extends AbstractModule {
@Resource
protected Logger logger = Logger.NULL;

View File

@ -68,14 +68,14 @@ public abstract class BaseS3Map<V> implements S3Map<String, V> {
* maximum duration of an S3 Request
*/
@Inject(optional = true)
@Named(S3Constants.PROPERTY_S3_MAP_TIMEOUT)
@Named(S3Constants.PROPERTY_OBJECTMAP_TIMEOUT)
protected long requestTimeoutMilliseconds = 10000;
/**
* time to pause before retrying a transient failure
*/
@Inject(optional = true)
@Named(S3Constants.PROPERTY_S3_MAP_RETRY)
@Named(S3Constants.PROPERTY_OBJECTMAP_RETRY)
protected long requestRetryMilliseconds = 10;
@Inject

View File

@ -24,22 +24,14 @@
package org.jclouds.aws.s3.reference;
import org.jclouds.aws.reference.AWSConstants;
import org.jclouds.objectstore.reference.ObjectStoreConstants;
/**
* Configuration properties and constants used in S3 connections.
*
* @author Adrian Cole
*/
public interface S3Constants extends AWSConstants, S3Headers {
/**
* longest time a single Map operation can take before throwing an exception.
*/
public static final String PROPERTY_S3_MAP_TIMEOUT = "jclouds.s3.map.timeout";
/**
* time to pause before retrying a transient failure
*/
public static final String PROPERTY_S3_MAP_RETRY = "jclouds.s3.map.retry";
public interface S3Constants extends AWSConstants, S3Headers, ObjectStoreConstants {
/**
* S3 service's XML Namespace, as used in XML request and response documents.

View File

@ -35,6 +35,7 @@ import org.jclouds.aws.s3.xml.ListAllMyBucketsHandler;
import org.jclouds.aws.s3.xml.ListBucketHandler;
import org.jclouds.aws.s3.xml.S3ParserFactory;
import org.jclouds.aws.xml.ErrorHandler;
import org.jclouds.command.ConfiguresResponseParser;
import org.jclouds.http.commands.callables.xml.ParseSax;
import org.jclouds.http.commands.callables.xml.config.SaxModule;
@ -47,6 +48,7 @@ import com.google.inject.assistedinject.FactoryProvider;
*
* @author Adrian Cole
*/
@ConfiguresResponseParser
public class S3ParserModule extends AbstractModule {
protected final TypeLiteral<S3ParserFactory.GenericParseFactory<AWSError>> errorTypeLiteral = new TypeLiteral<S3ParserFactory.GenericParseFactory<AWSError>>() {
};

View File

@ -0,0 +1,94 @@
/**
*
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*/
package org.jclouds.aws.s3;
import static org.jclouds.aws.reference.AWSConstants.PROPERTY_AWS_ACCESSKEYID;
import static org.jclouds.aws.reference.AWSConstants.PROPERTY_AWS_SECRETACCESSKEY;
import static org.jclouds.http.HttpConstants.PROPERTY_HTTP_ADDRESS;
import static org.testng.Assert.assertEquals;
import java.util.ArrayList;
import java.util.List;
import org.jclouds.aws.s3.config.LiveS3ConnectionModule;
import org.jclouds.aws.s3.config.S3ContextModule;
import org.jclouds.aws.s3.internal.GuiceS3Context;
import org.jclouds.aws.s3.xml.config.S3ParserModule;
import org.jclouds.cloud.CloudContext;
import org.testng.annotations.Test;
import com.google.inject.Injector;
import com.google.inject.Module;
/**
* Tests behavior of modules configured in S3ContextBuilder
*
* @author Adrian Cole
*/
@Test(groups = "unit", testName = "s3.S3ContextBuilderTest")
public class S3ContextBuilderTest {
public void testNewBuilder() {
S3ContextBuilder builder = S3ContextBuilder.newBuilder("id", "secret");
assertEquals(builder.getProperties().getProperty(PROPERTY_HTTP_ADDRESS), "s3.amazonaws.com");
assertEquals(builder.getProperties().getProperty(PROPERTY_AWS_ACCESSKEYID), "id");
assertEquals(builder.getProperties().getProperty(PROPERTY_AWS_SECRETACCESSKEY), "secret");
}
public void testBuildContext() {
CloudContext<S3Connection> context = S3ContextBuilder.newBuilder("id", "secret")
.buildContext();
assertEquals(context.getClass(), GuiceS3Context.class);
}
public void testBuildInjector() {
Injector i = S3ContextBuilder.newBuilder("id", "secret").buildInjector();
assert i.getInstance(S3Context.class) != null;
}
protected void testAddParserModule() {
List<Module> modules = new ArrayList<Module>();
S3ContextBuilder builder = S3ContextBuilder.newBuilder("id", "secret");
builder.addParserModule(modules);
assertEquals(modules.size(), 1);
assertEquals(modules.get(0).getClass(), S3ParserModule.class);
}
protected void testAddContextModule() {
List<Module> modules = new ArrayList<Module>();
S3ContextBuilder builder = S3ContextBuilder.newBuilder("id", "secret");
builder.addContextModule(modules);
assertEquals(modules.size(), 1);
assertEquals(modules.get(0).getClass(), S3ContextModule.class);
}
protected void addConnectionModule() {
List<Module> modules = new ArrayList<Module>();
S3ContextBuilder builder = S3ContextBuilder.newBuilder("id", "secret");
builder.addConnectionModule(modules);
assertEquals(modules.size(), 1);
assertEquals(modules.get(0).getClass(), LiveS3ConnectionModule.class);
}
}

View File

@ -174,14 +174,13 @@ public class S3IntegrationTest {
}
protected void createStubS3Context() {
context = S3ContextFactory.createContext("stub", "stub").withHttpAddress("stub").withModule(
new StubS3ConnectionModule()).build();
context = S3ContextFactory.createS3Context("stub", "stub", new StubS3ConnectionModule());
SANITY_CHECK_RETURNED_BUCKET_NAME = true;
}
protected void createLiveS3Context(String AWSAccessKeyId, String AWSSecretAccessKey) {
context = buildS3ContextFactory(AWSAccessKeyId, AWSSecretAccessKey).withModule(
createHttpModule()).withModule(new Log4JLoggingModule()).build();
context = S3ContextFactory.createS3Context(AWSAccessKeyId, AWSSecretAccessKey,
createHttpModule(), new Log4JLoggingModule());
}
public String getBucketName() throws InterruptedException, ExecutionException, TimeoutException {
@ -261,9 +260,9 @@ public class S3IntegrationTest {
}
}
protected S3ContextFactory buildS3ContextFactory(String AWSAccessKeyId, String AWSSecretAccessKey) {
return S3ContextFactory.createContext(AWSAccessKeyId, AWSSecretAccessKey).withSaxDebug()
.withHttpSecure(false).withHttpPort(80);
protected S3ContextBuilder buildS3ContextFactory(String AWSAccessKeyId, String AWSSecretAccessKey) {
return (S3ContextBuilder) S3ContextBuilder.newBuilder(AWSAccessKeyId, AWSSecretAccessKey)
.withSaxDebug().withHttpSecure(false).withHttpPort(80);
}
protected Module createHttpModule() {

View File

@ -33,11 +33,9 @@ import org.testng.annotations.Test;
@Test(groups = { "live" }, testName = "s3.SecureS3ConnectionLiveTest")
public class SecureS3ConnectionLiveTest extends S3ConnectionLiveTest {
@Override
protected S3ContextFactory buildS3ContextFactory(String AWSAccessKeyId,
String AWSSecretAccessKey) {
return S3ContextFactory.createContext(AWSAccessKeyId, AWSSecretAccessKey)
.withHttpSecure(true)
.withHttpPort(443);
protected S3ContextBuilder buildS3ContextFactory(String AWSAccessKeyId, String AWSSecretAccessKey) {
return (S3ContextBuilder) S3ContextBuilder.newBuilder(AWSAccessKeyId, AWSSecretAccessKey)
.withHttpSecure(true).withHttpPort(443);
}
}

View File

@ -26,21 +26,16 @@ package org.jclouds.aws.s3.commands.callables;
import static org.easymock.EasyMock.expect;
import static org.easymock.classextension.EasyMock.createMock;
import static org.easymock.classextension.EasyMock.replay;
import static org.easymock.classextension.EasyMock.reset;
import static org.testng.Assert.assertEquals;
import org.apache.commons.io.IOUtils;
import org.jclouds.aws.s3.domain.S3Object;
import org.jclouds.aws.s3.domain.S3Object.Metadata;
import org.jclouds.aws.util.DateService;
import org.jclouds.http.HttpException;
import org.jclouds.http.HttpHeaders;
import org.jclouds.http.HttpResponse;
import org.testng.annotations.Test;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;
/**
* @author Adrian Cole
*/
@ -92,21 +87,4 @@ public class ParseObjectFromHeadersAndHttpContentTest {
}
private void buildDefaultResponseMock(HttpResponse response) {
reset(response);
// Headers required for the parse classes to work, but we don't care about this data.
String data = "test data";
expect(response.getStatusCode()).andReturn(200).atLeastOnce();
Multimap<String, String> emptyHeaders = HashMultimap.create();
expect(response.getHeaders()).andReturn(emptyHeaders).atLeastOnce();
expect(response.getContent()).andReturn(IOUtils.toInputStream(data)).atLeastOnce();
expect(response.getFirstHeaderOrNull(HttpHeaders.LAST_MODIFIED))
.andReturn(new DateService().rfc822DateFormat()).atLeastOnce();
expect(response.getFirstHeaderOrNull(HttpHeaders.CONTENT_TYPE))
.andReturn("text/plain").atLeastOnce();
expect(response.getFirstHeaderOrNull(HttpHeaders.CONTENT_LENGTH))
.andReturn("" + data.length()).atLeastOnce();
}
}

View File

@ -27,6 +27,7 @@ import java.net.URI;
import org.jclouds.aws.s3.S3Connection;
import org.jclouds.aws.s3.internal.StubS3Connection;
import org.jclouds.cloud.ConfiguresCloudConnection;
import com.google.inject.AbstractModule;
@ -35,7 +36,7 @@ import com.google.inject.AbstractModule;
*
* @author Adrian Cole
*/
@S3ConnectionModule
@ConfiguresCloudConnection
public class StubS3ConnectionModule extends AbstractModule {
protected void configure() {
bind(S3Connection.class).to(StubS3Connection.class);

View File

@ -33,7 +33,7 @@ import java.util.concurrent.TimeUnit;
import org.jclouds.aws.s3.S3Connection;
import org.jclouds.aws.s3.S3Context;
import org.jclouds.aws.s3.S3ContextFactory;
import org.jclouds.aws.s3.S3ContextBuilder;
import org.jclouds.aws.s3.commands.options.CopyObjectOptions;
import org.jclouds.aws.s3.commands.options.GetObjectOptions;
import org.jclouds.aws.s3.commands.options.ListBucketOptions;
@ -79,8 +79,8 @@ public class JCloudsS3Service extends S3Service {
protected JCloudsS3Service(AWSCredentials awsCredentials, Module... modules)
throws S3ServiceException {
super(awsCredentials);
context = S3ContextFactory.createS3Context(awsCredentials.getAccessKey(), awsCredentials
.getSecretKey(), modules);
context = S3ContextBuilder.newBuilder(awsCredentials.getAccessKey(),
awsCredentials.getSecretKey()).withModules(modules).buildContext();
connection = context.getConnection();
}
@ -98,16 +98,13 @@ public class JCloudsS3Service extends S3Service {
protected Map copyObjectImpl(String sourceBucketName, String sourceObjectKey,
String destinationBucketName, String destinationObjectKey, AccessControlList acl,
Map destinationMetadata, Calendar ifModifiedSince, Calendar ifUnmodifiedSince,
String[] ifMatchTags, String[] ifNoneMatchTags) throws S3ServiceException
{
String[] ifMatchTags, String[] ifNoneMatchTags) throws S3ServiceException {
try {
CopyObjectOptions options = Util.convertCopyObjectOptions(acl,
destinationMetadata, ifModifiedSince, ifUnmodifiedSince,
ifMatchTags, ifNoneMatchTags);
org.jclouds.aws.s3.domain.S3Object.Metadata jcObjectMetadata =
connection.copyObject(sourceBucketName, sourceObjectKey,
destinationBucketName, destinationObjectKey, options)
.get(requestTimeoutMilliseconds, TimeUnit.MILLISECONDS);
CopyObjectOptions options = Util.convertCopyObjectOptions(acl, destinationMetadata,
ifModifiedSince, ifUnmodifiedSince, ifMatchTags, ifNoneMatchTags);
org.jclouds.aws.s3.domain.S3Object.Metadata jcObjectMetadata = connection.copyObject(
sourceBucketName, sourceObjectKey, destinationBucketName, destinationObjectKey,
options).get(requestTimeoutMilliseconds, TimeUnit.MILLISECONDS);
Map map = new HashMap();
// Result fields returned when copy is successful.
@ -129,8 +126,8 @@ public class JCloudsS3Service extends S3Service {
throw new UnsupportedOperationException("Bucket ACL is not yet supported");
try {
if (connection.putBucketIfNotExists(bucketName)
.get(requestTimeoutMilliseconds, TimeUnit.MILLISECONDS)) {
if (connection.putBucketIfNotExists(bucketName).get(requestTimeoutMilliseconds,
TimeUnit.MILLISECONDS)) {
// Bucket created.
}
} catch (Exception e) {
@ -176,8 +173,7 @@ public class JCloudsS3Service extends S3Service {
@Override
protected AccessControlList getBucketAclImpl(String bucketName) throws S3ServiceException {
try {
org.jclouds.aws.s3.domain.AccessControlList jcACL =
connection.getBucketACL(bucketName)
org.jclouds.aws.s3.domain.AccessControlList jcACL = connection.getBucketACL(bucketName)
.get(requestTimeoutMilliseconds, TimeUnit.MILLISECONDS);
return Util.convertAccessControlList(jcACL);
} catch (Exception e) {
@ -203,9 +199,8 @@ public class JCloudsS3Service extends S3Service {
protected AccessControlList getObjectAclImpl(String bucketName, String objectKey)
throws S3ServiceException {
try {
org.jclouds.aws.s3.domain.AccessControlList jcACL =
connection.getObjectACL(bucketName, objectKey)
.get(requestTimeoutMilliseconds,TimeUnit.MILLISECONDS);
org.jclouds.aws.s3.domain.AccessControlList jcACL = connection.getObjectACL(bucketName,
objectKey).get(requestTimeoutMilliseconds, TimeUnit.MILLISECONDS);
return Util.convertAccessControlList(jcACL);
} catch (Exception e) {
Utils.<S3ServiceException> rethrowIfRuntimeOrSameType(e);
@ -286,8 +281,8 @@ public class JCloudsS3Service extends S3Service {
ListBucketOptions options = Util.convertListObjectOptions(prefix, priorLastKey,
delimiter, maxListingLength);
jcBucket = connection.listBucket(bucketName, options)
.get(requestTimeoutMilliseconds, TimeUnit.MILLISECONDS);
jcBucket = connection.listBucket(bucketName, options).get(requestTimeoutMilliseconds,
TimeUnit.MILLISECONDS);
jsObjects.addAll(Arrays.asList(Util.convertObjectHeads(jcBucket.getContents())));
commonPrefixes.addAll(jcBucket.getCommonPrefixes());
@ -298,12 +293,11 @@ public class JCloudsS3Service extends S3Service {
}
} while (completeListing && jcBucket.isTruncated()); // Build entire listing if requested
return new S3ObjectsChunk(
prefix, // Return the supplied prefix, not the one in the S3 response.
jcBucket.getDelimiter(),
(S3Object[]) jsObjects.toArray(new S3Object[jsObjects.size()]),
(String[]) commonPrefixes.toArray(new String[commonPrefixes.size()]),
priorLastKey);
return new S3ObjectsChunk(prefix, // Return the supplied prefix, not the one in the S3
// response.
jcBucket.getDelimiter(), (S3Object[]) jsObjects.toArray(new S3Object[jsObjects
.size()]), (String[]) commonPrefixes.toArray(new String[commonPrefixes
.size()]), priorLastKey);
} catch (Exception e) {
Utils.<S3ServiceException> rethrowIfRuntimeOrSameType(e);
throw new S3ServiceException("error listing objects in bucket " + bucketName, e);
@ -312,8 +306,7 @@ public class JCloudsS3Service extends S3Service {
@Override
protected S3Object[] listObjectsImpl(String bucketName, String prefix, String delimiter,
long maxListingLength) throws S3ServiceException
{
long maxListingLength) throws S3ServiceException {
try {
return listObjectsChunked(bucketName, prefix, delimiter, maxListingLength, null, true)
.getObjects();
@ -328,8 +321,8 @@ public class JCloudsS3Service extends S3Service {
throws S3ServiceException {
try {
org.jclouds.aws.s3.domain.AccessControlList jcACL = Util.convertAccessControlList(jsACL);
connection.putBucketACL(bucketName, jcACL)
.get(requestTimeoutMilliseconds,TimeUnit.MILLISECONDS);
connection.putBucketACL(bucketName, jcACL).get(requestTimeoutMilliseconds,
TimeUnit.MILLISECONDS);
} catch (Exception e) {
Utils.<S3ServiceException> rethrowIfRuntimeOrSameType(e);
throw new S3ServiceException("error putting bucket's ACL: " + bucketName, e);
@ -341,8 +334,8 @@ public class JCloudsS3Service extends S3Service {
throws S3ServiceException {
try {
org.jclouds.aws.s3.domain.AccessControlList jcACL = Util.convertAccessControlList(jsACL);
connection.putObjectACL(bucketName, objectKey, jcACL)
.get(requestTimeoutMilliseconds,TimeUnit.MILLISECONDS);
connection.putObjectACL(bucketName, objectKey, jcACL).get(requestTimeoutMilliseconds,
TimeUnit.MILLISECONDS);
} catch (Exception e) {
Utils.<S3ServiceException> rethrowIfRuntimeOrSameType(e);
throw new S3ServiceException("error putting object's ACL", e);
@ -354,8 +347,8 @@ public class JCloudsS3Service extends S3Service {
try {
PutObjectOptions options = Util.convertPutObjectOptions(jsObject.getAcl());
org.jclouds.aws.s3.domain.S3Object jcObject = Util.convertObject(jsObject);
byte md5[] = connection.putObject(bucketName, jcObject, options)
.get(requestTimeoutMilliseconds, TimeUnit.MILLISECONDS);
byte md5[] = connection.putObject(bucketName, jcObject, options).get(
requestTimeoutMilliseconds, TimeUnit.MILLISECONDS);
jsObject.setMd5Hash(md5);
return jsObject;
} catch (Exception e) {

View File

@ -61,7 +61,6 @@ import org.jets3t.service.multithread.CreateObjectsEvent;
import org.jets3t.service.multithread.S3ServiceEventAdaptor;
import org.jets3t.service.multithread.S3ServiceEventListener;
import org.jets3t.service.multithread.S3ServiceMulti;
import org.jets3t.service.multithread.S3ServiceSimpleMulti;
import org.jets3t.service.security.AWSCredentials;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;

View File

@ -24,8 +24,8 @@
package org.jclouds.aws.s3.suncloud.config;
import org.jclouds.aws.s3.config.LiveS3ConnectionModule;
import org.jclouds.aws.s3.config.S3ConnectionModule;
import org.jclouds.aws.s3.suncloud.handlers.ParseSunCloudS3ErrorFromXmlContent;
import org.jclouds.cloud.ConfiguresCloudConnection;
import org.jclouds.http.HttpErrorHandler;
import org.jclouds.http.annotation.ClientError;
import org.jclouds.http.annotation.ServerError;
@ -37,7 +37,7 @@ import com.google.inject.Scopes;
*
* @author Adrian Cole
*/
@S3ConnectionModule
@ConfiguresCloudConnection
public class SunCloudS3ConnectionModule extends LiveS3ConnectionModule {
protected void bindErrorHandlers() {

View File

@ -24,7 +24,7 @@
package org.jclouds.aws.s3.suncloud;
import org.jclouds.aws.s3.S3ConnectionLiveTest;
import org.jclouds.aws.s3.S3ContextFactory;
import org.jclouds.aws.s3.S3ContextBuilder;
import org.jclouds.aws.s3.suncloud.config.SunCloudS3ConnectionModule;
import org.jclouds.aws.s3.suncloud.xml.config.SunCloudS3ParserModule;
import org.testng.annotations.Test;
@ -38,11 +38,11 @@ import org.testng.annotations.Test;
public class SunCloudS3ConnectionLiveTest extends S3ConnectionLiveTest {
@Override
protected S3ContextFactory buildS3ContextFactory(String AWSAccessKeyId, String AWSSecretAccessKey) {
return S3ContextFactory.createContext(AWSAccessKeyId, AWSSecretAccessKey).withModules(
new SunCloudS3ConnectionModule(), new SunCloudS3ParserModule()).withHttpAddress(
"object.storage.network.com").withHttpSecure(false).withHttpPort(80);
protected S3ContextBuilder buildS3ContextFactory(String AWSAccessKeyId, String AWSSecretAccessKey) {
return (S3ContextBuilder) S3ContextBuilder.newBuilder(AWSAccessKeyId, AWSSecretAccessKey)
.withModules(new SunCloudS3ConnectionModule(), new SunCloudS3ParserModule())
.withHttpAddress("object.storage.network.com").withHttpSecure(false)
.withHttpPort(80);
}
}

View File

@ -31,17 +31,6 @@ import com.google.inject.Module;
@Test(sequential = true, testName = "s3.JCloudsNioPerformanceLiveTest", groups = { "live" })
public class JCloudsNioPerformanceLiveTest extends BaseJCloudsPerformance {
@Override
protected S3ContextFactory buildS3ContextFactory(String AWSAccessKeyId,
String AWSSecretAccessKey) {
return super.buildS3ContextFactory(AWSAccessKeyId, AWSSecretAccessKey)
.withPoolMaxConnectionReuse(75)
.withPoolMaxSessionFailures(2)
.withPoolRequestInvokerThreads(1)
.withPoolIoWorkerThreads(2)
.withPoolMaxConnections(12);
}
@Override
protected Module createHttpModule() {
return new HttpNioConnectionPoolClientModule();

View File

@ -43,6 +43,11 @@
<module>samples</module>
</modules>
<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>jclouds-objectstore-core</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>jclouds-aws-core</artifactId>

View File

@ -32,7 +32,6 @@ import javax.annotation.Resource;
import org.jclouds.aws.s3.CreateListOwnedBuckets;
import org.jclouds.aws.s3.S3Context;
import org.jclouds.aws.s3.S3ContextFactory;
import org.jclouds.aws.s3.config.LiveS3ConnectionModule;
import org.jclouds.aws.s3.domain.S3Bucket;
import org.jclouds.logging.Logger;
@ -69,8 +68,7 @@ public class MainApp {
String bucketName = args[2];
// Init
context = S3ContextFactory.createS3Context(accesskeyid, secretkey,
new LiveS3ConnectionModule());
context = S3ContextFactory.createS3Context(accesskeyid, secretkey);
listMyOwnBuckets = new CreateListOwnedBuckets(context);
try {

View File

@ -28,7 +28,6 @@ import java.util.concurrent.TimeUnit;
import org.jclouds.aws.s3.CreateListOwnedBuckets;
import org.jclouds.aws.s3.S3Context;
import org.jclouds.aws.s3.S3ContextFactory;
import org.jclouds.aws.s3.config.LiveS3ConnectionModule;
import org.jclouds.aws.s3.config.StubS3ConnectionModule;
import org.jclouds.aws.s3.reference.S3Constants;
import org.testng.annotations.AfterClass;
@ -61,11 +60,10 @@ public class CreateListOwnedBucketsIntegrationTest {
AWSSecretAccessKey = AWSSecretAccessKey != null ? AWSSecretAccessKey : sysAWSSecretAccessKey;
if ((AWSAccessKeyId != null) && (AWSSecretAccessKey != null))
context = S3ContextFactory.createS3Context(AWSAccessKeyId, AWSSecretAccessKey,
new LiveS3ConnectionModule());
context = S3ContextFactory.createS3Context(AWSAccessKeyId, AWSSecretAccessKey);
else
context = S3ContextFactory.createContext("stub", "stub").withHttpAddress("stub")
.withModule(new StubS3ConnectionModule()).build();
context = S3ContextFactory.createS3Context("stub", "stub", new StubS3ConnectionModule());
}
@Test(groups = { "integration", "live" })

View File

@ -28,7 +28,6 @@ import java.util.concurrent.TimeUnit;
import org.jclouds.aws.s3.CreateListOwnedBuckets;
import org.jclouds.aws.s3.S3Context;
import org.jclouds.aws.s3.S3ContextFactory;
import org.jclouds.aws.s3.config.LiveS3ConnectionModule;
import org.jclouds.aws.s3.reference.S3Constants;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
@ -59,8 +58,7 @@ public class CreateListOwnedBucketsLiveTest {
AWSAccessKeyId = AWSAccessKeyId != null ? AWSAccessKeyId : sysAWSAccessKeyId;
AWSSecretAccessKey = AWSSecretAccessKey != null ? AWSSecretAccessKey : sysAWSSecretAccessKey;
context = S3ContextFactory.createS3Context(AWSAccessKeyId, AWSSecretAccessKey,
new LiveS3ConnectionModule());
context = S3ContextFactory.createS3Context(AWSAccessKeyId, AWSSecretAccessKey);
}

View File

@ -29,7 +29,7 @@ import com.google.inject.servlet.GuiceServletContextListener;
import com.google.inject.servlet.ServletModule;
import org.apache.commons.io.IOUtils;
import org.jclouds.aws.s3.S3Context;
import org.jclouds.aws.s3.S3ContextFactory;
import org.jclouds.aws.s3.S3ContextBuilder;
import org.jclouds.aws.s3.reference.S3Constants;
import org.jclouds.gae.config.URLFetchServiceClientModule;
import org.jclouds.samples.googleappengine.GetAllBucketsController;
@ -53,17 +53,14 @@ public class GuiceServletConfig extends GuiceServletContextListener {
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
Properties props = loadJCloudsProperties(servletContextEvent);
this.accessKeyId = props
.getProperty(S3Constants.PROPERTY_AWS_ACCESSKEYID);
this.secretAccessKey = props
.getProperty(S3Constants.PROPERTY_AWS_SECRETACCESSKEY);
this.accessKeyId = props.getProperty(S3Constants.PROPERTY_AWS_ACCESSKEYID);
this.secretAccessKey = props.getProperty(S3Constants.PROPERTY_AWS_SECRETACCESSKEY);
super.contextInitialized(servletContextEvent);
}
private Properties loadJCloudsProperties(
ServletContextEvent servletContextEvent) {
InputStream input = servletContextEvent.getServletContext()
.getResourceAsStream("/WEB-INF/jclouds.properties");
private Properties loadJCloudsProperties(ServletContextEvent servletContextEvent) {
InputStream input = servletContextEvent.getServletContext().getResourceAsStream(
"/WEB-INF/jclouds.properties");
Properties props = new Properties();
try {
props.load(input);
@ -77,15 +74,14 @@ public class GuiceServletConfig extends GuiceServletContextListener {
@Override
protected Injector getInjector() {
return S3ContextFactory.createInjector(accessKeyId, secretAccessKey,
false, new URLFetchServiceClientModule(),
new ServletModule() {
return S3ContextBuilder.newBuilder(accessKeyId, secretAccessKey).withHttpSecure(false)
.withModules(new URLFetchServiceClientModule(), new ServletModule() {
@Override
protected void configureServlets() {
serve("*.s3").with(GetAllBucketsController.class);
requestInjection(this);
}
});
}).buildInjector();
}
@Override

View File

@ -0,0 +1,50 @@
/**
*
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*/
package org.jclouds.cloud;
/**
* Represents an authenticated context to the cloud.
*
* <h2>Note</h2> Please issue {@link #close()} when you are finished with this context in order to
* release resources.
*
*
* @author Adrian Cole
*
*/
public interface CloudContext<C> {
/**
* low-level api to the cloud. Threadsafe implementations will return a singleton.
*
* @return a connection to the cloud
*/
C getConnection();
/**
* Closes all connections to Cloud Files.
*/
void close();
}

View File

@ -0,0 +1,249 @@
/**
*
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*/
package org.jclouds.cloud;
import static com.google.common.base.Preconditions.checkNotNull;
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_MAX_REDIRECTS;
import static org.jclouds.http.HttpConstants.PROPERTY_HTTP_MAX_RETRIES;
import static org.jclouds.http.HttpConstants.PROPERTY_HTTP_PORT;
import static org.jclouds.http.HttpConstants.PROPERTY_HTTP_SECURE;
import static org.jclouds.http.HttpConstants.PROPERTY_SAX_DEBUG;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Properties;
import org.jclouds.command.ConfiguresResponseParser;
import org.jclouds.http.RequiresHttp;
import org.jclouds.http.config.ConfiguresHttpFutureCommandClient;
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 com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.collect.Iterables;
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Module;
import com.google.inject.name.Names;
/**
* Creates {@link CloudContext} or {@link Injector} instances based on the most commonly requested
* arguments.
* <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.
*
* @author Adrian Cole, Andrew Newdigate
* @see CloudContext
*/
public abstract class CloudContextBuilder<C, X extends CloudContext<C>> {
private static final String DEFAULT_SECURE_HTTP_PORT = "443";
private static final String DEFAULT_NON_SECURE_HTTP_PORT = "80";
protected final Properties properties;
private final List<Module> modules = new ArrayList<Module>(3);
protected CloudContextBuilder(Properties properties) {
this.properties = properties;
}
public CloudContextBuilder<C, X> withHttpAddress(String httpAddress) {
properties.setProperty(PROPERTY_HTTP_ADDRESS, httpAddress);
return this;
}
public CloudContextBuilder<C, X> withSaxDebug() {
properties.setProperty(PROPERTY_SAX_DEBUG, "true");
return this;
}
public CloudContextBuilder<C, X> withHttpMaxRetries(int httpMaxRetries) {
properties.setProperty(PROPERTY_HTTP_MAX_RETRIES, Integer.toString(httpMaxRetries));
return this;
}
public CloudContextBuilder<C, X> withHttpMaxRedirects(int httpMaxRedirects) {
properties.setProperty(PROPERTY_HTTP_MAX_REDIRECTS, Integer.toString(httpMaxRedirects));
return this;
}
public CloudContextBuilder<C, X> withHttpPort(int httpPort) {
properties.setProperty(PROPERTY_HTTP_PORT, Integer.toString(httpPort));
return this;
}
public CloudContextBuilder<C, X> withHttpSecure(boolean httpSecure) {
properties.setProperty(PROPERTY_HTTP_SECURE, Boolean.toString(httpSecure));
return this;
}
public CloudContextBuilder<C, X> withPoolMaxConnectionReuse(int poolMaxConnectionReuse) {
properties.setProperty(PROPERTY_POOL_MAX_CONNECTION_REUSE, Integer
.toString(poolMaxConnectionReuse));
return this;
}
public CloudContextBuilder<C, X> withPoolMaxSessionFailures(int poolMaxSessionFailures) {
properties.setProperty(PROPERTY_POOL_MAX_SESSION_FAILURES, Integer
.toString(poolMaxSessionFailures));
return this;
}
public CloudContextBuilder<C, X> withPoolRequestInvokerThreads(int poolRequestInvokerThreads) {
properties.setProperty(PROPERTY_POOL_REQUEST_INVOKER_THREADS, Integer
.toString(poolRequestInvokerThreads));
return this;
}
public CloudContextBuilder<C, X> withPoolIoWorkerThreads(int poolIoWorkerThreads) {
properties
.setProperty(PROPERTY_POOL_IO_WORKER_THREADS, Integer.toString(poolIoWorkerThreads));
return this;
}
public CloudContextBuilder<C, X> withPoolMaxConnections(int poolMaxConnections) {
properties.setProperty(PROPERTY_POOL_MAX_CONNECTIONS, Integer.toString(poolMaxConnections));
return this;
}
public CloudContextBuilder<C, X> withModule(Module module) {
modules.add(module);
return this;
}
public CloudContextBuilder<C, X> withModules(Module... modules) {
this.modules.addAll(Arrays.asList(modules));
return this;
}
public Injector buildInjector() {
useDefaultPortIfNotPresent(properties);
addLoggingModuleIfNotPresent(modules);
addParserModuleIfNotPresent(modules);
addConnectionModuleIfNotPresent(modules);
addHttpModuleIfNeededAndNotPresent(modules);
modules.add(new AbstractModule() {
@Override
protected void configure() {
Names.bindProperties(binder(), checkNotNull(properties, "properties"));
}
});
addContextModule(modules);
return Guice.createInjector(modules);
}
private void useDefaultPortIfNotPresent(Properties properties) {
/* 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))) {
properties.setProperty(PROPERTY_HTTP_PORT, DEFAULT_SECURE_HTTP_PORT);
} else {
properties.setProperty(PROPERTY_HTTP_PORT, DEFAULT_NON_SECURE_HTTP_PORT);
}
}
}
protected void addLoggingModuleIfNotPresent(final List<Module> modules) {
if (!Iterables.any(modules, Predicates.instanceOf(LoggingModule.class)))
modules.add(new JDKLoggingModule());
}
protected void addHttpModuleIfNeededAndNotPresent(final List<Module> modules) {
if (Iterables.any(modules, new Predicate<Module>() {
public boolean apply(Module input) {
return input.getClass().isAnnotationPresent(RequiresHttp.class);
}
}) && (!Iterables.any(modules, new Predicate<Module>() {
public boolean apply(Module input) {
return input.getClass().isAnnotationPresent(ConfiguresHttpFutureCommandClient.class);
}
})))
modules.add(new JavaUrlHttpFutureCommandClientModule());
}
protected void addConnectionModuleIfNotPresent(final List<Module> modules) {
if (!Iterables.any(modules, new Predicate<Module>() {
public boolean apply(Module input) {
return input.getClass().isAnnotationPresent(ConfiguresCloudConnection.class);
}
})) {
addConnectionModule(modules);
}
}
protected void addParserModuleIfNotPresent(List<Module> modules) {
if (!Iterables.any(modules, new Predicate<Module>() {
public boolean apply(Module input) {
return input.getClass().isAnnotationPresent(ConfiguresResponseParser.class);
}
}))
addParserModule(modules);
}
@VisibleForTesting
public Properties getProperties() {
return properties;
}
public abstract X buildContext();
public abstract void authenticate(String id, String secret);
protected abstract void addParserModule(List<Module> modules);
protected abstract void addContextModule(List<Module> modules);
protected abstract void addConnectionModule(List<Module> modules);
}

View File

@ -21,7 +21,7 @@
* under the License.
* ====================================================================
*/
package org.jclouds.aws.s3.config;
package org.jclouds.cloud;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
@ -30,13 +30,13 @@ import java.lang.annotation.Retention;
import java.lang.annotation.Target;
/**
* designates the the module configures a {@link org.jclouds.aws.s3.S3Connection}
* designates the module configures a Connection to a cloud.
*
* @author Adrian Cole
*
*/
@Retention(RUNTIME)
@Target(TYPE)
public @interface S3ConnectionModule {
public @interface ConfiguresCloudConnection {
}

View File

@ -0,0 +1,42 @@
/**
*
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*/
package org.jclouds.command;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
/**
* designates the module configures a Connection to a cloud.
*
* @author Adrian Cole
*
*/
@Retention(RUNTIME)
@Target(TYPE)
public @interface ConfiguresResponseParser {
}

View File

@ -127,16 +127,16 @@ public class FutureCommand<E, Q extends Request<E>, R, T> implements Future<T> {
}
public interface ResponseRunnableFuture<R, T> extends Response<R>, Runnable, Future<T> {
public void setException(Throwable throwable);
void setException(Throwable throwable);
}
public interface ResponseCallable<R, T> extends Response<R>, Callable<T> {
}
public interface Response<R> {
public R getResponse();
R getResponse();
public void setResponse(R response);
void setResponse(R response);
}
}

View File

@ -38,8 +38,8 @@ import com.google.inject.name.Named;
*
* @author Adrian Cole
*/
public abstract class FutureCommandConnectionPoolClientModule<C> extends
AbstractModule {
public abstract class FutureCommandConnectionPoolClientModule<C> extends AbstractModule {
protected void configure() {
install(new LifeCycleModule());
bind(AtomicInteger.class).toInstance(new AtomicInteger());// max errors
@ -48,14 +48,12 @@ public abstract class FutureCommandConnectionPoolClientModule<C> extends
@Provides
// @Singleton per uri...
public abstract BlockingQueue<C> provideAvailablePool(
@Named(PoolConstants.PROPERTY_POOL_MAX_CONNECTIONS) int max)
throws Exception;
@Named(PoolConstants.PROPERTY_POOL_MAX_CONNECTIONS) int max) throws Exception;
/**
* controls production and destruction of real connections.
* <p/>
* aquire before a new connection is created release after an error has
* occurred
* aquire before a new connection is created release after an error has occurred
*
* @param max
* @throws Exception
@ -63,8 +61,7 @@ public abstract class FutureCommandConnectionPoolClientModule<C> extends
@Provides
// @Singleton per uri...
public Semaphore provideTotalConnectionSemaphore(
@Named(PoolConstants.PROPERTY_POOL_MAX_CONNECTIONS) int max)
throws Exception {
@Named(PoolConstants.PROPERTY_POOL_MAX_CONNECTIONS) int max) throws Exception {
return new Semaphore(max, true);
}
}

View File

@ -0,0 +1,42 @@
/**
*
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*/
package org.jclouds.http;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
/**
* designates the cloud has an HTTP API
*
* @author Adrian Cole
*
*/
@Retention(RUNTIME)
@Target(TYPE)
public @interface RequiresHttp {
}

View File

@ -30,20 +30,12 @@ import org.jclouds.http.HttpException;
import org.jclouds.http.HttpFutureCommand;
import org.jclouds.util.Utils;
import com.google.inject.Inject;
/**
* // TODO: Adrian: Document this!
*
* @author Adrian Cole
*/
public class ReturnStringIf200 extends
HttpFutureCommand.ResponseCallable<String> {
@Inject
public ReturnStringIf200() {
super();
}
public class ReturnStringIf200 extends HttpFutureCommand.ResponseCallable<String> {
public String call() throws HttpException {
checkCode();
@ -55,14 +47,12 @@ public class ReturnStringIf200 extends
try {
toReturn = Utils.toStringAndClose(entity);
} catch (IOException e) {
throw new HttpException(String.format(
"Couldn't receive response %1$s, entity: %2$s ",
throw new HttpException(String.format("Couldn't receive response %1$s, entity: %2$s ",
getResponse(), toReturn), e);
}
return toReturn;
} else {
throw new HttpException(String.format(
"Unhandled status code - %1$s", getResponse()));
throw new HttpException(String.format("Unhandled status code - %1$s", getResponse()));
}
}
}

View File

@ -27,24 +27,19 @@ import org.apache.commons.io.IOUtils;
import org.jclouds.http.HttpException;
import org.jclouds.http.HttpFutureCommand;
import com.google.inject.Inject;
/**
* Simply returns true when the http response code is in the range 200-299.
*
* @author Adrian Cole
*/
public class ReturnTrueIf2xx extends
HttpFutureCommand.ResponseCallable<Boolean> {
@Inject
public ReturnTrueIf2xx() {
super();
}
public class ReturnTrueIf2xx extends HttpFutureCommand.ResponseCallable<Boolean> {
public Boolean call() throws HttpException {
checkCode();
IOUtils.closeQuietly(getResponse().getContent());
int code = getResponse().getStatusCode();
if (code >= 300 || code < 200) {
throw new IllegalStateException("incorrect code for this operation: " + getResponse());
}
return true;
}
}

View File

@ -39,6 +39,6 @@ import org.jclouds.http.HttpFutureCommandClient;
*/
@Retention(RUNTIME)
@Target(TYPE)
public @interface HttpFutureCommandClientModule {
public @interface ConfiguresHttpFutureCommandClient {
}

View File

@ -33,7 +33,7 @@ import com.google.inject.AbstractModule;
*
* @author Adrian Cole
*/
@HttpFutureCommandClientModule
@ConfiguresHttpFutureCommandClient
public class JavaUrlHttpFutureCommandClientModule extends AbstractModule {
@Override

View File

@ -21,15 +21,16 @@
* under the License.
* ====================================================================
*/
package org.jclouds.aws.s3;
package org.jclouds.cloud;
import static org.testng.Assert.assertEquals;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import org.jclouds.aws.s3.config.LiveS3ConnectionModule;
import org.jclouds.http.config.HttpFutureCommandClientModule;
import org.jclouds.http.RequiresHttp;
import org.jclouds.http.config.ConfiguresHttpFutureCommandClient;
import org.jclouds.http.config.JavaUrlHttpFutureCommandClientModule;
import org.jclouds.logging.config.LoggingModule;
import org.jclouds.logging.config.NullLoggingModule;
@ -37,17 +38,18 @@ import org.jclouds.logging.jdk.config.JDKLoggingModule;
import org.testng.annotations.Test;
import com.google.inject.AbstractModule;
import com.google.inject.Binder;
import com.google.inject.Module;
/**
* Tests behavior of modules configured in S3ContextFactory
* Tests behavior of modules configured in CloudContextBuilder
*
* @author Adrian Cole
*/
@Test(groups = "unit", testName = "s3.S3ContextFactoryTest")
public class S3ContextFactoryTest {
@Test(groups = "unit", testName = "s3.CloudContextBuilderTest")
public class CloudContextBuilderTest {
@HttpFutureCommandClientModule
@ConfiguresHttpFutureCommandClient
static class HttpModule extends AbstractModule {
@Override
@ -56,12 +58,65 @@ public class S3ContextFactoryTest {
}
}
class TestCloudContext implements CloudContext<String> {
public void close() {
}
public String getConnection() {
return "";
}
}
class TestCloudContextBuilder extends CloudContextBuilder<String, TestCloudContext> {
protected TestCloudContextBuilder(Properties properties) {
super(properties);
}
@Override
public TestCloudContext buildContext() {
return new TestCloudContext();
}
@Override
protected void addConnectionModule(List<Module> modules) {
modules.add(new Module() {
public void configure(Binder arg0) {
}
});
}
@Override
protected void addContextModule(List<Module> modules) {
modules.add(new Module() {
public void configure(Binder arg0) {
}
});
}
@Override
protected void addParserModule(List<Module> modules) {
modules.add(new Module() {
public void configure(Binder arg0) {
}
});
}
@Override
public void authenticate(String id, String secret) {
}
}
@Test
public void testAddHttpModuleIfNotPresent() {
List<Module> modules = new ArrayList<Module>();
HttpModule module = new HttpModule();
modules.add(module);
S3ContextFactory.addHttpModuleIfNeededAndNotPresent(modules);
new TestCloudContextBuilder(new Properties()).addHttpModuleIfNeededAndNotPresent(modules);
assertEquals(modules.size(), 1);
assertEquals(modules.remove(0), module);
}
@ -71,7 +126,7 @@ public class S3ContextFactoryTest {
List<Module> modules = new ArrayList<Module>();
LoggingModule module = new NullLoggingModule();
modules.add(module);
S3ContextFactory.addLoggingModuleIfNotPresent(modules);
new TestCloudContextBuilder(new Properties()).addLoggingModuleIfNotPresent(modules);
assertEquals(modules.size(), 1);
assertEquals(modules.remove(0), module);
}
@ -83,37 +138,48 @@ public class S3ContextFactoryTest {
modules.add(loggingModule);
HttpModule httpModule = new HttpModule();
modules.add(httpModule);
S3ContextFactory.addHttpModuleIfNeededAndNotPresent(modules);
S3ContextFactory.addLoggingModuleIfNotPresent(modules);
TestCloudContextBuilder builder = new TestCloudContextBuilder(new Properties());
builder.addHttpModuleIfNeededAndNotPresent(modules);
builder.addLoggingModuleIfNotPresent(modules);
assertEquals(modules.size(), 2);
assertEquals(modules.remove(0), loggingModule);
assertEquals(modules.remove(0), httpModule);
}
@Test
public void testAddBothWhenNotLive() {
public void testAddBothWhenDoesntRequireHttp() {
List<Module> modules = new ArrayList<Module>();
S3ContextFactory.addHttpModuleIfNeededAndNotPresent(modules);
S3ContextFactory.addLoggingModuleIfNotPresent(modules);
TestCloudContextBuilder builder = new TestCloudContextBuilder(new Properties());
builder.addHttpModuleIfNeededAndNotPresent(modules);
builder.addLoggingModuleIfNotPresent(modules);
assertEquals(modules.size(), 1);
assert modules.remove(0) instanceof JDKLoggingModule;
}
@RequiresHttp
class RequiresHttpModule implements Module {
public void configure(Binder arg0) {
}
}
@Test
public void testAddBothWhenLive() {
List<Module> modules = new ArrayList<Module>();
modules.add(new LiveS3ConnectionModule());
S3ContextFactory.addHttpModuleIfNeededAndNotPresent(modules);
S3ContextFactory.addLoggingModuleIfNotPresent(modules);
modules.add(new RequiresHttpModule());
TestCloudContextBuilder builder = new TestCloudContextBuilder(new Properties());
builder.addHttpModuleIfNeededAndNotPresent(modules);
builder.addLoggingModuleIfNotPresent(modules);
assertEquals(modules.size(), 3);
assert modules.remove(0) instanceof LiveS3ConnectionModule;
assert modules.remove(0) instanceof RequiresHttpModule;
assert modules.remove(0) instanceof JavaUrlHttpFutureCommandClientModule;
assert modules.remove(0) instanceof JDKLoggingModule;
}
public void testBuilder() {
String awsAccessKeyId = "awsAccessKeyId";
String awsSecretAccessKey = "awsSecretAccessKey";
String id = "awsAccessKeyId";
String secret = "awsSecretAccessKey";
String httpAddress = "httpAddress";
int httpMaxRetries = 9875;
int httpPort = 3827;
@ -136,18 +202,18 @@ public class S3ContextFactoryTest {
protected void configure() {
}
};
S3ContextFactory factory = S3ContextFactory.createContext(awsAccessKeyId, awsSecretAccessKey);
factory.withHttpAddress(httpAddress);
factory.withHttpMaxRetries(httpMaxRetries);
factory.withHttpPort(httpPort);
factory.withHttpSecure(httpSecure);
factory.withModule(module1);
factory.withModules(module2);
factory.withPoolIoWorkerThreads(poolIoWorkerThreads);
factory.withPoolMaxConnectionReuse(poolMaxConnectionReuse);
factory.withPoolMaxConnections(poolMaxConnections);
factory.withPoolMaxSessionFailures(poolMaxSessionFailures);
factory.withPoolRequestInvokerThreads(poolRequestInvokerThreads);
TestCloudContextBuilder builder = new TestCloudContextBuilder(new Properties());
builder.authenticate(id, secret);
builder.withHttpAddress(httpAddress);
builder.withHttpMaxRetries(httpMaxRetries);
builder.withHttpPort(httpPort);
builder.withHttpSecure(httpSecure);
builder.withModule(module1);
builder.withModules(module2);
builder.withPoolIoWorkerThreads(poolIoWorkerThreads);
builder.withPoolMaxConnectionReuse(poolMaxConnectionReuse);
builder.withPoolMaxConnections(poolMaxConnections);
builder.withPoolMaxSessionFailures(poolMaxSessionFailures);
builder.withPoolRequestInvokerThreads(poolRequestInvokerThreads);
}
}

48
objectstore/core/pom.xml Normal file
View File

@ -0,0 +1,48 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
$HeadURL$
$Revision$
$Date$
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.html
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.
====================================================================
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<groupId>org.jclouds</groupId>
<artifactId>jclouds-objectstore-project</artifactId>
<version>1.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.jclouds</groupId>
<artifactId>jclouds-objectstore-core</artifactId>
<name>jclouds objectstore Components Core</name>
<packaging>jar</packaging>
<description>jclouds Core components to access objectstores</description>
<scm>
<connection>scm:svn:http://jclouds.googlecode.com/svn/trunk/objectstore/core</connection>
<developerConnection>scm:svn:https://jclouds.googlecode.com/svn/trunk/objectstore/core</developerConnection>
<url>http://jclouds.googlecode.com/svn/trunk/objectstore/core</url>
</scm>
</project>

View File

@ -0,0 +1,42 @@
/**
*
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*/
package org.jclouds.objectstore.reference;
/**
* Configuration properties and constants used in ObjectStore connections.
*
* @author Adrian Cole
*/
public interface ObjectStoreConstants {
/**
* longest time a single Map operation can take before throwing an exception.
*/
public static final String PROPERTY_OBJECTMAP_TIMEOUT = "jclouds.objectmap.timeout";
/**
* time to pause before retrying a transient failure
*/
public static final String PROPERTY_OBJECTMAP_RETRY = "jclouds.objectmap.retry";
}

View File

@ -0,0 +1,28 @@
/**
*
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*/
/**
* This package contains properties and reference data used in S3.
* @author Adrian Cole
*/
package org.jclouds.objectstore.reference;

68
objectstore/pom.xml Normal file
View File

@ -0,0 +1,68 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
$HeadURL$
$Revision$
$Date$
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.html
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.
====================================================================
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<artifactId>jclouds-project</artifactId>
<groupId>org.jclouds</groupId>
<version>1.0-SNAPSHOT</version>
<relativePath>../project/pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jclouds-objectstore-project</artifactId>
<packaging>pom</packaging>
<name>jclouds objectstore project</name>
<modules>
<module>core</module>
</modules>
<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>jclouds-core</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>jclouds-core</artifactId>
<version>${project.version}</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.14</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>jclouds-log4j</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>