Issue 95: created qualifier annotations for endpoints and removed host/port logic

git-svn-id: http://jclouds.googlecode.com/svn/trunk@1917 3d8758e0-26b5-11de-8745-db77d3ebf521
This commit is contained in:
adrian.f.cole 2009-09-24 22:49:43 +00:00
parent 6b0f7e289a
commit 95409990b1
37 changed files with 311 additions and 388 deletions

View File

@ -0,0 +1,44 @@
/**
*
* 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 java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import javax.inject.Qualifier;
/**
* Related to a resource of type S3
*
* @author Adrian Cole
*
*/
@Retention(value = RetentionPolicy.RUNTIME)
@Target(value = { ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD })
@Qualifier
public @interface S3 {
}

View File

@ -27,23 +27,14 @@ 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.blobstore.reference.BlobStoreConstants.PROPERTY_USER_METADATA_PREFIX;
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 static org.jclouds.http.pool.PoolConstants.PROPERTY_POOL_IO_WORKER_THREADS;
import static org.jclouds.http.pool.PoolConstants.PROPERTY_POOL_MAX_CONNECTIONS;
import static org.jclouds.http.pool.PoolConstants.PROPERTY_POOL_MAX_CONNECTION_REUSE;
import static org.jclouds.http.pool.PoolConstants.PROPERTY_POOL_MAX_SESSION_FAILURES;
import static org.jclouds.http.pool.PoolConstants.PROPERTY_POOL_REQUEST_INVOKER_THREADS;
import java.net.URI;
import java.util.List;
import java.util.Properties;
import org.jclouds.aws.s3.config.RestS3ConnectionModule;
import org.jclouds.aws.s3.config.S3ContextModule;
import org.jclouds.aws.s3.xml.config.S3ParserModule;
import org.jclouds.aws.s3.reference.S3Constants;
import org.jclouds.cloud.CloudContextBuilder;
import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule;
import org.jclouds.logging.jdk.config.JDKLoggingModule;
@ -68,23 +59,20 @@ public class S3ContextBuilder extends CloudContextBuilder<S3Context> {
public S3ContextBuilder(Properties props) {
super(props);
properties.setProperty(S3Constants.PROPERTY_S3_ENDPOINT, "https://s3.amazonaws.com");
properties.setProperty(PROPERTY_USER_METADATA_PREFIX, "x-amz-meta-");
}
@Override
public CloudContextBuilder<S3Context> withEndpoint(URI endpoint) {
properties.setProperty(S3Constants.PROPERTY_S3_ENDPOINT, checkNotNull(endpoint, "endpoint")
.toString());
return this;
}
public static S3ContextBuilder newBuilder(String id, String secret) {
Properties properties = new Properties();
properties.setProperty(PROPERTY_HTTP_ADDRESS, "s3.amazonaws.com");
properties.setProperty(PROPERTY_USER_METADATA_PREFIX, "x-amz-meta-");
properties.setProperty(PROPERTY_HTTP_SECURE, "true");
properties.setProperty(PROPERTY_SAX_DEBUG, "false");
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;
@ -100,15 +88,11 @@ public class S3ContextBuilder extends CloudContextBuilder<S3Context> {
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) {
protected void addApiModule(List<Module> modules) {
modules.add(new RestS3ConnectionModule());
}

View File

@ -23,34 +23,31 @@
*/
package org.jclouds.aws.s3.config;
import java.net.MalformedURLException;
import java.net.URI;
import javax.annotation.Resource;
import javax.inject.Named;
import javax.inject.Singleton;
import org.jclouds.aws.s3.S3;
import org.jclouds.aws.s3.S3BlobStore;
import org.jclouds.aws.s3.filters.RequestAuthorizeSignature;
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.reference.S3Constants;
import org.jclouds.cloud.ConfiguresCloudConnection;
import org.jclouds.http.HttpConstants;
import org.jclouds.http.HttpErrorHandler;
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;
import org.jclouds.logging.Logger;
import org.jclouds.rest.RestClientFactory;
import org.jclouds.rest.config.JaxrsModule;
import com.google.inject.AbstractModule;
import javax.inject.Inject;
import com.google.inject.Provides;
import com.google.inject.Scopes;
import javax.inject.Singleton;
import javax.inject.Named;
/**
* Configures the S3 connection, including logging and http transport.
@ -60,18 +57,6 @@ import javax.inject.Named;
@ConfiguresCloudConnection
@RequiresHttp
public class RestS3ConnectionModule extends AbstractModule {
@Resource
protected Logger logger = Logger.NULL;
@Inject
@Named(HttpConstants.PROPERTY_HTTP_ADDRESS)
String address;
@Inject
@Named(HttpConstants.PROPERTY_HTTP_PORT)
int port;
@Inject
@Named(HttpConstants.PROPERTY_HTTP_SECURE)
boolean isSecure;
@Override
protected void configure() {
@ -79,13 +64,18 @@ public class RestS3ConnectionModule extends AbstractModule {
bind(RequestAuthorizeSignature.class).in(Scopes.SINGLETON);
bindErrorHandlers();
bindRetryHandlers();
requestInjection(this);
logger.info("S3 Context = %s://%s:%s", (isSecure ? "https" : "http"), address, port);
}
@Provides
@Singleton
protected S3BlobStore provideS3Connection(URI uri, RestClientFactory factory) {
@S3
protected URI provideS3URI(@Named(S3Constants.PROPERTY_S3_ENDPOINT) String endpoint) {
return URI.create(endpoint);
}
@Provides
@Singleton
protected S3BlobStore provideS3Connection(@S3 URI uri, RestClientFactory factory) {
return factory.create(uri, S3BlobStore.class);
}
@ -104,16 +94,4 @@ public class RestS3ConnectionModule extends AbstractModule {
bind(HttpRetryHandler.class).annotatedWith(ClientError.class).to(
AWSClientErrorRetryHandler.class);
}
@Singleton
@Provides
protected URI provideAddress(@Named(HttpConstants.PROPERTY_HTTP_ADDRESS) String address,
@Named(HttpConstants.PROPERTY_HTTP_PORT) int port,
@Named(HttpConstants.PROPERTY_HTTP_SECURE) boolean isSecure)
throws MalformedURLException {
return URI.create(String.format("%1$s://%2$s:%3$s", isSecure ? "https" : "http", address,
port));
}
}

View File

@ -27,7 +27,10 @@ import java.io.IOException;
import java.net.URI;
import javax.annotation.Resource;
import javax.inject.Inject;
import javax.inject.Named;
import org.jclouds.aws.s3.S3;
import org.jclouds.aws.s3.S3BlobStore;
import org.jclouds.aws.s3.S3Context;
import org.jclouds.aws.s3.domain.ObjectMetadata;
@ -38,9 +41,7 @@ import org.jclouds.blobstore.InputStreamMap;
import org.jclouds.lifecycle.Closer;
import org.jclouds.logging.Logger;
import javax.inject.Inject;
import com.google.inject.Injector;
import javax.inject.Named;
/**
* Uses a Guice Injector to configure the objects served by S3Context methods.
@ -69,7 +70,7 @@ public class GuiceS3Context implements S3Context {
@Inject
private GuiceS3Context(Injector injector, Closer closer, S3ObjectMapFactory s3ObjectMapFactory,
S3InputStreamMapFactory s3InputStreamMapFactory,
@Named(S3Constants.PROPERTY_AWS_ACCESSKEYID) String accessKey, URI endPoint) {
@Named(S3Constants.PROPERTY_AWS_ACCESSKEYID) String accessKey, @S3 URI endPoint) {
this.injector = injector;
this.s3InputStreamMapFactory = s3InputStreamMapFactory;
this.s3ObjectMapFactory = s3ObjectMapFactory;

View File

@ -34,7 +34,7 @@ import org.jclouds.blobstore.reference.BlobStoreConstants;
public interface S3Constants extends AWSConstants, S3Headers, BlobStoreConstants {
/**
* S3 service's XML Jsr330pace, as used in XML request and response documents.
* S3 service's XML Namespace, as used in XML request and response documents.
*/
public static final String S3_REST_API_XML_NAMESPACE = "http://s3.amazonaws.com/doc/2006-03-01/";
public static final String ENDPOINT = "Endpoint";
@ -42,5 +42,7 @@ public interface S3Constants extends AWSConstants, S3Headers, BlobStoreConstants
public static final String MARKER = "marker";
public static final String MAX_KEYS = "max-keys";
public static final String DELIMITER = "delimiter";
public static final String PROPERTY_S3_ENDPOINT = "https://s3.amazonaws.com";
}

View File

@ -26,19 +26,19 @@ 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.blobstore.reference.BlobStoreConstants.PROPERTY_USER_METADATA_PREFIX;
import static org.jclouds.http.HttpConstants.PROPERTY_HTTP_ADDRESS;
import static org.testng.Assert.assertEquals;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import javax.inject.Inject;
import org.jclouds.aws.s3.config.RestS3ConnectionModule;
import org.jclouds.aws.s3.config.S3ContextModule;
import org.jclouds.aws.s3.domain.ObjectMetadata;
import org.jclouds.aws.s3.domain.S3Object;
import org.jclouds.aws.s3.internal.GuiceS3Context;
import org.jclouds.aws.s3.xml.config.S3ParserModule;
import org.jclouds.blobstore.functions.ParseBlobFromHeadersAndHttpContent.BlobFactory;
import org.jclouds.blobstore.functions.ParseBlobMetadataFromHeaders.BlobMetadataFactory;
import org.jclouds.cloud.CloudContext;
@ -61,7 +61,6 @@ public class S3ContextBuilderTest {
S3ContextBuilder builder = S3ContextBuilder.newBuilder("id", "secret");
assertEquals(builder.getProperties().getProperty(PROPERTY_USER_METADATA_PREFIX),
"x-amz-meta-");
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");
}
@ -71,7 +70,7 @@ public class S3ContextBuilderTest {
.buildContext();
assertEquals(context.getClass(), GuiceS3Context.class);
assertEquals(context.getAccount(), "id");
assertEquals(context.getEndPoint(), URI.create("https://s3.amazonaws.com:443"));
assertEquals(context.getEndPoint(), URI.create("https://s3.amazonaws.com"));
}
public void testBuildInjector() {
@ -84,15 +83,13 @@ public class S3ContextBuilderTest {
})) != null;
assert i.getInstance(Key.get(new TypeLiteral<BlobFactory<ObjectMetadata, S3Object>>() {
})) != null;
i.injectMembers(this);
assertEquals(endpoint, URI.create("https://s3.amazonaws.com"));
}
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);
}
private @Inject
@S3
URI endpoint;
protected void testAddContextModule() {
List<Module> modules = new ArrayList<Module>();
@ -105,7 +102,7 @@ public class S3ContextBuilderTest {
protected void addConnectionModule() {
List<Module> modules = new ArrayList<Module>();
S3ContextBuilder builder = S3ContextBuilder.newBuilder("id", "secret");
builder.addConnectionModule(modules);
builder.addApiModule(modules);
assertEquals(modules.size(), 1);
assertEquals(modules.get(0).getClass(), RestS3ConnectionModule.class);
}

View File

@ -29,17 +29,16 @@ 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.reference.S3Constants;
import org.jclouds.aws.s3.xml.config.S3ParserModule;
import org.jclouds.concurrent.WithinThreadExecutorService;
import org.jclouds.concurrent.config.ExecutorServiceModule;
import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule;
import org.jclouds.http.handlers.DelegatingErrorHandler;
import org.jclouds.http.handlers.DelegatingRetryHandler;
import org.jclouds.util.Jsr330;
import org.testng.annotations.Test;
import com.google.inject.Guice;
import com.google.inject.Injector;
import org.jclouds.util.Jsr330;
/**
* @author Adrian Cole
@ -48,25 +47,19 @@ import org.jclouds.util.Jsr330;
public class S3ContextModuleTest {
Injector createInjector() {
return Guice.createInjector(new RestS3ConnectionModule(), new ExecutorServiceModule(
new WithinThreadExecutorService()), new S3ParserModule(), new S3ContextModule() {
return Guice.createInjector(new RestS3ConnectionModule(), new S3ContextModule() {
@Override
protected void configure() {
bindConstant().annotatedWith(Jsr330.named(S3Constants.PROPERTY_AWS_ACCESSKEYID)).to(
"localhost");
bindConstant().annotatedWith(Jsr330.named(S3Constants.PROPERTY_AWS_SECRETACCESSKEY)).to(
"localhost");
bindConstant().annotatedWith(Jsr330.named(S3Constants.PROPERTY_HTTP_ADDRESS)).to(
"localhost");
bindConstant().annotatedWith(Jsr330.named(S3Constants.PROPERTY_HTTP_PORT)).to("1000");
bindConstant().annotatedWith(Jsr330.named(S3Constants.PROPERTY_HTTP_SECURE)).to("false");
bindConstant().annotatedWith(Jsr330.named(S3Constants.PROPERTY_HTTP_MAX_RETRIES))
.to("5");
bindConstant().annotatedWith(Jsr330.named(S3Constants.PROPERTY_HTTP_MAX_REDIRECTS)).to(
"5");
"user");
bindConstant().annotatedWith(Jsr330.named(S3Constants.PROPERTY_AWS_SECRETACCESSKEY))
.to("key");
bindConstant().annotatedWith(Jsr330.named(S3Constants.PROPERTY_S3_ENDPOINT)).to(
"http://localhost");
super.configure();
}
}, new JavaUrlHttpCommandExecutorServiceModule());
}, new JavaUrlHttpCommandExecutorServiceModule(), new ExecutorServiceModule(
new WithinThreadExecutorService()));
}
@Test

View File

@ -25,6 +25,7 @@ package org.jclouds.aws.s3.config;
import java.net.URI;
import org.jclouds.aws.s3.S3;
import org.jclouds.aws.s3.S3BlobStore;
import org.jclouds.aws.s3.internal.StubS3BlobStore;
import org.jclouds.cloud.ConfiguresCloudConnection;
@ -42,6 +43,6 @@ public class StubS3BlobStoreModule extends AbstractModule {
protected void configure() {
install(new ParserModule());
bind(S3BlobStore.class).to(StubS3BlobStore.class);
bind(URI.class).toInstance(URI.create("http://localhost:8080"));
bind(URI.class).annotatedWith(S3.class).toInstance(URI.create("http://localhost:8080"));
}
}

View File

@ -74,8 +74,8 @@ public class GuiceServletConfig extends GuiceServletContextListener {
@Override
protected Injector getInjector() {
return S3ContextBuilder.newBuilder(accessKeyId, secretAccessKey).withHttpSecure(false)
.withModules(new GaeHttpCommandExecutorServiceModule(), new ServletModule() {
return S3ContextBuilder.newBuilder(accessKeyId, secretAccessKey).withModules(
new GaeHttpCommandExecutorServiceModule(), new ServletModule() {
@Override
protected void configureServlets() {
serve("*.s3").with(GetAllBucketsController.class);

View File

@ -0,0 +1,21 @@
package org.jclouds.azure.storage.blob;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import javax.inject.Qualifier;
/**
* Related to a resource of type Azure Blob
*
* @author Adrian Cole
*
*/
@Retention(value = RetentionPolicy.RUNTIME)
@Target(value = { ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD })
@Qualifier
public @interface AzureBlob {
}

View File

@ -25,23 +25,14 @@ package org.jclouds.azure.storage.blob;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.jclouds.blobstore.reference.BlobStoreConstants.PROPERTY_USER_METADATA_PREFIX;
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 static org.jclouds.http.pool.PoolConstants.PROPERTY_POOL_IO_WORKER_THREADS;
import static org.jclouds.http.pool.PoolConstants.PROPERTY_POOL_MAX_CONNECTIONS;
import static org.jclouds.http.pool.PoolConstants.PROPERTY_POOL_MAX_CONNECTION_REUSE;
import static org.jclouds.http.pool.PoolConstants.PROPERTY_POOL_MAX_SESSION_FAILURES;
import static org.jclouds.http.pool.PoolConstants.PROPERTY_POOL_REQUEST_INVOKER_THREADS;
import java.net.URI;
import java.util.List;
import java.util.Properties;
import org.jclouds.azure.storage.blob.config.AzureBlobContextModule;
import org.jclouds.azure.storage.blob.config.RestAzureBlobStoreModule;
import org.jclouds.azure.storage.blob.xml.config.AzureBlobParserModule;
import org.jclouds.azure.storage.blob.reference.AzureBlobConstants;
import org.jclouds.azure.storage.reference.AzureStorageConstants;
import org.jclouds.cloud.CloudContextBuilder;
import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule;
@ -67,47 +58,44 @@ public class AzureBlobContextBuilder extends CloudContextBuilder<AzureBlobContex
public AzureBlobContextBuilder(Properties props) {
super(props);
properties.setProperty(PROPERTY_USER_METADATA_PREFIX, "x-ms-meta-");
properties.setProperty(AzureBlobConstants.PROPERTY_AZUREBLOB_ENDPOINT,
"https://{account}.blob.core.windows.net");
}
public static AzureBlobContextBuilder newBuilder(String id, String secret) {
Properties properties = new Properties();
properties.setProperty(PROPERTY_USER_METADATA_PREFIX, "x-ms-meta-");
properties.setProperty(PROPERTY_HTTP_ADDRESS, id + ".blob.core.windows.net");
properties.setProperty(PROPERTY_HTTP_SECURE, "true");
properties.setProperty(PROPERTY_SAX_DEBUG, "false");
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");
AzureBlobContextBuilder builder = new AzureBlobContextBuilder(properties);
builder.authenticate(id, secret);
return builder;
}
@Override
public CloudContextBuilder<AzureBlobContext> withEndpoint(URI endpoint) {
properties.setProperty(AzureBlobConstants.PROPERTY_AZUREBLOB_ENDPOINT, checkNotNull(endpoint,
"endpoint").toString());
return this;
}
public void authenticate(String id, String secret) {
properties.setProperty(AzureStorageConstants.PROPERTY_AZURESTORAGE_ACCOUNT, checkNotNull(id,
"azureStorageAccount"));
properties.setProperty(AzureStorageConstants.PROPERTY_AZURESTORAGE_KEY, checkNotNull(secret,
"azureStorageKey"));
String endpoint = properties.getProperty(AzureBlobConstants.PROPERTY_AZUREBLOB_ENDPOINT);
properties.setProperty(AzureBlobConstants.PROPERTY_AZUREBLOB_ENDPOINT, endpoint.replaceAll(
"\\{account\\}", id));
}
public AzureBlobContext buildContext() {
return buildInjector().getInstance(AzureBlobContext.class);
}
protected void addParserModule(List<Module> modules) {
modules.add(new AzureBlobParserModule());
}
protected void addContextModule(List<Module> modules) {
modules.add(new AzureBlobContextModule());
}
protected void addConnectionModule(List<Module> modules) {
protected void addApiModule(List<Module> modules) {
modules.add(new RestAzureBlobStoreModule());
}

View File

@ -25,14 +25,18 @@ package org.jclouds.azure.storage.blob.config;
import java.net.URI;
import javax.inject.Named;
import javax.inject.Singleton;
import org.jclouds.azure.storage.blob.AzureBlob;
import org.jclouds.azure.storage.blob.AzureBlobStore;
import org.jclouds.azure.storage.blob.reference.AzureBlobConstants;
import org.jclouds.azure.storage.config.RestAzureStorageConnectionModule;
import org.jclouds.cloud.ConfiguresCloudConnection;
import org.jclouds.http.RequiresHttp;
import org.jclouds.rest.RestClientFactory;
import com.google.inject.Provides;
import javax.inject.Singleton;
/**
* Configures the Azure Blob Service connection, including logging and http transport.
@ -50,7 +54,15 @@ public class RestAzureBlobStoreModule extends RestAzureStorageConnectionModule {
@Provides
@Singleton
protected AzureBlobStore provideAzureBlobStore(URI uri, RestClientFactory factory) {
@AzureBlob
protected URI provideAuthenticationURI(
@Named(AzureBlobConstants.PROPERTY_AZUREBLOB_ENDPOINT) String endpoint) {
return URI.create(endpoint);
}
@Provides
@Singleton
protected AzureBlobStore provideAzureBlobStore(@AzureBlob URI uri, RestClientFactory factory) {
return factory.create(uri, AzureBlobStore.class);
}

View File

@ -27,7 +27,10 @@ import java.io.IOException;
import java.net.URI;
import javax.annotation.Resource;
import javax.inject.Inject;
import javax.inject.Named;
import org.jclouds.azure.storage.blob.AzureBlob;
import org.jclouds.azure.storage.blob.AzureBlobContext;
import org.jclouds.azure.storage.blob.AzureBlobStore;
import org.jclouds.azure.storage.blob.domain.Blob;
@ -38,9 +41,7 @@ import org.jclouds.blobstore.InputStreamMap;
import org.jclouds.lifecycle.Closer;
import org.jclouds.logging.Logger;
import javax.inject.Inject;
import com.google.inject.Injector;
import javax.inject.Named;
/**
* Uses a Guice Injector to configure the objects served by AzureBlobContext methods.
@ -70,7 +71,8 @@ public class GuiceAzureBlobContext implements AzureBlobContext {
private GuiceAzureBlobContext(Injector injector, Closer closer,
AzureBlobObjectMapFactory azureObjectMapFactory,
AzureBlobInputStreamMapFactory azureInputStreamMapFactory,
@Named(AzureStorageConstants.PROPERTY_AZURESTORAGE_ACCOUNT) String account, URI endPoint) {
@Named(AzureStorageConstants.PROPERTY_AZURESTORAGE_ACCOUNT) String account,
@AzureBlob URI endPoint) {
this.injector = injector;
this.closer = closer;
this.azureInputStreamMapFactory = azureInputStreamMapFactory;

View File

@ -0,0 +1,12 @@
package org.jclouds.azure.storage.blob.reference;
import org.jclouds.azure.storage.reference.AzureStorageConstants;
/**
* Configuration properties and constants used in Azure Blob connections.
*
* @author Adrian Cole
*/
public interface AzureBlobConstants extends AzureStorageConstants {
public static final String PROPERTY_AZUREBLOB_ENDPOINT = "jclouds.azureblob.endpoint";
}

View File

@ -24,7 +24,6 @@
package org.jclouds.azure.storage.blob;
import static org.jclouds.blobstore.reference.BlobStoreConstants.PROPERTY_USER_METADATA_PREFIX;
import static org.jclouds.http.HttpConstants.PROPERTY_HTTP_ADDRESS;
import static org.testng.Assert.assertEquals;
import java.net.URI;
@ -58,8 +57,6 @@ public class AzureBlobContextBuilderTest {
public void testNewBuilder() {
AzureBlobContextBuilder builder = AzureBlobContextBuilder.newBuilder("id", "secret");
assertEquals(builder.getProperties().getProperty(PROPERTY_USER_METADATA_PREFIX), "x-ms-meta-");
assertEquals(builder.getProperties().getProperty(PROPERTY_HTTP_ADDRESS),
"id.blob.core.windows.net");
assertEquals(builder.getProperties().getProperty(
AzureStorageConstants.PROPERTY_AZURESTORAGE_ACCOUNT), "id");
assertEquals(builder.getProperties().getProperty(
@ -71,7 +68,7 @@ public class AzureBlobContextBuilderTest {
.buildContext();
assertEquals(context.getClass(), GuiceAzureBlobContext.class);
assertEquals(context.getAccount(), "id");
assertEquals(context.getEndPoint(), URI.create("https://id.blob.core.windows.net:443"));
assertEquals(context.getEndPoint(), URI.create("https://id.blob.core.windows.net"));
}
public void testBuildInjector() {
@ -96,7 +93,7 @@ public class AzureBlobContextBuilderTest {
protected void addConnectionModule() {
List<Module> modules = new ArrayList<Module>();
AzureBlobContextBuilder builder = AzureBlobContextBuilder.newBuilder("id", "secret");
builder.addConnectionModule(modules);
builder.addApiModule(modules);
assertEquals(modules.size(), 1);
assertEquals(modules.get(0).getClass(), RestAzureBlobStoreModule.class);
}

View File

@ -35,7 +35,6 @@ import javax.ws.rs.HttpMethod;
import org.jclouds.azure.storage.blob.functions.ReturnTrueIfContainerAlreadyExists;
import org.jclouds.azure.storage.blob.options.CreateContainerOptions;
import org.jclouds.azure.storage.blob.xml.config.AzureBlobParserModule;
import org.jclouds.azure.storage.options.CreateOptions;
import org.jclouds.azure.storage.options.ListOptions;
import org.jclouds.azure.storage.reference.AzureStorageConstants;
@ -49,13 +48,13 @@ import org.jclouds.http.functions.ReturnTrueIf2xx;
import org.jclouds.http.functions.ReturnTrueOn404;
import org.jclouds.rest.JaxrsAnnotationProcessor;
import org.jclouds.rest.config.JaxrsModule;
import org.jclouds.util.Jsr330;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableMultimap;
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import org.jclouds.util.Jsr330;
/**
* Tests behavior of {@code AzureBlobStore}
@ -258,14 +257,13 @@ public class AzureBlobStoreTest {
@BeforeClass
void setupFactory() {
factory = Guice.createInjector(
new AzureBlobParserModule(),
new AbstractModule() {
@Override
protected void configure() {
bind(URI.class).toInstance(URI.create("http://blob.core.windows.net"));
bindConstant().annotatedWith(
Jsr330.named(AzureStorageConstants.PROPERTY_AZURESTORAGE_ACCOUNT)).to(
"myaccount");
Jsr330.named(AzureStorageConstants.PROPERTY_AZURESTORAGE_ACCOUNT))
.to("myaccount");
bindConstant().annotatedWith(
Jsr330.named(AzureStorageConstants.PROPERTY_AZURESTORAGE_KEY)).to(
HttpUtils.toBase64String("key".getBytes()));

View File

@ -25,6 +25,7 @@ package org.jclouds.azure.storage.blob.config;
import java.net.URI;
import org.jclouds.azure.storage.blob.AzureBlob;
import org.jclouds.azure.storage.blob.AzureBlobStore;
import org.jclouds.azure.storage.blob.internal.StubAzureBlobStore;
import org.jclouds.cloud.ConfiguresCloudConnection;
@ -42,6 +43,7 @@ public class StubAzureBlobStoreModule extends AbstractModule {
protected void configure() {
install(new ParserModule());
bind(AzureBlobStore.class).to(StubAzureBlobStore.class);
bind(URI.class).toInstance(URI.create("http://localhost:8080"));
bind(URI.class).annotatedWith(AzureBlob.class)
.toInstance(URI.create("http://localhost:8080"));
}
}

View File

@ -0,0 +1,21 @@
package org.jclouds.azure.storage;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import javax.inject.Qualifier;
/**
* Related to a resource of type Azure Storage
*
* @author Adrian Cole
*
*/
@Retention(value = RetentionPolicy.RUNTIME)
@Target(value = { ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD })
@Qualifier
public @interface AzureStorage {
}

View File

@ -23,29 +23,18 @@
*/
package org.jclouds.azure.storage.config;
import java.net.MalformedURLException;
import java.net.URI;
import javax.annotation.Resource;
import org.jclouds.azure.storage.filters.SharedKeyAuthentication;
import org.jclouds.azure.storage.handlers.ParseAzureStorageErrorFromXmlContent;
import org.jclouds.cloud.ConfiguresCloudConnection;
import org.jclouds.http.HttpConstants;
import org.jclouds.http.HttpErrorHandler;
import org.jclouds.http.RequiresHttp;
import org.jclouds.http.annotation.ClientError;
import org.jclouds.http.annotation.Redirection;
import org.jclouds.http.annotation.ServerError;
import org.jclouds.logging.Logger;
import org.jclouds.rest.config.JaxrsModule;
import com.google.inject.AbstractModule;
import javax.inject.Inject;
import com.google.inject.Provides;
import com.google.inject.Scopes;
import javax.inject.Singleton;
import javax.inject.Named;
/**
* Configures the AzureStorage connection, including logging and http transport.
@ -55,18 +44,6 @@ import javax.inject.Named;
@ConfiguresCloudConnection
@RequiresHttp
public class RestAzureStorageConnectionModule extends AbstractModule {
@Resource
protected Logger logger = Logger.NULL;
@Inject
@Named(HttpConstants.PROPERTY_HTTP_ADDRESS)
String address;
@Inject
@Named(HttpConstants.PROPERTY_HTTP_PORT)
int port;
@Inject
@Named(HttpConstants.PROPERTY_HTTP_SECURE)
boolean isSecure;
@Override
protected void configure() {
@ -74,10 +51,6 @@ public class RestAzureStorageConnectionModule extends AbstractModule {
bind(SharedKeyAuthentication.class).in(Scopes.SINGLETON);
bindErrorHandlers();
bindRetryHandlers();
requestInjection(this);
logger
.info("AzureStorage Context = %s://%s:%s", (isSecure ? "https" : "http"), address,
port);
}
protected void bindErrorHandlers() {
@ -92,15 +65,4 @@ public class RestAzureStorageConnectionModule extends AbstractModule {
protected void bindRetryHandlers() {
}
@Singleton
@Provides
protected URI provideAddress(@Named(HttpConstants.PROPERTY_HTTP_ADDRESS) String address,
@Named(HttpConstants.PROPERTY_HTTP_PORT) int port,
@Named(HttpConstants.PROPERTY_HTTP_SECURE) boolean isSecure)
throws MalformedURLException {
return URI.create(String.format("%1$s://%2$s:%3$s", isSecure ? "https" : "http", address,
port));
}
}

View File

@ -24,24 +24,15 @@
package org.jclouds.azure.storage.queue;
import static com.google.common.base.Preconditions.checkNotNull;
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 static org.jclouds.http.pool.PoolConstants.PROPERTY_POOL_IO_WORKER_THREADS;
import static org.jclouds.http.pool.PoolConstants.PROPERTY_POOL_MAX_CONNECTIONS;
import static org.jclouds.http.pool.PoolConstants.PROPERTY_POOL_MAX_CONNECTION_REUSE;
import static org.jclouds.http.pool.PoolConstants.PROPERTY_POOL_MAX_SESSION_FAILURES;
import static org.jclouds.http.pool.PoolConstants.PROPERTY_POOL_REQUEST_INVOKER_THREADS;
import java.net.URI;
import java.util.List;
import java.util.Properties;
import org.jclouds.azure.storage.queue.config.AzureQueueContextModule;
import org.jclouds.azure.storage.queue.config.RestAzureQueueConnectionModule;
import org.jclouds.azure.storage.queue.reference.AzureQueueConstants;
import org.jclouds.azure.storage.reference.AzureStorageConstants;
import org.jclouds.azure.storage.xml.config.AzureStorageParserModule;
import org.jclouds.cloud.CloudContextBuilder;
import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule;
import org.jclouds.logging.jdk.config.JDKLoggingModule;
@ -62,52 +53,47 @@ import com.google.inject.Module;
* @author Adrian Cole
* @see AzureQueueContext
*/
public class AzureQueueContextBuilder extends
CloudContextBuilder<AzureQueueContext> {
public class AzureQueueContextBuilder extends CloudContextBuilder<AzureQueueContext> {
public AzureQueueContextBuilder(Properties props) {
super(props);
properties.setProperty(AzureQueueConstants.PROPERTY_AZUREQUEUE_ENDPOINT,
"https://{account}.blob.core.windows.net");
}
public static AzureQueueContextBuilder newBuilder(String id, String secret) {
Properties properties = new Properties();
properties.setProperty(PROPERTY_HTTP_ADDRESS, id + ".queue.core.windows.net");
properties.setProperty(PROPERTY_HTTP_SECURE, "true");
properties.setProperty(PROPERTY_SAX_DEBUG, "false");
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");
AzureQueueContextBuilder builder = new AzureQueueContextBuilder(properties);
builder.authenticate(id, secret);
return builder;
}
@Override
public CloudContextBuilder<AzureQueueContext> withEndpoint(URI endpoint) {
properties.setProperty(AzureQueueConstants.PROPERTY_AZUREQUEUE_ENDPOINT, checkNotNull(
endpoint, "endpoint").toString());
return this;
}
public void authenticate(String id, String secret) {
properties.setProperty(AzureStorageConstants.PROPERTY_AZURESTORAGE_ACCOUNT, checkNotNull(id,
"azureStorageAccount"));
properties.setProperty(AzureStorageConstants.PROPERTY_AZURESTORAGE_KEY, checkNotNull(secret,
"azureStorageKey"));
String endpoint = properties.getProperty(AzureQueueConstants.PROPERTY_AZUREQUEUE_ENDPOINT);
properties.setProperty(AzureQueueConstants.PROPERTY_AZUREQUEUE_ENDPOINT, endpoint.replaceAll(
"\\{account\\}", id));
}
public AzureQueueContext buildContext() {
return buildInjector().getInstance(AzureQueueContext.class);
}
protected void addParserModule(List<Module> modules) {
modules.add(new AzureStorageParserModule());
}
protected void addContextModule(List<Module> modules) {
modules.add(new AzureQueueContextModule());
}
protected void addConnectionModule(List<Module> modules) {
protected void addApiModule(List<Module> modules) {
modules.add(new RestAzureQueueConnectionModule());
}

View File

@ -0,0 +1,12 @@
package org.jclouds.azure.storage.queue.reference;
import org.jclouds.azure.storage.reference.AzureStorageConstants;
/**
* Configuration properties and constants used in Azure Blob connections.
*
* @author Adrian Cole
*/
public interface AzureQueueConstants extends AzureStorageConstants {
public static final String PROPERTY_AZUREQUEUE_ENDPOINT = "jclouds.azurequeue.endpoint";
}

View File

@ -35,7 +35,6 @@ import javax.ws.rs.HttpMethod;
import org.jclouds.azure.storage.options.CreateOptions;
import org.jclouds.azure.storage.options.ListOptions;
import org.jclouds.azure.storage.queue.xml.config.AzureQueueParserModule;
import org.jclouds.azure.storage.reference.AzureStorageConstants;
import org.jclouds.concurrent.WithinThreadExecutorService;
import org.jclouds.concurrent.config.ExecutorServiceModule;
@ -46,13 +45,13 @@ import org.jclouds.http.functions.ParseSax;
import org.jclouds.http.functions.ReturnTrueIf2xx;
import org.jclouds.rest.JaxrsAnnotationProcessor;
import org.jclouds.rest.config.JaxrsModule;
import org.jclouds.util.Jsr330;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableMultimap;
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import org.jclouds.util.Jsr330;
/**
* Tests behavior of {@code AzureQueueConnection}
@ -164,14 +163,13 @@ public class AzureQueueConnectionTest {
@BeforeClass
void setupFactory() {
factory = Guice.createInjector(
new AzureQueueParserModule(),
new AbstractModule() {
@Override
protected void configure() {
bind(URI.class).toInstance(URI.create("http://localhost:8080"));
bindConstant().annotatedWith(
Jsr330.named(AzureStorageConstants.PROPERTY_AZURESTORAGE_ACCOUNT)).to(
"user");
Jsr330.named(AzureStorageConstants.PROPERTY_AZURESTORAGE_ACCOUNT))
.to("user");
bindConstant().annotatedWith(
Jsr330.named(AzureStorageConstants.PROPERTY_AZURESTORAGE_KEY)).to(
HttpUtils.toBase64String("key".getBytes()));

View File

@ -31,6 +31,7 @@ import java.util.Properties;
import java.util.concurrent.ConcurrentHashMap;
import javax.annotation.Resource;
import javax.inject.Inject;
import org.jclouds.blobstore.BlobMap;
import org.jclouds.blobstore.BlobStore;
@ -50,7 +51,6 @@ import org.jclouds.logging.Logger;
import org.testng.ITestContext;
import com.google.inject.AbstractModule;
import javax.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.inject.Module;
@ -113,11 +113,11 @@ public class StubTestInitializer
}
public static interface BlobMapFactory {
BlobMap<BlobMetadata, Blob<BlobMetadata>> createMapView(String bucket);
BlobMap<BlobMetadata, Blob<BlobMetadata>> createMapView(String container);
}
public static interface InputStreamMapFactory {
InputStreamMap<BlobMetadata> createMapView(String bucket);
InputStreamMap<BlobMetadata> createMapView(String container);
}
public static class GuiceStubBlobStoreContext implements StubBlobStoreContext {
@ -125,33 +125,33 @@ public class StubTestInitializer
@Resource
private Logger logger = Logger.NULL;
private final Injector injector;
private final InputStreamMapFactory s3InputStreamMapFactory;
private final BlobMapFactory s3ObjectMapFactory;
private final InputStreamMapFactory inputStreamMapFactory;
private final BlobMapFactory objectMapFactory;
private final Closer closer;
@Inject
private GuiceStubBlobStoreContext(Injector injector, Closer closer,
BlobMapFactory s3ObjectMapFactory, InputStreamMapFactory s3InputStreamMapFactory) {
BlobMapFactory objectMapFactory, InputStreamMapFactory inputStreamMapFactory) {
this.injector = injector;
this.s3InputStreamMapFactory = s3InputStreamMapFactory;
this.s3ObjectMapFactory = s3ObjectMapFactory;
this.inputStreamMapFactory = inputStreamMapFactory;
this.objectMapFactory = objectMapFactory;
this.closer = closer;
}
/**
* {@inheritDoc}
*/
public InputStreamMap<BlobMetadata> createInputStreamMap(String bucket) {
getApi().createContainer(bucket);
return s3InputStreamMapFactory.createMapView(bucket);
public InputStreamMap<BlobMetadata> createInputStreamMap(String container) {
getApi().createContainer(container);
return inputStreamMapFactory.createMapView(container);
}
/**
* {@inheritDoc}
*/
public BlobMap<BlobMetadata, Blob<BlobMetadata>> createBlobMap(String bucket) {
getApi().createContainer(bucket);
return s3ObjectMapFactory.createMapView(bucket);
public BlobMap<BlobMetadata, Blob<BlobMetadata>> createBlobMap(String container) {
getApi().createContainer(container);
return objectMapFactory.createMapView(container);
}
/**
@ -205,9 +205,6 @@ public class StubTestInitializer
return buildInjector().getInstance(StubBlobStoreContext.class);
}
protected void addParserModule(List<Module> modules) {
}
protected void addContextModule(List<Module> modules) {
modules.add(new AbstractModule() {
@ -234,7 +231,7 @@ public class StubTestInitializer
});
}
protected void addConnectionModule(List<Module> modules) {
protected void addApiModule(List<Module> modules) {
modules.add(new AbstractModule() {
@Override
@ -246,6 +243,12 @@ public class StubTestInitializer
});
}
@Override
public CloudContextBuilder<StubBlobStoreContext> withEndpoint(URI endpoint) {
// throw org.jboss.util.NotImplementedException("FIXME NYI withEndpoint");
return null;
}
}
public static class StubInputStreamMap extends

View File

@ -69,6 +69,9 @@ public class BaseBlobIntegrationTest<S extends BlobStore<C, M, B>, C extends Con
String key = "apples";
DateTime before = new DateTime().minusSeconds(1);
// first create the object
addObjectAndValidateContent(containerName, key);
// now, modify it
addObjectAndValidateContent(containerName, key);
DateTime after = new DateTime().plusSeconds(1);

View File

@ -24,12 +24,9 @@
package org.jclouds.cloud;
import static com.google.common.base.Preconditions.checkNotNull;
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_RELAX_HOSTNAME;
import static org.jclouds.http.HttpConstants.PROPERTY_HTTP_SECURE;
import static org.jclouds.http.HttpConstants.PROPERTY_JSON_DEBUG;
import static org.jclouds.http.HttpConstants.PROPERTY_SAX_DEBUG;
import static org.jclouds.http.pool.PoolConstants.PROPERTY_POOL_IO_WORKER_THREADS;
@ -38,6 +35,7 @@ import static org.jclouds.http.pool.PoolConstants.PROPERTY_POOL_MAX_CONNECTION_R
import static org.jclouds.http.pool.PoolConstants.PROPERTY_POOL_MAX_SESSION_FAILURES;
import static org.jclouds.http.pool.PoolConstants.PROPERTY_POOL_REQUEST_INVOKER_THREADS;
import java.net.URI;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@ -45,7 +43,6 @@ import java.util.Properties;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import org.jclouds.command.ConfiguresResponseTransformer;
import org.jclouds.concurrent.SingleThreaded;
import org.jclouds.concurrent.WithinThreadExecutorService;
import org.jclouds.concurrent.config.ConfiguresExecutorService;
@ -55,6 +52,7 @@ import org.jclouds.http.config.ConfiguresHttpCommandExecutorService;
import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule;
import org.jclouds.logging.config.LoggingModule;
import org.jclouds.logging.jdk.config.JDKLoggingModule;
import org.jclouds.util.Jsr330;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Predicate;
@ -64,7 +62,6 @@ import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Module;
import org.jclouds.util.Jsr330;
/**
* Creates {@link CloudContext} or {@link Injector} instances based on the most commonly requested
@ -81,9 +78,6 @@ import org.jclouds.util.Jsr330;
*/
public abstract class CloudContextBuilder<X extends CloudContext<?>> {
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);
@ -91,11 +85,6 @@ public abstract class CloudContextBuilder<X extends CloudContext<?>> {
this.properties = properties;
}
public CloudContextBuilder<X> withHttpAddress(String httpAddress) {
properties.setProperty(PROPERTY_HTTP_ADDRESS, httpAddress);
return this;
}
public CloudContextBuilder<X> withSaxDebug() {
properties.setProperty(PROPERTY_SAX_DEBUG, "true");
return this;
@ -129,23 +118,14 @@ public abstract class CloudContextBuilder<X extends CloudContext<?>> {
return this;
}
public CloudContextBuilder<X> withHttpPort(int httpPort) {
properties.setProperty(PROPERTY_HTTP_PORT, Integer.toString(httpPort));
return this;
}
public CloudContextBuilder<X> withHttpSecure(boolean httpSecure) {
properties.setProperty(PROPERTY_HTTP_SECURE, Boolean.toString(httpSecure));
return this;
}
public CloudContextBuilder<X> withPoolMaxConnectionReuse(int poolMaxConnectionReuse) {
properties.setProperty(PROPERTY_POOL_MAX_CONNECTION_REUSE, Integer
.toString(poolMaxConnectionReuse));
return this;
}
public abstract CloudContextBuilder<X> withEndpoint(URI endpoint);
public CloudContextBuilder<X> withPoolMaxSessionFailures(int poolMaxSessionFailures) {
properties.setProperty(PROPERTY_POOL_MAX_SESSION_FAILURES, Integer
.toString(poolMaxSessionFailures));
@ -184,12 +164,8 @@ public abstract class CloudContextBuilder<X extends CloudContext<?>> {
public Injector buildInjector() {
useDefaultPortIfNotPresent(properties);
addLoggingModuleIfNotPresent(modules);
addParserModuleIfNotPresent(modules);
addConnectionModuleIfNotPresent(modules);
addHttpModuleIfNeededAndNotPresent(modules);
@ -207,17 +183,6 @@ public abstract class CloudContextBuilder<X extends CloudContext<?>> {
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());
@ -265,20 +230,10 @@ public abstract class CloudContextBuilder<X extends CloudContext<?>> {
}
})) {
addConnectionModule(modules);
addApiModule(modules);
}
}
protected void addParserModuleIfNotPresent(List<Module> modules) {
if (!Iterables.any(modules, new Predicate<Module>() {
public boolean apply(Module input) {
return input.getClass().isAnnotationPresent(ConfiguresResponseTransformer.class);
}
}))
addParserModule(modules);
}
@VisibleForTesting
public Properties getProperties() {
return properties;
@ -288,10 +243,8 @@ public abstract class CloudContextBuilder<X extends CloudContext<?>> {
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);
protected abstract void addApiModule(List<Module> modules);
}

View File

@ -29,9 +29,6 @@ package org.jclouds.http;
* @author Adrian Cole
*/
public interface HttpConstants {
public static final String PROPERTY_HTTP_SECURE = "jclouds.http.secure";
public static final String PROPERTY_HTTP_PORT = "jclouds.http.port";
public static final String PROPERTY_HTTP_ADDRESS = "jclouds.http.address";
public static final String PROPERTY_HTTP_MAX_RETRIES = "jclouds.http.max-retries";
public static final String PROPERTY_HTTP_MAX_REDIRECTS = "jclouds.http.max-redirects";
public static final String PROPERTY_SAX_DEBUG = "jclouds.http.sax.debug";

View File

@ -92,7 +92,7 @@ public class CloudContextBuilderTest {
}
@Override
protected void addConnectionModule(List<Module> modules) {
protected void addApiModule(List<Module> modules) {
modules.add(new Module() {
public void configure(Binder arg0) {
}
@ -108,15 +108,12 @@ public class CloudContextBuilderTest {
}
@Override
protected void addParserModule(List<Module> modules) {
modules.add(new Module() {
public void configure(Binder arg0) {
}
});
public void authenticate(String id, String secret) {
}
@Override
public void authenticate(String id, String secret) {
public CloudContextBuilder<TestCloudContext> withEndpoint(URI endpoint) {
return this;
}
}
@ -190,10 +187,7 @@ public class CloudContextBuilderTest {
public void testBuilder() {
String id = "awsAccessKeyId";
String secret = "awsSecretAccessKey";
String httpAddress = "httpAddress";
int httpMaxRetries = 9875;
int httpPort = 3827;
boolean httpSecure = false;
int poolIoWorkerThreads = 2727;
int poolMaxConnectionReuse = 3932;
int poolMaxConnections = 3382;
@ -214,10 +208,7 @@ public class CloudContextBuilderTest {
};
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);

View File

@ -39,6 +39,7 @@ import org.jclouds.lifecycle.Closer;
import org.jclouds.logging.jdk.config.JDKLoggingModule;
import org.jclouds.rest.RestClientFactory;
import org.jclouds.rest.config.JaxrsModule;
import org.jclouds.util.Jsr330;
import org.jclouds.util.Utils;
import org.mortbay.jetty.Handler;
import org.mortbay.jetty.Request;
@ -54,7 +55,6 @@ import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Module;
import org.jclouds.util.Jsr330;
public abstract class BaseJettyTest {
protected static final String XML = "<foo><bar>whoppers</bar></foo>";
@ -139,9 +139,6 @@ public abstract class BaseJettyTest {
server2.start();
final Properties properties = new Properties();
properties.put(HttpConstants.PROPERTY_HTTP_ADDRESS, "localhost");
properties.put(HttpConstants.PROPERTY_HTTP_PORT, testPort + "");
properties.put(HttpConstants.PROPERTY_HTTP_SECURE, "false");
addConnectionProperties(properties);
List<Module> modules = Lists.newArrayList(new AbstractModule() {

View File

@ -31,13 +31,12 @@ import org.jclouds.concurrent.SingleThreadCompatible;
import org.jclouds.concurrent.WithinThreadExecutorService;
import org.jclouds.concurrent.config.ExecutorServiceModule;
import org.jclouds.gae.GaeHttpCommandExecutorService;
import org.jclouds.http.HttpConstants;
import org.jclouds.http.HttpCommandExecutorService;
import org.jclouds.util.Jsr330;
import org.testng.annotations.Test;
import com.google.inject.Guice;
import com.google.inject.Injector;
import org.jclouds.util.Jsr330;
/**
* Tests the ability to configure a {@link GaeHttpCommandExecutorService}
@ -49,9 +48,6 @@ public class GaeHttpCommandExecutorServiceModuleTest {
public void testConfigureBindsClient() {
final Properties properties = new Properties();
properties.put(HttpConstants.PROPERTY_HTTP_ADDRESS, "localhost");
properties.put(HttpConstants.PROPERTY_HTTP_PORT, "8088");
properties.put(HttpConstants.PROPERTY_HTTP_SECURE, "false");
Injector i = Guice.createInjector(
new ExecutorServiceModule(new WithinThreadExecutorService()),

View File

@ -60,8 +60,9 @@ public class CloudFilesCDNContextBuilder extends RackspaceContextBuilder<CloudFi
return builder;
}
protected void addConnectionModule(List<Module> modules) {
super.addConnectionModule(modules);
@Override
public void addApiModule(List<Module> modules) {
super.addApiModule(modules);
modules.add(new RestCloudFilesCDNConnectionModule());
}
@ -70,11 +71,6 @@ public class CloudFilesCDNContextBuilder extends RackspaceContextBuilder<CloudFi
// TODO
}
@Override
protected void addParserModule(List<Module> modules) {
// TODO
}
@Override
public CloudFilesCDNContext buildContext() {
return buildInjector().getInstance(CloudFilesCDNContext.class);

View File

@ -64,8 +64,9 @@ public class CloudFilesContextBuilder extends RackspaceContextBuilder<CloudFiles
return builder;
}
protected void addConnectionModule(List<Module> modules) {
super.addConnectionModule(modules);
@Override
public void addApiModule(List<Module> modules) {
super.addApiModule(modules);
modules.add(new RestCloudFilesBlobStoreModule());
}
@ -74,11 +75,6 @@ public class CloudFilesContextBuilder extends RackspaceContextBuilder<CloudFiles
modules.add(new CloudFilesContextModule());
}
@Override
protected void addParserModule(List<Module> modules) {
// TODO
}
@Override
public CloudFilesContext buildContext() {
return buildInjector().getInstance(CloudFilesContext.class);

View File

@ -23,7 +23,6 @@
*/
package org.jclouds.rackspace.cloudfiles;
import static org.jclouds.http.HttpConstants.PROPERTY_HTTP_ADDRESS;
import static org.testng.Assert.assertEquals;
import java.net.URI;
@ -33,7 +32,7 @@ import java.util.List;
import org.jclouds.cloud.CloudContext;
import org.jclouds.rackspace.cloudfiles.config.RestCloudFilesCDNConnectionModule;
import org.jclouds.rackspace.cloudfiles.internal.GuiceCloudFilesCDNContext;
import org.jclouds.rackspace.config.RackspaceAuthenticationModule;
import org.jclouds.rackspace.config.RestRackspaceAuthenticationModule;
import org.jclouds.rackspace.reference.RackspaceConstants;
import org.testng.annotations.Test;
@ -50,7 +49,8 @@ public class CloudFilesCDNContextBuilderTest {
public void testNewBuilder() {
CloudFilesCDNContextBuilder builder = CloudFilesCDNContextBuilder.newBuilder("id", "secret");
assertEquals(builder.getProperties().getProperty(PROPERTY_HTTP_ADDRESS), "api.mosso.com");
assertEquals(builder.getProperties().getProperty(
RackspaceConstants.PROPERTY_RACKSPACE_ENDPOINT), "https://api.mosso.com");
assertEquals(builder.getProperties().getProperty(RackspaceConstants.PROPERTY_RACKSPACE_USER),
"id");
assertEquals(builder.getProperties().getProperty(RackspaceConstants.PROPERTY_RACKSPACE_KEY),
@ -62,7 +62,7 @@ public class CloudFilesCDNContextBuilderTest {
"secret").buildContext();
assertEquals(context.getClass(), GuiceCloudFilesCDNContext.class);
assertEquals(context.getAccount(), "id");
assertEquals(context.getEndPoint(), URI.create("https://api.mosso.com:443"));
assertEquals(context.getEndPoint(), URI.create("https://api.mosso.com"));
}
public void testBuildInjector() {
@ -75,13 +75,13 @@ public class CloudFilesCDNContextBuilderTest {
CloudFilesCDNContextBuilder builder = CloudFilesCDNContextBuilder.newBuilder("id", "secret");
builder.addContextModule(modules);
assertEquals(modules.size(), 1);
assertEquals(modules.get(0).getClass(), RackspaceAuthenticationModule.class);
assertEquals(modules.get(0).getClass(), RestRackspaceAuthenticationModule.class);
}
protected void addConnectionModule() {
List<Module> modules = new ArrayList<Module>();
CloudFilesCDNContextBuilder builder = CloudFilesCDNContextBuilder.newBuilder("id", "secret");
builder.addConnectionModule(modules);
builder.addApiModule(modules);
assertEquals(modules.size(), 1);
assertEquals(modules.get(0).getClass(), RestCloudFilesCDNConnectionModule.class);
}

View File

@ -24,7 +24,6 @@
package org.jclouds.rackspace.cloudfiles;
import static org.jclouds.blobstore.reference.BlobStoreConstants.PROPERTY_USER_METADATA_PREFIX;
import static org.jclouds.http.HttpConstants.PROPERTY_HTTP_ADDRESS;
import static org.testng.Assert.assertEquals;
import java.net.URI;
@ -38,7 +37,7 @@ import org.jclouds.blobstore.functions.ParseBlobMetadataFromHeaders.BlobMetadata
import org.jclouds.cloud.CloudContext;
import org.jclouds.rackspace.cloudfiles.config.RestCloudFilesBlobStoreModule;
import org.jclouds.rackspace.cloudfiles.internal.GuiceCloudFilesContext;
import org.jclouds.rackspace.config.RackspaceAuthenticationModule;
import org.jclouds.rackspace.config.RestRackspaceAuthenticationModule;
import org.jclouds.rackspace.reference.RackspaceConstants;
import org.testng.annotations.Test;
@ -59,7 +58,8 @@ public class CloudFilesContextBuilderTest {
CloudFilesContextBuilder builder = CloudFilesContextBuilder.newBuilder("id", "secret");
assertEquals(builder.getProperties().getProperty(PROPERTY_USER_METADATA_PREFIX),
"X-Object-Meta-");
assertEquals(builder.getProperties().getProperty(PROPERTY_HTTP_ADDRESS), "api.mosso.com");
assertEquals(builder.getProperties().getProperty(
RackspaceConstants.PROPERTY_RACKSPACE_ENDPOINT), "https://api.mosso.com");
assertEquals(builder.getProperties().getProperty(RackspaceConstants.PROPERTY_RACKSPACE_USER),
"id");
assertEquals(builder.getProperties().getProperty(RackspaceConstants.PROPERTY_RACKSPACE_KEY),
@ -71,7 +71,7 @@ public class CloudFilesContextBuilderTest {
"secret").buildContext();
assertEquals(context.getClass(), GuiceCloudFilesContext.class);
assertEquals(context.getAccount(), "id");
assertEquals(context.getEndPoint(), URI.create("https://api.mosso.com:443"));
assertEquals(context.getEndPoint(), URI.create("https://api.mosso.com"));
}
public void testBuildInjector() {
@ -91,13 +91,13 @@ public class CloudFilesContextBuilderTest {
CloudFilesContextBuilder builder = CloudFilesContextBuilder.newBuilder("id", "secret");
builder.addContextModule(modules);
assertEquals(modules.size(), 1);
assertEquals(modules.get(0).getClass(), RackspaceAuthenticationModule.class);
assertEquals(modules.get(0).getClass(), RestRackspaceAuthenticationModule.class);
}
protected void addConnectionModule() {
List<Module> modules = new ArrayList<Module>();
CloudFilesContextBuilder builder = CloudFilesContextBuilder.newBuilder("id", "secret");
builder.addConnectionModule(modules);
builder.addApiModule(modules);
assertEquals(modules.size(), 1);
assertEquals(modules.get(0).getClass(), RestCloudFilesBlobStoreModule.class);
}

View File

@ -47,8 +47,7 @@ import com.google.inject.Module;
* @author Adrian Cole
* @see CloudServersContext
*/
public class CloudServersContextBuilder extends
RackspaceContextBuilder<CloudServersContext> {
public class CloudServersContextBuilder extends RackspaceContextBuilder<CloudServersContext> {
public CloudServersContextBuilder(Properties props) {
super(props);
@ -61,20 +60,15 @@ public class CloudServersContextBuilder extends
return builder;
}
protected void addConnectionModule(List<Module> modules) {
super.addConnectionModule(modules);
@Override
public void addApiModule(List<Module> modules) {
super.addApiModule(modules);
modules.add(new RestCloudServersConnectionModule());
}
@Override
protected void addContextModule(List<Module> modules) {
//TODO
}
@Override
protected void addParserModule(List<Module> modules) {
//TODO
// TODO
}
@Override

View File

@ -24,19 +24,11 @@
package org.jclouds.rackspace;
import static com.google.common.base.Preconditions.checkNotNull;
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 static org.jclouds.http.pool.PoolConstants.PROPERTY_POOL_IO_WORKER_THREADS;
import static org.jclouds.http.pool.PoolConstants.PROPERTY_POOL_MAX_CONNECTIONS;
import static org.jclouds.http.pool.PoolConstants.PROPERTY_POOL_MAX_CONNECTION_REUSE;
import static org.jclouds.http.pool.PoolConstants.PROPERTY_POOL_MAX_SESSION_FAILURES;
import static org.jclouds.http.pool.PoolConstants.PROPERTY_POOL_REQUEST_INVOKER_THREADS;
import static org.jclouds.rackspace.reference.RackspaceConstants.PROPERTY_RACKSPACE_ENDPOINT;
import static org.jclouds.rackspace.reference.RackspaceConstants.PROPERTY_RACKSPACE_KEY;
import static org.jclouds.rackspace.reference.RackspaceConstants.PROPERTY_RACKSPACE_USER;
import java.net.URI;
import java.util.List;
import java.util.Properties;
@ -44,7 +36,7 @@ import org.jclouds.cloud.CloudContext;
import org.jclouds.cloud.CloudContextBuilder;
import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule;
import org.jclouds.logging.jdk.config.JDKLoggingModule;
import org.jclouds.rackspace.config.RackspaceAuthenticationModule;
import org.jclouds.rackspace.config.RestRackspaceAuthenticationModule;
import com.google.inject.Injector;
import com.google.inject.Module;
@ -67,16 +59,14 @@ public abstract class RackspaceContextBuilder<X extends CloudContext<?>> extends
public RackspaceContextBuilder(Properties props) {
super(props);
properties.setProperty(PROPERTY_HTTP_ADDRESS, "api.mosso.com");
properties.setProperty(PROPERTY_HTTP_SECURE, "true");
properties.setProperty(PROPERTY_SAX_DEBUG, "false");
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");
properties.setProperty(PROPERTY_RACKSPACE_ENDPOINT, "https://api.mosso.com");
}
@Override
public CloudContextBuilder<X> withEndpoint(URI endpoint) {
properties.setProperty(PROPERTY_RACKSPACE_ENDPOINT, checkNotNull(endpoint, "endpoint")
.toString());
return this;
}
public void authenticate(String id, String secret) {
@ -84,8 +74,8 @@ public abstract class RackspaceContextBuilder<X extends CloudContext<?>> extends
properties.setProperty(PROPERTY_RACKSPACE_KEY, checkNotNull(secret, "key"));
}
protected void addConnectionModule(List<Module> modules) {
modules.add(new RackspaceAuthenticationModule());
public void addApiModule(List<Module> modules) {
modules.add(new RestRackspaceAuthenticationModule());
}
}

View File

@ -23,13 +23,15 @@
*/
package org.jclouds.rackspace.config;
import static org.jclouds.rackspace.reference.RackspaceConstants.PROPERTY_RACKSPACE_ENDPOINT;
import static org.jclouds.rackspace.reference.RackspaceConstants.PROPERTY_RACKSPACE_KEY;
import static org.jclouds.rackspace.reference.RackspaceConstants.PROPERTY_RACKSPACE_USER;
import java.net.MalformedURLException;
import java.net.URI;
import org.jclouds.http.HttpConstants;
import javax.inject.Named;
import javax.inject.Singleton;
import org.jclouds.http.RequiresHttp;
import org.jclouds.rackspace.Authentication;
import org.jclouds.rackspace.CDN;
@ -42,8 +44,6 @@ import org.jclouds.rest.config.JaxrsModule;
import com.google.inject.AbstractModule;
import com.google.inject.Provides;
import javax.inject.Singleton;
import javax.inject.Named;
/**
* Configures the Rackspace authentication service connection, including logging and http transport.
@ -51,7 +51,7 @@ import javax.inject.Named;
* @author Adrian Cole
*/
@RequiresHttp
public class RackspaceAuthenticationModule extends AbstractModule {
public class RestRackspaceAuthenticationModule extends AbstractModule {
@Override
protected void configure() {
@ -60,6 +60,13 @@ public class RackspaceAuthenticationModule extends AbstractModule {
bindRetryHandlers();
}
@Provides
@Singleton
@Authentication
protected URI provideAuthenticationURI(@Named(PROPERTY_RACKSPACE_ENDPOINT) String endpoint) {
return URI.create(endpoint);
}
@Provides
@Singleton
protected AuthenticationResponse provideAuthenticationResponse(
@ -107,16 +114,4 @@ public class RackspaceAuthenticationModule extends AbstractModule {
// TODO retry on 401 by AuthenticateRequest.update()
}
@Singleton
@Provides
@Authentication
protected URI provideAddress(@Named(HttpConstants.PROPERTY_HTTP_ADDRESS) String address,
@Named(HttpConstants.PROPERTY_HTTP_PORT) int port,
@Named(HttpConstants.PROPERTY_HTTP_SECURE) boolean isSecure)
throws MalformedURLException {
return URI.create(String.format("%1$s://%2$s:%3$s", isSecure ? "https" : "http", address,
port));
}
}

View File

@ -29,6 +29,7 @@ package org.jclouds.rackspace.reference;
* @author Adrian Cole
*/
public interface RackspaceConstants {
public static final String PROPERTY_RACKSPACE_ENDPOINT = "jclouds.rackspace.endpoint";
public static final String PROPERTY_RACKSPACE_USER = "jclouds.rackspace.user";
public static final String PROPERTY_RACKSPACE_KEY = "jclouds.rackspace.key";
}