mirror of https://github.com/apache/jclouds.git
Issue 103, Issue 73: cleaned up injection and portability layer, removing need for most internal classes and facilitating shared testing stubs across providers
git-svn-id: http://jclouds.googlecode.com/svn/trunk@1940 3d8758e0-26b5-11de-8745-db77d3ebf521
This commit is contained in:
parent
9cfc6b0420
commit
502dc92836
|
@ -23,6 +23,7 @@
|
|||
*/
|
||||
package org.jclouds.aws.s3;
|
||||
|
||||
import org.jclouds.aws.s3.domain.BucketMetadata;
|
||||
import org.jclouds.aws.s3.domain.ObjectMetadata;
|
||||
import org.jclouds.aws.s3.domain.S3Object;
|
||||
import org.jclouds.blobstore.BlobStoreContext;
|
||||
|
@ -39,6 +40,7 @@ import org.jclouds.blobstore.BlobStoreContext;
|
|||
* @author Adrian Cole
|
||||
*
|
||||
*/
|
||||
public interface S3Context extends BlobStoreContext<S3BlobStore, ObjectMetadata, S3Object> {
|
||||
public interface S3Context extends
|
||||
BlobStoreContext<S3BlobStore, BucketMetadata, ObjectMetadata, S3Object> {
|
||||
|
||||
}
|
|
@ -31,16 +31,21 @@ import static org.jclouds.blobstore.reference.BlobStoreConstants.PROPERTY_USER_M
|
|||
import java.net.URI;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
|
||||
import org.jclouds.aws.s3.config.RestS3ConnectionModule;
|
||||
import org.jclouds.aws.s3.config.S3ContextModule;
|
||||
import org.jclouds.aws.s3.domain.BucketMetadata;
|
||||
import org.jclouds.aws.s3.domain.ObjectMetadata;
|
||||
import org.jclouds.aws.s3.domain.S3Object;
|
||||
import org.jclouds.aws.s3.reference.S3Constants;
|
||||
import org.jclouds.cloud.CloudContextBuilder;
|
||||
import org.jclouds.blobstore.BlobStoreContextBuilder;
|
||||
import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule;
|
||||
import org.jclouds.logging.jdk.config.JDKLoggingModule;
|
||||
|
||||
import com.google.inject.Injector;
|
||||
import com.google.inject.Module;
|
||||
import com.google.inject.TypeLiteral;
|
||||
|
||||
/**
|
||||
* Creates {@link S3Context} or {@link Injector} instances based on the most commonly requested
|
||||
|
@ -55,44 +60,110 @@ import com.google.inject.Module;
|
|||
* @author Adrian Cole, Andrew Newdigate
|
||||
* @see S3Context
|
||||
*/
|
||||
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-");
|
||||
|
||||
}
|
||||
public class S3ContextBuilder extends
|
||||
BlobStoreContextBuilder<S3BlobStore, BucketMetadata, ObjectMetadata, S3Object> {
|
||||
|
||||
@Override
|
||||
public CloudContextBuilder<S3Context> withEndpoint(URI endpoint) {
|
||||
properties.setProperty(S3Constants.PROPERTY_S3_ENDPOINT, checkNotNull(endpoint, "endpoint")
|
||||
.toString());
|
||||
return this;
|
||||
public S3Context buildContext() {
|
||||
return this.buildInjector().getInstance(S3Context.class);
|
||||
}
|
||||
|
||||
public static S3ContextBuilder newBuilder(String id, String secret) {
|
||||
Properties properties = new Properties();
|
||||
S3ContextBuilder builder = new S3ContextBuilder(properties);
|
||||
builder.authenticate(id, secret);
|
||||
return builder;
|
||||
public S3ContextBuilder(Properties props) {
|
||||
super(new TypeLiteral<S3BlobStore>() {
|
||||
}, new TypeLiteral<BucketMetadata>() {
|
||||
}, new TypeLiteral<ObjectMetadata>() {
|
||||
}, new TypeLiteral<S3Object>() {
|
||||
}, props);
|
||||
properties.setProperty(S3Constants.PROPERTY_S3_ENDPOINT, "https://s3.amazonaws.com");
|
||||
properties.setProperty(PROPERTY_USER_METADATA_PREFIX, "x-amz-meta-");
|
||||
}
|
||||
|
||||
public void authenticate(String id, String secret) {
|
||||
public S3ContextBuilder(String id, String secret) {
|
||||
this(new Properties());
|
||||
properties.setProperty(PROPERTY_AWS_ACCESSKEYID, checkNotNull(id, "awsAccessKeyId"));
|
||||
properties.setProperty(PROPERTY_AWS_SECRETACCESSKEY, checkNotNull(secret,
|
||||
"awsSecretAccessKey"));
|
||||
}
|
||||
|
||||
public S3Context buildContext() {
|
||||
return buildInjector().getInstance(S3Context.class);
|
||||
@Override
|
||||
public S3ContextBuilder relaxSSLHostname() {
|
||||
return (S3ContextBuilder) super.relaxSSLHostname();
|
||||
}
|
||||
|
||||
@Override
|
||||
public S3ContextBuilder withExecutorService(ExecutorService service) {
|
||||
return (S3ContextBuilder) super.withExecutorService(service);
|
||||
}
|
||||
|
||||
@Override
|
||||
public S3ContextBuilder withHttpMaxRedirects(int httpMaxRedirects) {
|
||||
return (S3ContextBuilder) super.withHttpMaxRedirects(httpMaxRedirects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public S3ContextBuilder withHttpMaxRetries(int httpMaxRetries) {
|
||||
return (S3ContextBuilder) super.withHttpMaxRetries(httpMaxRetries);
|
||||
}
|
||||
|
||||
@Override
|
||||
public S3ContextBuilder withJsonDebug() {
|
||||
return (S3ContextBuilder) super.withJsonDebug();
|
||||
}
|
||||
|
||||
@Override
|
||||
public S3ContextBuilder withModule(Module module) {
|
||||
return (S3ContextBuilder) super.withModule(module);
|
||||
}
|
||||
|
||||
@Override
|
||||
public S3ContextBuilder withModules(Module... modules) {
|
||||
return (S3ContextBuilder) super.withModules(modules);
|
||||
}
|
||||
|
||||
@Override
|
||||
public S3ContextBuilder withPoolIoWorkerThreads(int poolIoWorkerThreads) {
|
||||
return (S3ContextBuilder) super.withPoolIoWorkerThreads(poolIoWorkerThreads);
|
||||
}
|
||||
|
||||
@Override
|
||||
public S3ContextBuilder withPoolMaxConnectionReuse(int poolMaxConnectionReuse) {
|
||||
return (S3ContextBuilder) super.withPoolMaxConnectionReuse(poolMaxConnectionReuse);
|
||||
}
|
||||
|
||||
@Override
|
||||
public S3ContextBuilder withPoolMaxConnections(int poolMaxConnections) {
|
||||
return (S3ContextBuilder) super.withPoolMaxConnections(poolMaxConnections);
|
||||
}
|
||||
|
||||
@Override
|
||||
public S3ContextBuilder withPoolMaxSessionFailures(int poolMaxSessionFailures) {
|
||||
return (S3ContextBuilder) super.withPoolMaxSessionFailures(poolMaxSessionFailures);
|
||||
}
|
||||
|
||||
@Override
|
||||
public S3ContextBuilder withPoolRequestInvokerThreads(int poolRequestInvokerThreads) {
|
||||
return (S3ContextBuilder) super.withPoolRequestInvokerThreads(poolRequestInvokerThreads);
|
||||
}
|
||||
|
||||
@Override
|
||||
public S3ContextBuilder withSaxDebug() {
|
||||
return (S3ContextBuilder) (S3ContextBuilder) super.withSaxDebug();
|
||||
}
|
||||
|
||||
@Override
|
||||
public S3ContextBuilder withEndpoint(URI endpoint) {
|
||||
properties.setProperty(S3Constants.PROPERTY_S3_ENDPOINT, checkNotNull(endpoint, "endpoint")
|
||||
.toString());
|
||||
return (S3ContextBuilder) this;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addContextModule(List<Module> modules) {
|
||||
modules.add(new S3ContextModule());
|
||||
}
|
||||
|
||||
protected void addApiModule(List<Module> modules) {
|
||||
@Override
|
||||
protected void addConnectionModule(List<Module> modules) {
|
||||
modules.add(new RestS3ConnectionModule());
|
||||
}
|
||||
|
||||
|
|
|
@ -44,15 +44,15 @@ import com.google.inject.Module;
|
|||
*/
|
||||
public class S3ContextFactory {
|
||||
|
||||
public static S3Context createS3Context(String awsAccessKeyId, String awsSecretAccessKey,
|
||||
Module... modules) {
|
||||
return S3ContextBuilder.newBuilder(awsAccessKeyId, awsSecretAccessKey).withModules(modules)
|
||||
public static S3Context createContext(
|
||||
String awsAccessKeyId, String awsSecretAccessKey, Module... modules) {
|
||||
return new S3ContextBuilder(awsAccessKeyId, awsSecretAccessKey).withModules(modules)
|
||||
.buildContext();
|
||||
}
|
||||
|
||||
public static S3Context createS3Context(URI endpoint, String awsAccessKeyId,
|
||||
String awsSecretAccessKey, Module... modules) {
|
||||
return S3ContextBuilder.newBuilder(awsAccessKeyId, awsSecretAccessKey).withEndpoint(endpoint)
|
||||
public static S3Context createContext(
|
||||
URI endpoint, String awsAccessKeyId, String awsSecretAccessKey, Module... modules) {
|
||||
return new S3ContextBuilder(awsAccessKeyId, awsSecretAccessKey).withEndpoint(endpoint)
|
||||
.withModules(modules).buildContext();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,7 +43,6 @@ import org.jclouds.http.annotation.ClientError;
|
|||
import org.jclouds.http.annotation.Redirection;
|
||||
import org.jclouds.http.annotation.ServerError;
|
||||
import org.jclouds.rest.RestClientFactory;
|
||||
import org.jclouds.rest.config.JaxrsModule;
|
||||
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Provides;
|
||||
|
@ -60,7 +59,6 @@ public class RestS3ConnectionModule extends AbstractModule {
|
|||
|
||||
@Override
|
||||
protected void configure() {
|
||||
install(new JaxrsModule());
|
||||
bind(RequestAuthorizeSignature.class).in(Scopes.SINGLETON);
|
||||
bindErrorHandlers();
|
||||
bindRetryHandlers();
|
||||
|
|
|
@ -23,19 +23,25 @@
|
|||
*/
|
||||
package org.jclouds.aws.s3.config;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Provider;
|
||||
|
||||
import org.jclouds.aws.reference.AWSConstants;
|
||||
import org.jclouds.aws.s3.S3;
|
||||
import org.jclouds.aws.s3.S3BlobStore;
|
||||
import org.jclouds.aws.s3.S3Context;
|
||||
import org.jclouds.aws.s3.domain.BucketMetadata;
|
||||
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.internal.LiveS3InputStreamMap;
|
||||
import org.jclouds.aws.s3.internal.LiveS3ObjectMap;
|
||||
import org.jclouds.blobstore.functions.ParseBlobFromHeadersAndHttpContent.BlobFactory;
|
||||
import org.jclouds.blobstore.functions.ParseContentTypeFromHeaders.BlobMetadataFactory;
|
||||
import org.jclouds.blobstore.BlobStoreContextImpl;
|
||||
import org.jclouds.blobstore.BlobMap.Factory;
|
||||
import org.jclouds.lifecycle.Closer;
|
||||
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.TypeLiteral;
|
||||
import com.google.inject.assistedinject.FactoryProvider;
|
||||
import com.google.inject.Scopes;
|
||||
|
||||
/**
|
||||
* Configures the {@link S3Context}; requires {@link S3BlobStore} bound.
|
||||
|
@ -43,28 +49,24 @@ import com.google.inject.assistedinject.FactoryProvider;
|
|||
* @author Adrian Cole
|
||||
*/
|
||||
public class S3ContextModule extends AbstractModule {
|
||||
protected final TypeLiteral<BlobMetadataFactory<ObjectMetadata>> objectMetadataFactoryLiteral = new TypeLiteral<BlobMetadataFactory<ObjectMetadata>>() {
|
||||
};
|
||||
protected final TypeLiteral<BlobFactory<ObjectMetadata, S3Object>> objectFactoryLiteral = new TypeLiteral<BlobFactory<ObjectMetadata, S3Object>>() {
|
||||
};
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
this.requireBinding(S3BlobStore.class);
|
||||
bind(GuiceS3Context.S3ObjectMapFactory.class).toProvider(
|
||||
FactoryProvider.newFactory(GuiceS3Context.S3ObjectMapFactory.class,
|
||||
LiveS3ObjectMap.class));
|
||||
bind(GuiceS3Context.S3InputStreamMapFactory.class).toProvider(
|
||||
FactoryProvider.newFactory(GuiceS3Context.S3InputStreamMapFactory.class,
|
||||
LiveS3InputStreamMap.class));
|
||||
bind(objectMetadataFactoryLiteral).toProvider(
|
||||
FactoryProvider.newFactory(objectMetadataFactoryLiteral,
|
||||
new TypeLiteral<ObjectMetadata>() {
|
||||
}));
|
||||
bind(objectFactoryLiteral).toProvider(
|
||||
FactoryProvider.newFactory(objectFactoryLiteral, new TypeLiteral<S3Object>() {
|
||||
}));
|
||||
bind(S3Context.class).to(GuiceS3Context.class);
|
||||
bind(S3Context.class).to(S3ContextImpl.class).in(Scopes.SINGLETON);
|
||||
}
|
||||
|
||||
public static class S3ContextImpl extends
|
||||
BlobStoreContextImpl<S3BlobStore, BucketMetadata, ObjectMetadata, S3Object> implements
|
||||
S3Context {
|
||||
@Inject
|
||||
S3ContextImpl(Factory<ObjectMetadata, S3Object> blobMapFactory,
|
||||
org.jclouds.blobstore.InputStreamMap.Factory<ObjectMetadata> inputStreamMapFactory,
|
||||
Closer closer, Provider<S3Object> blobProvider, S3BlobStore defaultApi,
|
||||
@S3 URI endPoint, @Named(AWSConstants.PROPERTY_AWS_ACCESSKEYID) String account) {
|
||||
super(blobMapFactory, inputStreamMapFactory, closer, blobProvider, defaultApi, endPoint,
|
||||
account);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -23,10 +23,9 @@
|
|||
*/
|
||||
package org.jclouds.aws.s3.domain;
|
||||
|
||||
import org.jclouds.blobstore.domain.Blob;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import com.google.inject.assistedinject.Assisted;
|
||||
|
||||
import org.jclouds.blobstore.domain.Blob;
|
||||
|
||||
/**
|
||||
* Amazon S3 is designed to store objects. Objects are stored in {@link S3Bucket buckets} and
|
||||
|
@ -44,8 +43,7 @@ public class S3Object extends Blob<ObjectMetadata> {
|
|||
super(metadata, data);
|
||||
}
|
||||
|
||||
@Inject
|
||||
public S3Object(@Assisted ObjectMetadata metadata) {
|
||||
public S3Object(ObjectMetadata metadata) {
|
||||
super(metadata);
|
||||
}
|
||||
|
||||
|
@ -53,6 +51,11 @@ public class S3Object extends Blob<ObjectMetadata> {
|
|||
this(new ObjectMetadata(key), data);
|
||||
}
|
||||
|
||||
@Inject
|
||||
public S3Object() {
|
||||
this(new ObjectMetadata());
|
||||
}
|
||||
|
||||
public S3Object(String key) {
|
||||
this(new ObjectMetadata(key));
|
||||
}
|
||||
|
|
|
@ -23,25 +23,26 @@
|
|||
*/
|
||||
package org.jclouds.aws.s3.functions;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Provider;
|
||||
|
||||
import org.jclouds.aws.s3.domain.ObjectMetadata;
|
||||
import org.jclouds.aws.s3.domain.S3Object;
|
||||
import org.jclouds.blobstore.functions.ParseBlobFromHeadersAndHttpContent;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
/**
|
||||
* Parses response headers and creates a new S3Object from them and the HTTP content.
|
||||
*
|
||||
* @see ParseMetadataFromHeaders
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class ParseObjectFromHeadersAndHttpContent extends ParseBlobFromHeadersAndHttpContent<ObjectMetadata, S3Object> {
|
||||
public class ParseObjectFromHeadersAndHttpContent extends
|
||||
ParseBlobFromHeadersAndHttpContent<ObjectMetadata, S3Object> {
|
||||
|
||||
@Inject
|
||||
public ParseObjectFromHeadersAndHttpContent(
|
||||
ParseObjectMetadataFromHeaders metadataParser,
|
||||
BlobFactory<ObjectMetadata, S3Object> blobFactory) {
|
||||
public ParseObjectFromHeadersAndHttpContent(ParseObjectMetadataFromHeaders metadataParser,
|
||||
Provider<S3Object> blobFactory) {
|
||||
super(metadataParser, blobFactory);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -25,6 +25,9 @@ package org.jclouds.aws.s3.functions;
|
|||
|
||||
import static org.jclouds.blobstore.reference.BlobStoreConstants.PROPERTY_USER_METADATA_PREFIX;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Provider;
|
||||
import javax.ws.rs.core.HttpHeaders;
|
||||
|
||||
import org.jclouds.aws.s3.domain.ObjectMetadata;
|
||||
|
@ -35,8 +38,6 @@ import org.jclouds.http.HttpUtils;
|
|||
import org.jclouds.util.DateService;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
|
||||
/**
|
||||
* This parses @{link {@link org.jclouds.aws.s3.domain.ObjectMetadata} from HTTP headers.
|
||||
|
@ -44,12 +45,13 @@ import javax.inject.Named;
|
|||
* @see <a href="http://docs.amazonwebservices.com/AmazonS3/latest/RESTObjectGET.html" />
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class ParseObjectMetadataFromHeaders extends ParseSystemAndUserMetadataFromHeaders<ObjectMetadata> {
|
||||
public class ParseObjectMetadataFromHeaders extends
|
||||
ParseSystemAndUserMetadataFromHeaders<ObjectMetadata> {
|
||||
|
||||
@Inject
|
||||
public ParseObjectMetadataFromHeaders(DateService dateParser,
|
||||
@Named(PROPERTY_USER_METADATA_PREFIX) String metadataPrefix,
|
||||
BlobMetadataFactory<ObjectMetadata> metadataFactory) {
|
||||
Provider<ObjectMetadata> metadataFactory) {
|
||||
super(dateParser, metadataPrefix, metadataFactory);
|
||||
}
|
||||
|
||||
|
|
|
@ -63,7 +63,7 @@ public class AWSClientErrorRetryHandler implements HttpRetryHandler {
|
|||
return false;
|
||||
if (response.getStatusCode() == 400 || response.getStatusCode() == 409) {
|
||||
byte[] content = Utils.closeConnectionButKeepContentStream(response);
|
||||
command.incrementRedirectCount();
|
||||
command.incrementFailureCount();
|
||||
try {
|
||||
AWSError error = utils.parseAWSErrorFromContent(command, response, new String(content));
|
||||
if ("RequestTimeout".equals(error.getCode())
|
||||
|
|
|
@ -1,162 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.internal;
|
||||
|
||||
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;
|
||||
import org.jclouds.aws.s3.domain.S3Object;
|
||||
import org.jclouds.aws.s3.reference.S3Constants;
|
||||
import org.jclouds.blobstore.BlobMap;
|
||||
import org.jclouds.blobstore.InputStreamMap;
|
||||
import org.jclouds.lifecycle.Closer;
|
||||
import org.jclouds.logging.Logger;
|
||||
|
||||
import com.google.inject.Injector;
|
||||
|
||||
/**
|
||||
* Uses a Guice Injector to configure the objects served by S3Context methods.
|
||||
*
|
||||
* @author Adrian Cole
|
||||
* @see Injector
|
||||
*/
|
||||
public class GuiceS3Context implements S3Context {
|
||||
public interface S3ObjectMapFactory {
|
||||
BlobMap<ObjectMetadata, S3Object> createMapView(String bucket);
|
||||
}
|
||||
|
||||
public interface S3InputStreamMapFactory {
|
||||
InputStreamMap<ObjectMetadata> createMapView(String bucket);
|
||||
}
|
||||
|
||||
@Resource
|
||||
private Logger logger = Logger.NULL;
|
||||
private final Injector injector;
|
||||
private final S3InputStreamMapFactory s3InputStreamMapFactory;
|
||||
private final S3ObjectMapFactory s3ObjectMapFactory;
|
||||
private final Closer closer;
|
||||
private final String account;
|
||||
private final URI endPoint;
|
||||
|
||||
@Inject
|
||||
private GuiceS3Context(Injector injector, Closer closer, S3ObjectMapFactory s3ObjectMapFactory,
|
||||
S3InputStreamMapFactory s3InputStreamMapFactory,
|
||||
@Named(S3Constants.PROPERTY_AWS_ACCESSKEYID) String accessKey, @S3 URI endPoint) {
|
||||
this.injector = injector;
|
||||
this.s3InputStreamMapFactory = s3InputStreamMapFactory;
|
||||
this.s3ObjectMapFactory = s3ObjectMapFactory;
|
||||
this.closer = closer;
|
||||
this.account = accessKey;
|
||||
this.endPoint = endPoint;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public S3BlobStore getApi() {
|
||||
return injector.getInstance(S3BlobStore.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public InputStreamMap<ObjectMetadata> createInputStreamMap(String bucket) {
|
||||
getApi().createContainer(bucket);
|
||||
return s3InputStreamMapFactory.createMapView(bucket);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public BlobMap<ObjectMetadata, S3Object> createBlobMap(String bucket) {
|
||||
getApi().createContainer(bucket);
|
||||
return s3ObjectMapFactory.createMapView(bucket);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @see Closer
|
||||
*/
|
||||
public void close() {
|
||||
try {
|
||||
closer.close();
|
||||
} catch (IOException e) {
|
||||
logger.error(e, "error closing content");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "GuiceS3Context [account=" + account + ", endPoint=" + endPoint + "]";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((account == null) ? 0 : account.hashCode());
|
||||
result = prime * result + ((endPoint == null) ? 0 : endPoint.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
GuiceS3Context other = (GuiceS3Context) obj;
|
||||
if (account == null) {
|
||||
if (other.account != null)
|
||||
return false;
|
||||
} else if (!account.equals(other.account))
|
||||
return false;
|
||||
if (endPoint == null) {
|
||||
if (other.endPoint != null)
|
||||
return false;
|
||||
} else if (!endPoint.equals(other.endPoint))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public String getAccount() {
|
||||
return account;
|
||||
}
|
||||
|
||||
public URI getEndPoint() {
|
||||
return endPoint;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,55 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.internal;
|
||||
|
||||
import org.jclouds.aws.s3.S3BlobStore;
|
||||
import org.jclouds.aws.s3.domain.BucketMetadata;
|
||||
import org.jclouds.aws.s3.domain.ObjectMetadata;
|
||||
import org.jclouds.aws.s3.domain.S3Object;
|
||||
import org.jclouds.blobstore.LiveInputStreamMap;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import com.google.inject.assistedinject.Assisted;
|
||||
|
||||
/**
|
||||
* Map representation of a live connection to S3. All put operations will result in ETag
|
||||
* calculation. If this is not desired, use {@link LiveS3ObjectMap} instead.
|
||||
*
|
||||
* @author Adrian Cole
|
||||
* @see S3Connection
|
||||
* @see BaseS3Map
|
||||
*/
|
||||
public class LiveS3InputStreamMap extends
|
||||
LiveInputStreamMap<BucketMetadata, ObjectMetadata, S3Object> {
|
||||
|
||||
@Inject
|
||||
public LiveS3InputStreamMap(S3BlobStore connection, @Assisted String container) {
|
||||
super(connection, container);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected S3Object createBlob(String s) {
|
||||
return new S3Object(s);
|
||||
}
|
||||
}
|
|
@ -1,50 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.internal;
|
||||
|
||||
import org.jclouds.aws.s3.S3BlobStore;
|
||||
import org.jclouds.aws.s3.domain.BucketMetadata;
|
||||
import org.jclouds.aws.s3.domain.ObjectMetadata;
|
||||
import org.jclouds.aws.s3.domain.S3Object;
|
||||
import org.jclouds.blobstore.LiveBlobMap;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import com.google.inject.assistedinject.Assisted;
|
||||
|
||||
/**
|
||||
* Map representation of a live connection to S3.
|
||||
*
|
||||
* @see S3Connection
|
||||
* @see BaseS3Map
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class LiveS3ObjectMap extends LiveBlobMap<BucketMetadata, ObjectMetadata, S3Object> {
|
||||
|
||||
@Inject
|
||||
public LiveS3ObjectMap(S3BlobStore connection, @Assisted String container) {
|
||||
super(connection, container);
|
||||
}
|
||||
|
||||
}
|
|
@ -32,22 +32,14 @@ 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.blobstore.functions.ParseBlobFromHeadersAndHttpContent.BlobFactory;
|
||||
import org.jclouds.blobstore.functions.ParseContentTypeFromHeaders.BlobMetadataFactory;
|
||||
import org.jclouds.cloud.CloudContext;
|
||||
import org.jclouds.aws.s3.config.StubS3BlobStoreModule;
|
||||
import org.jclouds.aws.s3.config.S3ContextModule.S3ContextImpl;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.inject.Injector;
|
||||
import com.google.inject.Key;
|
||||
import com.google.inject.Module;
|
||||
import com.google.inject.TypeLiteral;
|
||||
|
||||
/**
|
||||
* Tests behavior of modules configured in S3ContextBuilder
|
||||
|
@ -58,7 +50,7 @@ import com.google.inject.TypeLiteral;
|
|||
public class S3ContextBuilderTest {
|
||||
|
||||
public void testNewBuilder() {
|
||||
S3ContextBuilder builder = S3ContextBuilder.newBuilder("id", "secret");
|
||||
S3ContextBuilder builder = new S3ContextBuilder("id", "secret");
|
||||
assertEquals(builder.getProperties().getProperty(PROPERTY_USER_METADATA_PREFIX),
|
||||
"x-amz-meta-");
|
||||
assertEquals(builder.getProperties().getProperty(PROPERTY_AWS_ACCESSKEYID), "id");
|
||||
|
@ -66,34 +58,22 @@ public class S3ContextBuilderTest {
|
|||
}
|
||||
|
||||
public void testBuildContext() {
|
||||
CloudContext<S3BlobStore> context = S3ContextBuilder.newBuilder("id", "secret")
|
||||
.buildContext();
|
||||
assertEquals(context.getClass(), GuiceS3Context.class);
|
||||
S3Context context = new S3ContextBuilder("id", "secret").withModules(
|
||||
new StubS3BlobStoreModule()).buildContext();
|
||||
assertEquals(context.getClass(), S3ContextImpl.class);
|
||||
assertEquals(context.getAccount(), "id");
|
||||
assertEquals(context.getEndPoint(), URI.create("https://s3.amazonaws.com"));
|
||||
assertEquals(context.getEndPoint(), URI.create("https://localhost/s3stub"));
|
||||
}
|
||||
|
||||
public void testBuildInjector() {
|
||||
Injector i = S3ContextBuilder.newBuilder("id", "secret").buildInjector();
|
||||
Injector i = new S3ContextBuilder("id", "secret").withModules(new StubS3BlobStoreModule())
|
||||
.buildInjector();
|
||||
assert i.getInstance(S3Context.class) != null;
|
||||
|
||||
assert i.getInstance(GuiceS3Context.S3ObjectMapFactory.class) != null;
|
||||
assert i.getInstance(GuiceS3Context.S3InputStreamMapFactory.class) != null;
|
||||
assert i.getInstance(Key.get(new TypeLiteral<BlobMetadataFactory<ObjectMetadata>>() {
|
||||
})) != null;
|
||||
assert i.getInstance(Key.get(new TypeLiteral<BlobFactory<ObjectMetadata, S3Object>>() {
|
||||
})) != null;
|
||||
i.injectMembers(this);
|
||||
assertEquals(endpoint, URI.create("https://s3.amazonaws.com"));
|
||||
}
|
||||
|
||||
private @Inject
|
||||
@S3
|
||||
URI endpoint;
|
||||
|
||||
protected void testAddContextModule() {
|
||||
List<Module> modules = new ArrayList<Module>();
|
||||
S3ContextBuilder builder = S3ContextBuilder.newBuilder("id", "secret");
|
||||
S3ContextBuilder builder = new S3ContextBuilder("id", "secret");
|
||||
builder.addContextModule(modules);
|
||||
assertEquals(modules.size(), 1);
|
||||
assertEquals(modules.get(0).getClass(), S3ContextModule.class);
|
||||
|
@ -101,8 +81,8 @@ public class S3ContextBuilderTest {
|
|||
|
||||
protected void addConnectionModule() {
|
||||
List<Module> modules = new ArrayList<Module>();
|
||||
S3ContextBuilder builder = S3ContextBuilder.newBuilder("id", "secret");
|
||||
builder.addApiModule(modules);
|
||||
S3ContextBuilder builder = new S3ContextBuilder("id", "secret");
|
||||
builder.addConnectionModule(modules);
|
||||
assertEquals(modules.size(), 1);
|
||||
assertEquals(modules.get(0).getClass(), RestS3ConnectionModule.class);
|
||||
}
|
||||
|
|
|
@ -25,13 +25,19 @@ package org.jclouds.aws.s3.config;
|
|||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import org.jclouds.aws.s3.S3BlobStore;
|
||||
import org.jclouds.aws.s3.domain.BucketMetadata;
|
||||
import org.jclouds.aws.s3.domain.ObjectMetadata;
|
||||
import org.jclouds.aws.s3.domain.S3Object;
|
||||
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.blobstore.BlobStoreMapsModule;
|
||||
import org.jclouds.concurrent.WithinThreadExecutorService;
|
||||
import org.jclouds.concurrent.config.ExecutorServiceModule;
|
||||
import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule;
|
||||
import org.jclouds.http.functions.config.ParserModule;
|
||||
import org.jclouds.http.handlers.DelegatingErrorHandler;
|
||||
import org.jclouds.http.handlers.DelegatingRetryHandler;
|
||||
import org.jclouds.util.Jsr330;
|
||||
|
@ -39,6 +45,7 @@ import org.testng.annotations.Test;
|
|||
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Injector;
|
||||
import com.google.inject.TypeLiteral;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
|
@ -47,19 +54,25 @@ import com.google.inject.Injector;
|
|||
public class S3ContextModuleTest {
|
||||
|
||||
Injector createInjector() {
|
||||
return Guice.createInjector(new RestS3ConnectionModule(), new S3ContextModule() {
|
||||
@Override
|
||||
protected void configure() {
|
||||
bindConstant().annotatedWith(Jsr330.named(S3Constants.PROPERTY_AWS_ACCESSKEYID)).to(
|
||||
"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 ExecutorServiceModule(
|
||||
new WithinThreadExecutorService()));
|
||||
return Guice.createInjector(new RestS3ConnectionModule(),
|
||||
new BlobStoreMapsModule<S3BlobStore, BucketMetadata, ObjectMetadata, S3Object>(
|
||||
new TypeLiteral<S3BlobStore>() {
|
||||
}, new TypeLiteral<BucketMetadata>() {
|
||||
}, new TypeLiteral<ObjectMetadata>() {
|
||||
}, new TypeLiteral<S3Object>() {
|
||||
}), new S3ContextModule() {
|
||||
@Override
|
||||
protected void configure() {
|
||||
bindConstant().annotatedWith(
|
||||
Jsr330.named(S3Constants.PROPERTY_AWS_ACCESSKEYID)).to("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 ParserModule(), new JavaUrlHttpCommandExecutorServiceModule(),
|
||||
new ExecutorServiceModule(new WithinThreadExecutorService()));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -24,14 +24,18 @@
|
|||
package org.jclouds.aws.s3.config;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.jclouds.aws.s3.S3;
|
||||
import org.jclouds.aws.s3.S3BlobStore;
|
||||
import org.jclouds.aws.s3.domain.S3Object;
|
||||
import org.jclouds.aws.s3.internal.StubS3BlobStore;
|
||||
import org.jclouds.cloud.ConfiguresCloudConnection;
|
||||
import org.jclouds.http.functions.config.ParserModule;
|
||||
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.TypeLiteral;
|
||||
|
||||
/**
|
||||
* adds a stub alternative to invoking S3
|
||||
|
@ -40,9 +44,13 @@ import com.google.inject.AbstractModule;
|
|||
*/
|
||||
@ConfiguresCloudConnection
|
||||
public class StubS3BlobStoreModule extends AbstractModule {
|
||||
static final ConcurrentHashMap<String, Map<String, S3Object>> map = new ConcurrentHashMap<String, Map<String, S3Object>>();
|
||||
|
||||
protected void configure() {
|
||||
install(new ParserModule());
|
||||
bind(S3BlobStore.class).to(StubS3BlobStore.class);
|
||||
bind(URI.class).annotatedWith(S3.class).toInstance(URI.create("http://localhost:8080"));
|
||||
bind(new TypeLiteral<Map<String, Map<String, S3Object>>>() {
|
||||
}).toInstance(map);
|
||||
bind(S3BlobStore.class).to(StubS3BlobStore.class).asEagerSingleton();
|
||||
bind(URI.class).annotatedWith(S3.class).toInstance(URI.create("https://localhost/s3stub"));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -76,16 +76,15 @@ public class S3BlobIntegrationTest extends
|
|||
final String containerName = getContainerName();
|
||||
try {
|
||||
// Public Read-Write object
|
||||
client.putBlob(containerName, new S3Object(publicReadWriteObjectKey, ""),
|
||||
context.getApi().putBlob(containerName, new S3Object(publicReadWriteObjectKey, ""),
|
||||
new PutObjectOptions().withAcl(CannedAccessPolicy.PUBLIC_READ_WRITE)).get(10,
|
||||
TimeUnit.SECONDS);
|
||||
|
||||
assertEventually(new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
AccessControlList acl = client
|
||||
.getBlobACL(containerName, publicReadWriteObjectKey).get(10,
|
||||
TimeUnit.SECONDS);
|
||||
AccessControlList acl = context.getApi().getBlobACL(containerName,
|
||||
publicReadWriteObjectKey).get(10, TimeUnit.SECONDS);
|
||||
assertEquals(acl.getGrants().size(), 3);
|
||||
assertEquals(acl.getPermissions(GroupGranteeURI.ALL_USERS).size(), 2);
|
||||
assertTrue(acl.getOwner() != null);
|
||||
|
@ -115,7 +114,7 @@ public class S3BlobIntegrationTest extends
|
|||
|
||||
// Private object
|
||||
addBlobToContainer(containerName, objectKey);
|
||||
AccessControlList acl = client.getBlobACL(containerName, objectKey).get(10,
|
||||
AccessControlList acl = context.getApi().getBlobACL(containerName, objectKey).get(10,
|
||||
TimeUnit.SECONDS);
|
||||
String ownerId = acl.getOwner().getId();
|
||||
|
||||
|
@ -124,10 +123,11 @@ public class S3BlobIntegrationTest extends
|
|||
|
||||
addGrantsToACL(acl);
|
||||
assertEquals(acl.getGrants().size(), 4);
|
||||
assertTrue(client.putBlobACL(containerName, objectKey, acl).get(10, TimeUnit.SECONDS));
|
||||
assertTrue(context.getApi().putBlobACL(containerName, objectKey, acl).get(10,
|
||||
TimeUnit.SECONDS));
|
||||
|
||||
// Confirm that the updated ACL has stuck.
|
||||
acl = client.getBlobACL(containerName, objectKey).get(10, TimeUnit.SECONDS);
|
||||
acl = context.getApi().getBlobACL(containerName, objectKey).get(10, TimeUnit.SECONDS);
|
||||
checkGrants(acl);
|
||||
|
||||
/*
|
||||
|
@ -141,10 +141,11 @@ public class S3BlobIntegrationTest extends
|
|||
assertTrue(acl.hasPermission(GroupGranteeURI.ALL_USERS, Permission.READ));
|
||||
|
||||
// Update the object's ACL settings
|
||||
assertTrue(client.putBlobACL(containerName, objectKey, acl).get(10, TimeUnit.SECONDS));
|
||||
assertTrue(context.getApi().putBlobACL(containerName, objectKey, acl).get(10,
|
||||
TimeUnit.SECONDS));
|
||||
|
||||
// Confirm that the updated ACL has stuck
|
||||
acl = client.getBlobACL(containerName, objectKey).get(10, TimeUnit.SECONDS);
|
||||
acl = context.getApi().getBlobACL(containerName, objectKey).get(10, TimeUnit.SECONDS);
|
||||
assertEquals(acl.getGrants().size(), 1);
|
||||
assertEquals(acl.getPermissions(ownerId).size(), 0);
|
||||
assertTrue(acl.hasPermission(GroupGranteeURI.ALL_USERS, Permission.READ), acl.toString());
|
||||
|
@ -180,8 +181,8 @@ public class S3BlobIntegrationTest extends
|
|||
try {
|
||||
// Private object
|
||||
addBlobToContainer(containerName, privateObjectKey);
|
||||
AccessControlList acl = client.getBlobACL(containerName, privateObjectKey).get(10,
|
||||
TimeUnit.SECONDS);
|
||||
AccessControlList acl = context.getApi().getBlobACL(containerName, privateObjectKey).get(
|
||||
10, TimeUnit.SECONDS);
|
||||
|
||||
assertEquals(acl.getGrants().size(), 1);
|
||||
assertTrue(acl.getOwner() != null);
|
||||
|
@ -198,15 +199,15 @@ public class S3BlobIntegrationTest extends
|
|||
final String publicReadObjectKey = "public-read-acl";
|
||||
final String containerName = getContainerName();
|
||||
try {
|
||||
client.putBlob(containerName, new S3Object(publicReadObjectKey, ""),
|
||||
context.getApi().putBlob(containerName, new S3Object(publicReadObjectKey, ""),
|
||||
new PutObjectOptions().withAcl(CannedAccessPolicy.PUBLIC_READ)).get(10,
|
||||
TimeUnit.SECONDS);
|
||||
|
||||
assertEventually(new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
AccessControlList acl = client.getBlobACL(containerName, publicReadObjectKey)
|
||||
.get(10, TimeUnit.SECONDS);
|
||||
AccessControlList acl = context.getApi().getBlobACL(containerName,
|
||||
publicReadObjectKey).get(10, TimeUnit.SECONDS);
|
||||
|
||||
assertEquals(acl.getGrants().size(), 2);
|
||||
assertEquals(acl.getPermissions(GroupGranteeURI.ALL_USERS).size(), 1);
|
||||
|
@ -229,7 +230,7 @@ public class S3BlobIntegrationTest extends
|
|||
public void testMetadataWithCacheControlAndContentDisposition() throws Exception {
|
||||
String key = "hello";
|
||||
|
||||
S3Object object = objectFactory.createBlob(key);
|
||||
S3Object object = context.newBlob(key);
|
||||
object.setData(TEST_STRING);
|
||||
object.getMetadata().setCacheControl("no-cache");
|
||||
object.getMetadata().setContentDisposition("attachment; filename=hello.txt");
|
||||
|
@ -250,7 +251,7 @@ public class S3BlobIntegrationTest extends
|
|||
public void testMetadataContentEncoding() throws Exception {
|
||||
String key = "hello";
|
||||
|
||||
S3Object object = objectFactory.createBlob(key);
|
||||
S3Object object = context.newBlob(key);
|
||||
object.setData(TEST_STRING);
|
||||
object.getMetadata().setContentEncoding("x-compress");
|
||||
String containerName = getContainerName();
|
||||
|
@ -271,8 +272,8 @@ public class S3BlobIntegrationTest extends
|
|||
try {
|
||||
addToContainerAndValidate(containerName, sourceKey);
|
||||
|
||||
client.copyBlob(containerName, sourceKey, destinationContainer, destinationKey).get(10,
|
||||
TimeUnit.SECONDS);
|
||||
context.getApi().copyBlob(containerName, sourceKey, destinationContainer, destinationKey)
|
||||
.get(10, TimeUnit.SECONDS);
|
||||
|
||||
validateContent(destinationContainer, destinationKey);
|
||||
} finally {
|
||||
|
@ -298,13 +299,13 @@ public class S3BlobIntegrationTest extends
|
|||
addToContainerAndValidate(containerName, sourceKey + "mod");
|
||||
DateTime after = new DateTime().plusSeconds(1);
|
||||
|
||||
client.copyBlob(containerName, sourceKey + "mod", destinationContainer, destinationKey,
|
||||
ifSourceModifiedSince(before)).get(10, TimeUnit.SECONDS);
|
||||
context.getApi().copyBlob(containerName, sourceKey + "mod", destinationContainer,
|
||||
destinationKey, ifSourceModifiedSince(before)).get(10, TimeUnit.SECONDS);
|
||||
validateContent(destinationContainer, destinationKey);
|
||||
|
||||
try {
|
||||
client.copyBlob(containerName, sourceKey + "mod", destinationContainer, destinationKey,
|
||||
ifSourceModifiedSince(after)).get(10, TimeUnit.SECONDS);
|
||||
context.getApi().copyBlob(containerName, sourceKey + "mod", destinationContainer,
|
||||
destinationKey, ifSourceModifiedSince(after)).get(10, TimeUnit.SECONDS);
|
||||
} catch (ExecutionException e) {
|
||||
if (e.getCause() instanceof HttpResponseException) {
|
||||
HttpResponseException ex = (HttpResponseException) e.getCause();
|
||||
|
@ -330,13 +331,13 @@ public class S3BlobIntegrationTest extends
|
|||
addToContainerAndValidate(containerName, sourceKey + "un");
|
||||
DateTime after = new DateTime().plusSeconds(1);
|
||||
|
||||
client.copyBlob(containerName, sourceKey + "un", destinationContainer, destinationKey,
|
||||
ifSourceUnmodifiedSince(after)).get(10, TimeUnit.SECONDS);
|
||||
context.getApi().copyBlob(containerName, sourceKey + "un", destinationContainer,
|
||||
destinationKey, ifSourceUnmodifiedSince(after)).get(10, TimeUnit.SECONDS);
|
||||
validateContent(destinationContainer, destinationKey);
|
||||
|
||||
try {
|
||||
client.copyBlob(containerName, sourceKey + "un", destinationContainer, destinationKey,
|
||||
ifSourceModifiedSince(before)).get(10, TimeUnit.SECONDS);
|
||||
context.getApi().copyBlob(containerName, sourceKey + "un", destinationContainer,
|
||||
destinationKey, ifSourceModifiedSince(before)).get(10, TimeUnit.SECONDS);
|
||||
} catch (ExecutionException e) {
|
||||
HttpResponseException ex = (HttpResponseException) e.getCause();
|
||||
assertEquals(ex.getResponse().getStatusCode(), 412);
|
||||
|
@ -354,13 +355,13 @@ public class S3BlobIntegrationTest extends
|
|||
try {
|
||||
addToContainerAndValidate(containerName, sourceKey);
|
||||
|
||||
client.copyBlob(containerName, sourceKey, destinationContainer, destinationKey,
|
||||
context.getApi().copyBlob(containerName, sourceKey, destinationContainer, destinationKey,
|
||||
ifSourceETagMatches(goodETag)).get(10, TimeUnit.SECONDS);
|
||||
validateContent(destinationContainer, destinationKey);
|
||||
|
||||
try {
|
||||
client.copyBlob(containerName, sourceKey, destinationContainer, destinationKey,
|
||||
ifSourceETagMatches(badETag)).get(10, TimeUnit.SECONDS);
|
||||
context.getApi().copyBlob(containerName, sourceKey, destinationContainer,
|
||||
destinationKey, ifSourceETagMatches(badETag)).get(10, TimeUnit.SECONDS);
|
||||
} catch (ExecutionException e) {
|
||||
HttpResponseException ex = (HttpResponseException) e.getCause();
|
||||
assertEquals(ex.getResponse().getStatusCode(), 412);
|
||||
|
@ -378,13 +379,13 @@ public class S3BlobIntegrationTest extends
|
|||
try {
|
||||
addToContainerAndValidate(containerName, sourceKey);
|
||||
|
||||
client.copyBlob(containerName, sourceKey, destinationContainer, destinationKey,
|
||||
context.getApi().copyBlob(containerName, sourceKey, destinationContainer, destinationKey,
|
||||
ifSourceETagDoesntMatch(badETag)).get(10, TimeUnit.SECONDS);
|
||||
validateContent(destinationContainer, destinationKey);
|
||||
|
||||
try {
|
||||
client.copyBlob(containerName, sourceKey, destinationContainer, destinationKey,
|
||||
ifSourceETagDoesntMatch(goodETag)).get(10, TimeUnit.SECONDS);
|
||||
context.getApi().copyBlob(containerName, sourceKey, destinationContainer,
|
||||
destinationKey, ifSourceETagDoesntMatch(goodETag)).get(10, TimeUnit.SECONDS);
|
||||
} catch (ExecutionException e) {
|
||||
HttpResponseException ex = (HttpResponseException) e.getCause();
|
||||
assertEquals(ex.getResponse().getStatusCode(), 412);
|
||||
|
@ -406,12 +407,13 @@ public class S3BlobIntegrationTest extends
|
|||
Multimap<String, String> metadata = HashMultimap.create();
|
||||
metadata.put("adrian", "cole");
|
||||
|
||||
client.copyBlob(containerName, sourceKey, destinationContainer, destinationKey,
|
||||
context.getApi().copyBlob(containerName, sourceKey, destinationContainer, destinationKey,
|
||||
overrideMetadataWith(metadata)).get(10, TimeUnit.SECONDS);
|
||||
|
||||
validateContent(destinationContainer, destinationKey);
|
||||
|
||||
ObjectMetadata objectMeta = client.blobMetadata(destinationContainer, destinationKey);
|
||||
ObjectMetadata objectMeta = context.getApi().blobMetadata(destinationContainer,
|
||||
destinationKey);
|
||||
|
||||
assertEquals(objectMeta.getUserMetadata(), metadata);
|
||||
} finally {
|
||||
|
|
|
@ -52,7 +52,7 @@ public class S3BlobLiveTest extends
|
|||
try {
|
||||
String key = "hello";
|
||||
|
||||
client.putBlob(containerName, new S3Object(key, TEST_STRING),
|
||||
context.getApi().putBlob(containerName, new S3Object(key, TEST_STRING),
|
||||
|
||||
withAcl(CannedAccessPolicy.PUBLIC_READ)).get(10, TimeUnit.SECONDS);
|
||||
|
||||
|
@ -74,7 +74,7 @@ public class S3BlobLiveTest extends
|
|||
addBlobToContainer(containerName, sourceKey);
|
||||
validateContent(containerName, sourceKey);
|
||||
|
||||
client.copyBlob(containerName, sourceKey, destinationContainer, destinationKey,
|
||||
context.getApi().copyBlob(containerName, sourceKey, destinationContainer, destinationKey,
|
||||
overrideAcl(CannedAccessPolicy.PUBLIC_READ)).get(10, TimeUnit.SECONDS);
|
||||
|
||||
validateContent(destinationContainer, destinationKey);
|
||||
|
|
|
@ -66,8 +66,8 @@ public class S3ContainerIntegrationTest extends
|
|||
String prefix = "apps";
|
||||
addTenObjectsUnderPrefix(containerName, prefix);
|
||||
add15UnderRoot(containerName);
|
||||
ListBucketResponse container = client.listBlobs(containerName, delimiter("/")).get(10,
|
||||
TimeUnit.SECONDS);
|
||||
ListBucketResponse container = context.getApi().listBlobs(containerName, delimiter("/"))
|
||||
.get(10, TimeUnit.SECONDS);
|
||||
assertEquals(container.getDelimiter(), "/");
|
||||
assert !container.isTruncated();
|
||||
assertEquals(container.size(), 15);
|
||||
|
@ -86,8 +86,8 @@ public class S3ContainerIntegrationTest extends
|
|||
addTenObjectsUnderPrefix(containerName, prefix);
|
||||
add15UnderRoot(containerName);
|
||||
|
||||
ListBucketResponse container = client.listBlobs(containerName, withPrefix("apps/")).get(
|
||||
10, TimeUnit.SECONDS);
|
||||
ListBucketResponse container = context.getApi().listBlobs(containerName,
|
||||
withPrefix("apps/")).get(10, TimeUnit.SECONDS);
|
||||
assert !container.isTruncated();
|
||||
assertEquals(container.size(), 10);
|
||||
assertEquals(container.getPrefix(), "apps/");
|
||||
|
@ -101,7 +101,8 @@ public class S3ContainerIntegrationTest extends
|
|||
ExecutionException, TimeoutException, IOException {
|
||||
String containerName = getContainerName();
|
||||
try {
|
||||
AccessControlList acl = client.getContainerACL(containerName).get(10, TimeUnit.SECONDS);
|
||||
AccessControlList acl = context.getApi().getContainerACL(containerName).get(10,
|
||||
TimeUnit.SECONDS);
|
||||
assertEquals(acl.getGrants().size(), 1);
|
||||
assertTrue(acl.getOwner() != null);
|
||||
String ownerId = acl.getOwner().getId();
|
||||
|
@ -117,17 +118,18 @@ public class S3ContainerIntegrationTest extends
|
|||
String containerName = getContainerName();
|
||||
try {
|
||||
// Confirm the container is private
|
||||
AccessControlList acl = client.getContainerACL(containerName).get(10, TimeUnit.SECONDS);
|
||||
AccessControlList acl = context.getApi().getContainerACL(containerName).get(10,
|
||||
TimeUnit.SECONDS);
|
||||
String ownerId = acl.getOwner().getId();
|
||||
assertEquals(acl.getGrants().size(), 1);
|
||||
assertTrue(acl.hasPermission(ownerId, Permission.FULL_CONTROL));
|
||||
|
||||
addGrantsToACL(acl);
|
||||
assertEquals(acl.getGrants().size(), 4);
|
||||
assertTrue(client.putContainerACL(containerName, acl).get(10, TimeUnit.SECONDS));
|
||||
assertTrue(context.getApi().putContainerACL(containerName, acl).get(10, TimeUnit.SECONDS));
|
||||
|
||||
// Confirm that the updated ACL has stuck.
|
||||
acl = client.getContainerACL(containerName).get(10, TimeUnit.SECONDS);
|
||||
acl = context.getApi().getContainerACL(containerName).get(10, TimeUnit.SECONDS);
|
||||
checkGrants(acl);
|
||||
} finally {
|
||||
destroyContainer(containerName);
|
||||
|
@ -159,8 +161,8 @@ public class S3ContainerIntegrationTest extends
|
|||
String containerName = getContainerName();
|
||||
try {
|
||||
addAlphabetUnderRoot(containerName);
|
||||
ListBucketResponse container = client.listBlobs(containerName, afterMarker("y")).get(10,
|
||||
TimeUnit.SECONDS);
|
||||
ListBucketResponse container = context.getApi().listBlobs(containerName, afterMarker("y"))
|
||||
.get(10, TimeUnit.SECONDS);
|
||||
assertEquals(container.getMarker(), "y");
|
||||
assert !container.isTruncated();
|
||||
assertEquals(container.size(), 1);
|
||||
|
@ -174,8 +176,8 @@ public class S3ContainerIntegrationTest extends
|
|||
String containerName = getContainerName();
|
||||
try {
|
||||
addAlphabetUnderRoot(containerName);
|
||||
ListBucketResponse container = client.listBlobs(containerName, maxResults(5)).get(10,
|
||||
TimeUnit.SECONDS);
|
||||
ListBucketResponse container = context.getApi().listBlobs(containerName, maxResults(5))
|
||||
.get(10, TimeUnit.SECONDS);
|
||||
assertEquals(container.getMaxResults(), 5);
|
||||
assert container.isTruncated();
|
||||
assertEquals(container.size(), 5);
|
||||
|
|
|
@ -55,9 +55,9 @@ public class S3ContainerLiveTest extends
|
|||
public void testPublicReadAccessPolicy() throws Exception {
|
||||
String containerName = getScratchContainerName();
|
||||
try {
|
||||
client.createContainer(containerName, withBucketAcl(CannedAccessPolicy.PUBLIC_READ)).get(
|
||||
context.getApi().createContainer(containerName, withBucketAcl(CannedAccessPolicy.PUBLIC_READ)).get(
|
||||
10, TimeUnit.SECONDS);
|
||||
AccessControlList acl = client.getContainerACL(containerName).get(10, TimeUnit.SECONDS);
|
||||
AccessControlList acl = context.getApi().getContainerACL(containerName).get(10, TimeUnit.SECONDS);
|
||||
assertTrue(acl.hasPermission(GroupGranteeURI.ALL_USERS, Permission.READ), acl.toString());
|
||||
// TODO: I believe that the following should work based on the above acl assertion passing.
|
||||
// However, it fails on 403
|
||||
|
@ -86,13 +86,13 @@ public class S3ContainerLiveTest extends
|
|||
public void testEu() throws Exception {
|
||||
final String containerName = getScratchContainerName();
|
||||
try {
|
||||
client.createContainer(containerName + "eu",
|
||||
context.getApi().createContainer(containerName + "eu",
|
||||
createIn(LocationConstraint.EU).withBucketAcl(CannedAccessPolicy.PUBLIC_READ))
|
||||
.get(30, TimeUnit.SECONDS);
|
||||
assertEventually(new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
AccessControlList acl = client.getContainerACL(containerName + "eu").get(30,
|
||||
AccessControlList acl = context.getApi().getContainerACL(containerName + "eu").get(30,
|
||||
TimeUnit.SECONDS);
|
||||
assertTrue(acl.hasPermission(GroupGranteeURI.ALL_USERS, Permission.READ), acl
|
||||
.toString());
|
||||
|
|
|
@ -35,16 +35,16 @@ import org.testng.annotations.Test;
|
|||
/**
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = { "integration", "live" }, testName = "s3.S3ServiceIntegrationTest")
|
||||
@Test(groups = { "integration", "live" }, testName = "s3.S3ServiceIntegrationTest")
|
||||
public class S3ServiceIntegrationTest extends
|
||||
BaseServiceIntegrationTest<S3BlobStore, BucketMetadata, ObjectMetadata, S3Object> {
|
||||
|
||||
void containerExists() throws Exception {
|
||||
String containerName = getContainerName();
|
||||
try {
|
||||
List<BucketMetadata> list = client.listContainers();
|
||||
List<BucketMetadata> list = context.getApi().listContainers();
|
||||
BucketMetadata firstContainer = list.get(0);
|
||||
BucketMetadata toMatch = objectFactory.createContainerMetadata(containerName);
|
||||
BucketMetadata toMatch = new BucketMetadata(containerName);
|
||||
toMatch.setOwner(firstContainer.getOwner());
|
||||
assert list.contains(toMatch);
|
||||
} finally {
|
||||
|
|
|
@ -24,7 +24,6 @@
|
|||
package org.jclouds.aws.s3.integration;
|
||||
|
||||
import org.jclouds.aws.s3.S3BlobStore;
|
||||
import org.jclouds.aws.s3.S3Context;
|
||||
import org.jclouds.aws.s3.S3ContextBuilder;
|
||||
import org.jclouds.aws.s3.S3ContextFactory;
|
||||
import org.jclouds.aws.s3.config.StubS3BlobStoreModule;
|
||||
|
@ -33,9 +32,8 @@ import org.jclouds.aws.s3.domain.ObjectMetadata;
|
|||
import org.jclouds.aws.s3.domain.S3Object;
|
||||
import org.jclouds.blobstore.BlobStoreContext;
|
||||
import org.jclouds.blobstore.integration.internal.BaseBlobStoreIntegrationTest;
|
||||
import org.jclouds.blobstore.integration.internal.BaseBlobStoreIntegrationTest.BlobStoreObjectFactory;
|
||||
import org.jclouds.blobstore.integration.internal.BaseTestInitializer;
|
||||
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
|
||||
import org.testng.ITestContext;
|
||||
|
||||
import com.google.inject.Module;
|
||||
|
||||
|
@ -43,86 +41,20 @@ import com.google.inject.Module;
|
|||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class S3TestInitializer
|
||||
implements
|
||||
BaseBlobStoreIntegrationTest.TestInitializer<S3BlobStore, BucketMetadata, ObjectMetadata, S3Object> {
|
||||
public class S3TestInitializer extends
|
||||
BaseTestInitializer<S3BlobStore, BucketMetadata, ObjectMetadata, S3Object> {
|
||||
|
||||
public BaseBlobStoreIntegrationTest.TestInitializer.Result<S3BlobStore, BucketMetadata, ObjectMetadata, S3Object> init(
|
||||
Module configurationModule, ITestContext testContext) throws Exception {
|
||||
String account = System.getProperty("jclouds.test.user");
|
||||
String key = System.getProperty("jclouds.test.key");
|
||||
if (account != null)
|
||||
testContext.setAttribute("jclouds.test.user", account);
|
||||
if (key != null)
|
||||
testContext.setAttribute("jclouds.test.key", key);
|
||||
|
||||
final S3Context context;
|
||||
if (account != null) {
|
||||
context = createLiveS3Context(configurationModule, account, key);
|
||||
} else {
|
||||
context = createStubS3Context();
|
||||
}
|
||||
assert context != null;
|
||||
|
||||
final S3BlobStore client = context.getApi();
|
||||
assert client != null;
|
||||
|
||||
final BlobStoreObjectFactory<BucketMetadata, S3Object> objectFactory = new BaseBlobStoreIntegrationTest.BlobStoreObjectFactory<BucketMetadata, S3Object>() {
|
||||
|
||||
public S3Object createBlob(String key) {
|
||||
return new S3Object(key);
|
||||
|
||||
}
|
||||
|
||||
public BucketMetadata createContainerMetadata(String key) {
|
||||
return new BucketMetadata(key);
|
||||
}
|
||||
|
||||
};
|
||||
assert objectFactory != null;
|
||||
|
||||
return new BaseBlobStoreIntegrationTest.TestInitializer.Result<S3BlobStore, BucketMetadata, ObjectMetadata, S3Object>() {
|
||||
|
||||
public S3BlobStore getClient() {
|
||||
return client;
|
||||
}
|
||||
|
||||
public BlobStoreContext<S3BlobStore, ObjectMetadata, S3Object> getContext() {
|
||||
return context;
|
||||
}
|
||||
|
||||
public BlobStoreObjectFactory<BucketMetadata, S3Object> getObjectFactory() {
|
||||
return objectFactory;
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
protected S3Context createStubS3Context() {
|
||||
@Override
|
||||
protected BlobStoreContext<S3BlobStore, BucketMetadata, ObjectMetadata, S3Object> createLiveContext(
|
||||
Module configurationModule, String url, String app, String account, String key) {
|
||||
BaseBlobStoreIntegrationTest.SANITY_CHECK_RETURNED_BUCKET_NAME = true;
|
||||
return S3ContextFactory.createS3Context("stub", "stub", new StubS3BlobStoreModule());
|
||||
return new S3ContextBuilder(account, key).withSaxDebug().relaxSSLHostname().withModules(
|
||||
configurationModule, new Log4JLoggingModule()).buildContext();
|
||||
}
|
||||
|
||||
protected S3Context createLiveS3Context(Module configurationModule, String AWSAccessKeyId,
|
||||
String AWSSecretAccessKey) {
|
||||
return buildS3ContextFactory(configurationModule, AWSAccessKeyId, AWSSecretAccessKey)
|
||||
.buildContext();
|
||||
}
|
||||
|
||||
// protected String createScratchContainerInEU() throws InterruptedException, ExecutionException,
|
||||
// TimeoutException {
|
||||
// String containerName = getScratchContainerName();
|
||||
// deleteContainer(containerName);
|
||||
// client.createContainer(containerName, PutBucketOptions.Builder
|
||||
// .createIn(LocationConstraint.EU));
|
||||
// return containerName;
|
||||
// }
|
||||
|
||||
protected S3ContextBuilder buildS3ContextFactory(Module configurationModule,
|
||||
String AWSAccessKeyId, String AWSSecretAccessKey) {
|
||||
return (S3ContextBuilder) S3ContextBuilder.newBuilder(AWSAccessKeyId, AWSSecretAccessKey)
|
||||
.withSaxDebug().relaxSSLHostname().withModules(configurationModule,
|
||||
new Log4JLoggingModule());
|
||||
@Override
|
||||
protected BlobStoreContext<S3BlobStore, BucketMetadata, ObjectMetadata, S3Object> createStubContext() {
|
||||
return S3ContextFactory.createContext("user", "pass", new StubS3BlobStoreModule());
|
||||
}
|
||||
|
||||
}
|
|
@ -31,6 +31,9 @@ import java.util.concurrent.ConcurrentHashMap;
|
|||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Provider;
|
||||
|
||||
import org.jclouds.aws.s3.S3BlobStore;
|
||||
import org.jclouds.aws.s3.domain.AccessControlList;
|
||||
import org.jclouds.aws.s3.domain.ArrayListBucketResponse;
|
||||
|
@ -52,6 +55,7 @@ import org.jclouds.blobstore.KeyNotFoundException;
|
|||
import org.jclouds.blobstore.integration.internal.StubBlobStore;
|
||||
import org.jclouds.http.HttpUtils;
|
||||
import org.jclouds.http.options.GetOptions;
|
||||
import org.jclouds.util.DateService;
|
||||
import org.joda.time.DateTime;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
|
@ -69,6 +73,14 @@ import com.google.inject.internal.Nullable;
|
|||
*/
|
||||
public class StubS3BlobStore extends StubBlobStore<BucketMetadata, ObjectMetadata, S3Object>
|
||||
implements S3BlobStore {
|
||||
|
||||
@Inject
|
||||
protected StubS3BlobStore(Map<String, Map<String, S3Object>> containerToBlobs,
|
||||
DateService dateService, Provider<BucketMetadata> containerMetaProvider,
|
||||
Provider<S3Object> blobProvider) {
|
||||
super(containerToBlobs, dateService, containerMetaProvider, blobProvider);
|
||||
}
|
||||
|
||||
public static final String TEST_ACL_ID = "1a405254c932b52e5b5caaa88186bc431a1bacb9ece631f835daddaf0c47677c";
|
||||
public static final String TEST_ACL_EMAIL = "james@misterm.org";
|
||||
private static Map<String, BucketMetadata.LocationConstraint> bucketToLocation = new ConcurrentHashMap<String, BucketMetadata.LocationConstraint>();
|
||||
|
@ -318,29 +330,4 @@ public class StubS3BlobStore extends StubBlobStore<BucketMetadata, ObjectMetadat
|
|||
return putBlob(bucketName, object, PutObjectOptions.NONE);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected S3Object createBlob(String name) {
|
||||
return new S3Object(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected S3Object createBlob(ObjectMetadata metadata) {
|
||||
return new S3Object(metadata);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected BucketMetadata createContainerMetadata(String name) {
|
||||
return new BucketMetadata(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* note this must be final and static so that tests coming from multiple threads will pass.
|
||||
*/
|
||||
private static final Map<String, Map<String, S3Object>> containerToBlobs = new ConcurrentHashMap<String, Map<String, S3Object>>();
|
||||
|
||||
@Override
|
||||
public Map<String, Map<String, S3Object>> getContainerToBlobs() {
|
||||
return containerToBlobs;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -32,12 +32,14 @@ import java.util.Map;
|
|||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.jclouds.aws.s3.S3BlobStore;
|
||||
import org.jclouds.aws.s3.S3Context;
|
||||
import org.jclouds.aws.s3.S3ContextBuilder;
|
||||
import org.jclouds.aws.s3.S3ContextFactory;
|
||||
import org.jclouds.aws.s3.domain.BucketMetadata;
|
||||
import org.jclouds.aws.s3.domain.ListBucketResponse;
|
||||
import org.jclouds.aws.s3.domain.ObjectMetadata;
|
||||
import org.jclouds.aws.s3.options.CopyObjectOptions;
|
||||
import org.jclouds.aws.s3.options.ListBucketOptions;
|
||||
import org.jclouds.aws.s3.options.PutObjectOptions;
|
||||
import org.jclouds.blobstore.BlobStoreContext;
|
||||
import org.jclouds.http.HttpUtils;
|
||||
import org.jclouds.http.options.GetOptions;
|
||||
import org.jclouds.util.Utils;
|
||||
|
@ -62,7 +64,7 @@ public class JCloudsS3Service extends S3Service {
|
|||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private final S3Context context;
|
||||
private final BlobStoreContext<S3BlobStore, BucketMetadata, ObjectMetadata, org.jclouds.aws.s3.domain.S3Object> context;
|
||||
private final S3BlobStore connection;
|
||||
|
||||
private final long requestTimeoutMilliseconds = 10000;
|
||||
|
@ -80,8 +82,8 @@ public class JCloudsS3Service extends S3Service {
|
|||
protected JCloudsS3Service(AWSCredentials awsCredentials, Module... modules)
|
||||
throws S3ServiceException {
|
||||
super(awsCredentials);
|
||||
context = S3ContextBuilder.newBuilder(awsCredentials.getAccessKey(),
|
||||
awsCredentials.getSecretKey()).withModules(modules).buildContext();
|
||||
context = S3ContextFactory.createContext(awsCredentials.getAccessKey(), awsCredentials
|
||||
.getSecretKey(), modules);
|
||||
connection = context.getApi();
|
||||
}
|
||||
|
||||
|
|
|
@ -112,7 +112,7 @@ public class JCloudsS3ServiceLiveTest
|
|||
try {
|
||||
S3Bucket bucket = service.createBucket(new S3Bucket(bucketName));
|
||||
assertEquals(bucket.getName(), bucketName);
|
||||
assertTrue(client.containerExists(bucketName));
|
||||
assertTrue(context.getApi().containerExists(bucketName));
|
||||
} finally {
|
||||
returnContainer(bucketName);
|
||||
}
|
||||
|
@ -121,13 +121,13 @@ public class JCloudsS3ServiceLiveTest
|
|||
@Test
|
||||
public void testDeleteBucketImpl() throws S3ServiceException, InterruptedException,
|
||||
ExecutionException, TimeoutException {
|
||||
String bucketName = getContainerName();
|
||||
try {
|
||||
service.deleteBucket(bucketName);
|
||||
assertFalse(client.containerExists(bucketName));
|
||||
} finally {
|
||||
returnContainer(bucketName);
|
||||
}
|
||||
final String bucketName = getContainerName();
|
||||
service.deleteBucket(bucketName);
|
||||
assertEventually(new Runnable() {
|
||||
public void run() {
|
||||
assertFalse(context.getApi().containerExists(bucketName));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -211,7 +211,8 @@ public class JCloudsS3ServiceLiveTest
|
|||
// Ensure there is at least 1 bucket in S3 account to list and compare.
|
||||
S3Bucket[] jsBuckets = service.listAllBuckets();
|
||||
|
||||
List<org.jclouds.aws.s3.domain.BucketMetadata> jcBuckets = client.listContainers();
|
||||
List<org.jclouds.aws.s3.domain.BucketMetadata> jcBuckets = context.getApi()
|
||||
.listContainers();
|
||||
|
||||
assert jsBuckets.length == jcBuckets.size();
|
||||
|
||||
|
@ -362,7 +363,7 @@ public class JCloudsS3ServiceLiveTest
|
|||
// Upload empty object
|
||||
requestObject = new S3Object(objectKey);
|
||||
jsResultObject = service.putObject(new S3Bucket(bucketName), requestObject);
|
||||
jcObject = client.getBlob(bucketName, objectKey).get(10, TimeUnit.SECONDS);
|
||||
jcObject = context.getApi().getBlob(bucketName, objectKey).get(10, TimeUnit.SECONDS);
|
||||
// TODO null keys from s3object! assertEquals(jcObject.getKey(), objectKey);
|
||||
assertEquals(jcObject.getMetadata().getSize(), 0);
|
||||
assertEquals(jcObject.getMetadata().getContentType(), MediaType.APPLICATION_OCTET_STREAM);
|
||||
|
@ -373,7 +374,8 @@ public class JCloudsS3ServiceLiveTest
|
|||
// Upload unicode-named object
|
||||
requestObject = new S3Object("Ÿn’<EFBFBD>˜dŽ-object");
|
||||
jsResultObject = service.putObject(new S3Bucket(bucketName), requestObject);
|
||||
jcObject = client.getBlob(bucketName, requestObject.getKey()).get(10, TimeUnit.SECONDS);
|
||||
jcObject = context.getApi().getBlob(bucketName, requestObject.getKey()).get(10,
|
||||
TimeUnit.SECONDS);
|
||||
// TODO null keys from s3object! assertEquals(jcObject.getKey(), requestObject.getKey());
|
||||
assertEquals(jcObject.getMetadata().getSize(), 0);
|
||||
assertEquals(jcObject.getMetadata().getContentType(), MediaType.APPLICATION_OCTET_STREAM);
|
||||
|
@ -385,7 +387,7 @@ public class JCloudsS3ServiceLiveTest
|
|||
String data = "This is my Ÿn’<6E>˜dŽ data";
|
||||
requestObject = new S3Object(objectKey, data);
|
||||
jsResultObject = service.putObject(new S3Bucket(bucketName), requestObject);
|
||||
jcObject = client.getBlob(bucketName, objectKey).get(10, TimeUnit.SECONDS);
|
||||
jcObject = context.getApi().getBlob(bucketName, objectKey).get(10, TimeUnit.SECONDS);
|
||||
assertEquals(jcObject.getMetadata().getSize(), data.getBytes("UTF-8").length);
|
||||
assertTrue(jcObject.getMetadata().getContentType().startsWith("text/plain"));
|
||||
assertEquals(jsResultObject.getContentLength(), data.getBytes("UTF-8").length);
|
||||
|
@ -395,7 +397,7 @@ public class JCloudsS3ServiceLiveTest
|
|||
requestObject = new S3Object(objectKey);
|
||||
requestObject.addMetadata("x-amz-meta-" + "my-metadata-1", "value-1");
|
||||
jsResultObject = service.putObject(new S3Bucket(bucketName), requestObject);
|
||||
jcObject = client.getBlob(bucketName, objectKey).get(10, TimeUnit.SECONDS);
|
||||
jcObject = context.getApi().getBlob(bucketName, objectKey).get(10, TimeUnit.SECONDS);
|
||||
assertEquals(Iterables.getLast(jcObject.getMetadata().getUserMetadata().get(
|
||||
"my-metadata-1")), "value-1");
|
||||
assertEquals(jsResultObject.getMetadata("x-amz-meta-" + "my-metadata-1"), "value-1");
|
||||
|
@ -404,8 +406,8 @@ public class JCloudsS3ServiceLiveTest
|
|||
requestObject = new S3Object(objectKey);
|
||||
requestObject.setAcl(AccessControlList.REST_CANNED_PUBLIC_READ);
|
||||
jsResultObject = service.putObject(new S3Bucket(bucketName), requestObject);
|
||||
org.jclouds.aws.s3.domain.AccessControlList jcACL = client.getBlobACL(bucketName,
|
||||
objectKey).get(10, TimeUnit.SECONDS);
|
||||
org.jclouds.aws.s3.domain.AccessControlList jcACL = context.getApi().getBlobACL(
|
||||
bucketName, objectKey).get(10, TimeUnit.SECONDS);
|
||||
assertTrue(jcACL.hasPermission(GroupGranteeURI.ALL_USERS, Permission.READ));
|
||||
assertTrue(jcACL.hasPermission(jcACL.getOwner().getId(), Permission.FULL_CONTROL));
|
||||
assertEquals(jcACL.getGrants().size(), 2);
|
||||
|
@ -420,7 +422,7 @@ public class JCloudsS3ServiceLiveTest
|
|||
data = "Here is some d‡tˆ for you";
|
||||
requestObject.setDataInputStream(new ByteArrayInputStream(data.getBytes("UTF-8")));
|
||||
jsResultObject = service.putObject(new S3Bucket(bucketName), requestObject);
|
||||
jcObject = client.getBlob(bucketName, objectKey).get(10, TimeUnit.SECONDS);
|
||||
jcObject = context.getApi().getBlob(bucketName, objectKey).get(10, TimeUnit.SECONDS);
|
||||
assertTrue(jsResultObject.verifyData(data.getBytes("UTF-8")));
|
||||
assertEquals(jsResultObject.getMd5HashAsHex(), HttpUtils.toHexString(jcObject
|
||||
.getMetadata().getETag()));
|
||||
|
@ -456,8 +458,8 @@ public class JCloudsS3ServiceLiveTest
|
|||
destinationObject = new S3Object(destinationObjectKey);
|
||||
copyResult = service.copyObject(bucketName, sourceObjectKey, bucketName,
|
||||
destinationObject, false);
|
||||
jcDestinationObject = client.getBlob(bucketName, destinationObject.getKey()).get(10,
|
||||
TimeUnit.SECONDS);
|
||||
jcDestinationObject = context.getApi().getBlob(bucketName, destinationObject.getKey())
|
||||
.get(10, TimeUnit.SECONDS);
|
||||
// TODO null keys from s3object! assertEquals(jcDestinationObject.getKey(),
|
||||
// destinationObjectKey);
|
||||
assertEquals(Iterators.getLast(jcDestinationObject.getMetadata().getUserMetadata().get(
|
||||
|
@ -465,8 +467,8 @@ public class JCloudsS3ServiceLiveTest
|
|||
assertEquals(copyResult.get("ETag"), HttpUtils.toHexString(jcDestinationObject
|
||||
.getMetadata().getETag()));
|
||||
// Test destination ACL is unchanged (ie private)
|
||||
org.jclouds.aws.s3.domain.AccessControlList jcACL = client.getBlobACL(bucketName,
|
||||
destinationObject.getKey()).get(10, TimeUnit.SECONDS);
|
||||
org.jclouds.aws.s3.domain.AccessControlList jcACL = context.getApi().getBlobACL(
|
||||
bucketName, destinationObject.getKey()).get(10, TimeUnit.SECONDS);
|
||||
assertEquals(jcACL.getGrants().size(), 1);
|
||||
assertTrue(jcACL.hasPermission(jcACL.getOwner().getId(), Permission.FULL_CONTROL));
|
||||
|
||||
|
@ -475,13 +477,13 @@ public class JCloudsS3ServiceLiveTest
|
|||
destinationObject.addMetadata("x-amz-meta-" + metadataName, destinationMetadataValue);
|
||||
copyResult = service.copyObject(bucketName, sourceObjectKey, bucketName,
|
||||
destinationObject, true);
|
||||
jcDestinationObject = client.getBlob(bucketName, destinationObject.getKey()).get(10,
|
||||
TimeUnit.SECONDS);
|
||||
jcDestinationObject = context.getApi().getBlob(bucketName, destinationObject.getKey())
|
||||
.get(10, TimeUnit.SECONDS);
|
||||
assertEquals(Iterators.getLast(jcDestinationObject.getMetadata().getUserMetadata().get(
|
||||
metadataName).iterator()), destinationMetadataValue);
|
||||
// Test destination ACL is unchanged (ie private)
|
||||
jcACL = client.getBlobACL(bucketName, destinationObject.getKey())
|
||||
.get(10, TimeUnit.SECONDS);
|
||||
jcACL = context.getApi().getBlobACL(bucketName, destinationObject.getKey()).get(10,
|
||||
TimeUnit.SECONDS);
|
||||
assertEquals(jcACL.getGrants().size(), 1);
|
||||
assertTrue(jcACL.hasPermission(jcACL.getOwner().getId(), Permission.FULL_CONTROL));
|
||||
|
||||
|
@ -491,8 +493,8 @@ public class JCloudsS3ServiceLiveTest
|
|||
copyResult = service.copyObject(bucketName, sourceObjectKey, bucketName,
|
||||
destinationObject, false);
|
||||
// Test destination ACL is changed (ie public-read)
|
||||
jcACL = client.getBlobACL(bucketName, destinationObject.getKey())
|
||||
.get(10, TimeUnit.SECONDS);
|
||||
jcACL = context.getApi().getBlobACL(bucketName, destinationObject.getKey()).get(10,
|
||||
TimeUnit.SECONDS);
|
||||
assertEquals(jcACL.getGrants().size(), 2);
|
||||
assertTrue(jcACL.hasPermission(jcACL.getOwner().getId(), Permission.FULL_CONTROL));
|
||||
assertTrue(jcACL.hasPermission(GroupGranteeURI.ALL_USERS, Permission.READ));
|
||||
|
@ -671,7 +673,8 @@ public class JCloudsS3ServiceLiveTest
|
|||
multiService.putObjects(bucket, objects);
|
||||
|
||||
assertEquals(countOfUploadCompletions[0], OBJECT_COUNT);
|
||||
ListBucketResponse theBucket = client.listBlobs(bucketName).get(10, TimeUnit.SECONDS);
|
||||
ListBucketResponse theBucket = context.getApi().listBlobs(bucketName).get(10,
|
||||
TimeUnit.SECONDS);
|
||||
assertEquals(theBucket.size(), OBJECT_COUNT);
|
||||
|
||||
} finally {
|
||||
|
|
|
@ -45,7 +45,7 @@ public abstract class BaseJCloudsPerformanceLiveTest extends BasePerformanceLive
|
|||
// object.setContentType("application/octetstream");
|
||||
// //object.setData("this is a test");
|
||||
// object.setData(test);
|
||||
// return clientProvider.getObject(s3Bucket,
|
||||
// return context.getApi()Provider.getObject(s3Bucket,
|
||||
// object.getKey()).get(120,TimeUnit.SECONDS) !=
|
||||
// org.jclouds.aws.s3.domain.S3Object.NOT_FOUND;
|
||||
|
||||
|
@ -57,7 +57,7 @@ public abstract class BaseJCloudsPerformanceLiveTest extends BasePerformanceLive
|
|||
org.jclouds.aws.s3.domain.S3Object object = new org.jclouds.aws.s3.domain.S3Object(key);
|
||||
object.getMetadata().setContentType(contentType);
|
||||
object.setData(data);
|
||||
return client.putBlob(bucket, object).get(120, TimeUnit.SECONDS) != null;
|
||||
return context.getApi().putBlob(bucket, object).get(120, TimeUnit.SECONDS) != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -66,7 +66,7 @@ public abstract class BaseJCloudsPerformanceLiveTest extends BasePerformanceLive
|
|||
org.jclouds.aws.s3.domain.S3Object object = new org.jclouds.aws.s3.domain.S3Object(key);
|
||||
object.getMetadata().setContentType(contentType);
|
||||
object.setData(data);
|
||||
return client.putBlob(bucket, object).get(120, TimeUnit.SECONDS) != null;
|
||||
return context.getApi().putBlob(bucket, object).get(120, TimeUnit.SECONDS) != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -76,7 +76,7 @@ public abstract class BaseJCloudsPerformanceLiveTest extends BasePerformanceLive
|
|||
object.getMetadata().setContentType(contentType);
|
||||
object.setData(data);
|
||||
object.getMetadata().setSize(data.available());
|
||||
return client.putBlob(bucket, object).get(120, TimeUnit.SECONDS) != null;
|
||||
return context.getApi().putBlob(bucket, object).get(120, TimeUnit.SECONDS) != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -85,6 +85,6 @@ public abstract class BaseJCloudsPerformanceLiveTest extends BasePerformanceLive
|
|||
org.jclouds.aws.s3.domain.S3Object object = new org.jclouds.aws.s3.domain.S3Object(key);
|
||||
object.getMetadata().setContentType(contentType);
|
||||
object.setData(data);
|
||||
return client.putBlob(bucket, object).get(120, TimeUnit.SECONDS) != null;
|
||||
return context.getApi().putBlob(bucket, object).get(120, TimeUnit.SECONDS) != null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,6 +38,8 @@ import java.util.concurrent.TimeUnit;
|
|||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import javax.inject.Provider;
|
||||
|
||||
import org.jclouds.aws.s3.domain.BucketMetadata;
|
||||
import org.jclouds.aws.s3.domain.ObjectMetadata;
|
||||
import org.jclouds.aws.s3.domain.S3Object;
|
||||
|
@ -47,8 +49,6 @@ import org.testng.annotations.AfterClass;
|
|||
import org.testng.annotations.BeforeClass;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import javax.inject.Provider;
|
||||
|
||||
/**
|
||||
* Tests relative performance of S3 functions.
|
||||
*
|
||||
|
@ -94,7 +94,7 @@ public abstract class BasePerformanceLiveTest extends
|
|||
protected String createScratchContainerInEU() throws InterruptedException, ExecutionException,
|
||||
TimeoutException {
|
||||
String containerName = getScratchContainerName();
|
||||
client.createContainer(containerName, createIn(LocationConstraint.EU)).get(30,
|
||||
context.getApi().createContainer(containerName, createIn(LocationConstraint.EU)).get(30,
|
||||
TimeUnit.SECONDS);
|
||||
return containerName;
|
||||
}
|
||||
|
|
|
@ -29,6 +29,9 @@ import java.util.concurrent.ExecutionException;
|
|||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Provider;
|
||||
import javax.inject.Singleton;
|
||||
import javax.servlet.RequestDispatcher;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
|
@ -42,9 +45,6 @@ import org.jclouds.samples.googleappengine.domain.BucketResult;
|
|||
import org.jclouds.samples.googleappengine.functions.MetadataToBucketResult;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Provider;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
/**
|
||||
* Shows an example of how to use @{link S3Connection} injected with Guice.
|
||||
|
|
|
@ -23,10 +23,13 @@
|
|||
*/
|
||||
package org.jclouds.samples.googleappengine.config;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Properties;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import com.google.inject.Injector;
|
||||
import com.google.inject.servlet.GuiceServletContextListener;
|
||||
import com.google.inject.servlet.ServletModule;
|
||||
import javax.servlet.ServletContextEvent;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.jclouds.aws.s3.S3Context;
|
||||
import org.jclouds.aws.s3.S3ContextBuilder;
|
||||
|
@ -34,10 +37,9 @@ import org.jclouds.aws.s3.reference.S3Constants;
|
|||
import org.jclouds.gae.config.GaeHttpCommandExecutorServiceModule;
|
||||
import org.jclouds.samples.googleappengine.GetAllBucketsController;
|
||||
|
||||
import javax.servlet.ServletContextEvent;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Properties;
|
||||
import com.google.inject.Injector;
|
||||
import com.google.inject.servlet.GuiceServletContextListener;
|
||||
import com.google.inject.servlet.ServletModule;
|
||||
|
||||
/**
|
||||
* Setup Logging and create Injector for use in testing S3.
|
||||
|
@ -74,7 +76,7 @@ public class GuiceServletConfig extends GuiceServletContextListener {
|
|||
|
||||
@Override
|
||||
protected Injector getInjector() {
|
||||
return S3ContextBuilder.newBuilder(accessKeyId, secretAccessKey).withModules(
|
||||
return new S3ContextBuilder(accessKeyId, secretAccessKey).withModules(
|
||||
new GaeHttpCommandExecutorServiceModule(), new ServletModule() {
|
||||
@Override
|
||||
protected void configureServlets() {
|
||||
|
|
|
@ -25,6 +25,7 @@ package org.jclouds.azure.storage.blob;
|
|||
|
||||
import org.jclouds.azure.storage.blob.domain.Blob;
|
||||
import org.jclouds.azure.storage.blob.domain.BlobMetadata;
|
||||
import org.jclouds.azure.storage.blob.domain.ContainerMetadata;
|
||||
import org.jclouds.blobstore.BlobStoreContext;
|
||||
import org.jclouds.cloud.CloudContext;
|
||||
|
||||
|
@ -37,6 +38,7 @@ import org.jclouds.cloud.CloudContext;
|
|||
* @author Adrian Cole
|
||||
*
|
||||
*/
|
||||
public interface AzureBlobContext extends BlobStoreContext<AzureBlobStore, BlobMetadata, Blob> {
|
||||
public interface AzureBlobContext extends
|
||||
BlobStoreContext<AzureBlobStore, ContainerMetadata, BlobMetadata, Blob> {
|
||||
|
||||
}
|
|
@ -29,17 +29,22 @@ import static org.jclouds.blobstore.reference.BlobStoreConstants.PROPERTY_USER_M
|
|||
import java.net.URI;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
|
||||
import org.jclouds.azure.storage.blob.config.AzureBlobContextModule;
|
||||
import org.jclouds.azure.storage.blob.config.RestAzureBlobStoreModule;
|
||||
import org.jclouds.azure.storage.blob.domain.Blob;
|
||||
import org.jclouds.azure.storage.blob.domain.BlobMetadata;
|
||||
import org.jclouds.azure.storage.blob.domain.ContainerMetadata;
|
||||
import org.jclouds.azure.storage.blob.reference.AzureBlobConstants;
|
||||
import org.jclouds.azure.storage.reference.AzureStorageConstants;
|
||||
import org.jclouds.cloud.CloudContextBuilder;
|
||||
import org.jclouds.blobstore.BlobStoreContextBuilder;
|
||||
import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule;
|
||||
import org.jclouds.logging.jdk.config.JDKLoggingModule;
|
||||
|
||||
import com.google.inject.Injector;
|
||||
import com.google.inject.Module;
|
||||
import com.google.inject.TypeLiteral;
|
||||
|
||||
/**
|
||||
* Creates {@link AzureBlobContext} or {@link Injector} instances based on the most commonly
|
||||
|
@ -51,33 +56,30 @@ import com.google.inject.Module;
|
|||
* If no <code>Module</code>s are specified, the default {@link JDKLoggingModule logging} and
|
||||
* {@link JavaUrlHttpCommandExecutorServiceModule http transports} will be installed.
|
||||
*
|
||||
* @author Adrian Cole
|
||||
* @author Adrian Cole, Andrew Newdigate
|
||||
* @see AzureBlobContext
|
||||
*/
|
||||
public class AzureBlobContextBuilder extends CloudContextBuilder<AzureBlobContext> {
|
||||
public class AzureBlobContextBuilder extends
|
||||
BlobStoreContextBuilder<AzureBlobStore, ContainerMetadata, BlobMetadata, Blob> {
|
||||
|
||||
@Override
|
||||
public AzureBlobContext buildContext() {
|
||||
return this.buildInjector().getInstance(AzureBlobContext.class);
|
||||
}
|
||||
|
||||
public AzureBlobContextBuilder(Properties props) {
|
||||
super(props);
|
||||
super(new TypeLiteral<AzureBlobStore>() {
|
||||
}, new TypeLiteral<ContainerMetadata>() {
|
||||
}, new TypeLiteral<BlobMetadata>() {
|
||||
}, new TypeLiteral<Blob>() {
|
||||
}, 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();
|
||||
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) {
|
||||
public AzureBlobContextBuilder(String id, String secret) {
|
||||
this(new Properties());
|
||||
properties.setProperty(AzureStorageConstants.PROPERTY_AZURESTORAGE_ACCOUNT, checkNotNull(id,
|
||||
"azureStorageAccount"));
|
||||
properties.setProperty(AzureStorageConstants.PROPERTY_AZURESTORAGE_KEY, checkNotNull(secret,
|
||||
|
@ -87,15 +89,86 @@ public class AzureBlobContextBuilder extends CloudContextBuilder<AzureBlobContex
|
|||
"\\{account\\}", id));
|
||||
}
|
||||
|
||||
public AzureBlobContext buildContext() {
|
||||
return buildInjector().getInstance(AzureBlobContext.class);
|
||||
@Override
|
||||
public AzureBlobContextBuilder relaxSSLHostname() {
|
||||
return (AzureBlobContextBuilder) super.relaxSSLHostname();
|
||||
}
|
||||
|
||||
@Override
|
||||
public AzureBlobContextBuilder withExecutorService(ExecutorService service) {
|
||||
return (AzureBlobContextBuilder) super.withExecutorService(service);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AzureBlobContextBuilder withHttpMaxRedirects(int httpMaxRedirects) {
|
||||
return (AzureBlobContextBuilder) super.withHttpMaxRedirects(httpMaxRedirects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AzureBlobContextBuilder withHttpMaxRetries(int httpMaxRetries) {
|
||||
return (AzureBlobContextBuilder) super.withHttpMaxRetries(httpMaxRetries);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AzureBlobContextBuilder withJsonDebug() {
|
||||
return (AzureBlobContextBuilder) super.withJsonDebug();
|
||||
}
|
||||
|
||||
@Override
|
||||
public AzureBlobContextBuilder withModule(Module module) {
|
||||
return (AzureBlobContextBuilder) super.withModule(module);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AzureBlobContextBuilder withModules(Module... modules) {
|
||||
return (AzureBlobContextBuilder) super.withModules(modules);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AzureBlobContextBuilder withPoolIoWorkerThreads(int poolIoWorkerThreads) {
|
||||
return (AzureBlobContextBuilder) super.withPoolIoWorkerThreads(poolIoWorkerThreads);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AzureBlobContextBuilder withPoolMaxConnectionReuse(int poolMaxConnectionReuse) {
|
||||
return (AzureBlobContextBuilder) super.withPoolMaxConnectionReuse(poolMaxConnectionReuse);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AzureBlobContextBuilder withPoolMaxConnections(int poolMaxConnections) {
|
||||
return (AzureBlobContextBuilder) super.withPoolMaxConnections(poolMaxConnections);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AzureBlobContextBuilder withPoolMaxSessionFailures(int poolMaxSessionFailures) {
|
||||
return (AzureBlobContextBuilder) super.withPoolMaxSessionFailures(poolMaxSessionFailures);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AzureBlobContextBuilder withPoolRequestInvokerThreads(int poolRequestInvokerThreads) {
|
||||
return (AzureBlobContextBuilder) super
|
||||
.withPoolRequestInvokerThreads(poolRequestInvokerThreads);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AzureBlobContextBuilder withSaxDebug() {
|
||||
return (AzureBlobContextBuilder) (AzureBlobContextBuilder) super.withSaxDebug();
|
||||
}
|
||||
|
||||
@Override
|
||||
public AzureBlobContextBuilder withEndpoint(URI endpoint) {
|
||||
properties.setProperty(AzureBlobConstants.PROPERTY_AZUREBLOB_ENDPOINT, checkNotNull(endpoint,
|
||||
"endpoint").toString());
|
||||
return (AzureBlobContextBuilder) this;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addContextModule(List<Module> modules) {
|
||||
modules.add(new AzureBlobContextModule());
|
||||
}
|
||||
|
||||
protected void addApiModule(List<Module> modules) {
|
||||
@Override
|
||||
protected void addConnectionModule(List<Module> modules) {
|
||||
modules.add(new RestAzureBlobStoreModule());
|
||||
}
|
||||
|
||||
|
|
|
@ -39,20 +39,19 @@ import com.google.inject.Module;
|
|||
* If no <code>Module</code>s are specified, the default {@link JDKLoggingModule logging} and
|
||||
* {@link JavaUrlHttpCommandExecutorServiceModule http transports} will be installed.
|
||||
*
|
||||
* @author Adrian Cole, Andrew Newdigate
|
||||
* @author Adrian Cole
|
||||
* @see AzureBlobContext
|
||||
*/
|
||||
public class AzureBlobContextFactory {
|
||||
|
||||
public static AzureBlobContext createAzureBlobContext(String account, String encodedKey,
|
||||
public static AzureBlobContext createContext(String account, String encodedKey,
|
||||
Module... modules) {
|
||||
return AzureBlobContextBuilder.newBuilder(account, encodedKey).withModules(modules)
|
||||
.buildContext();
|
||||
return new AzureBlobContextBuilder(account, encodedKey).withModules(modules).buildContext();
|
||||
}
|
||||
|
||||
public static AzureBlobContext createAzureBlobContext(URI endpoint, String account,
|
||||
String encodedKey, Module... modules) {
|
||||
return AzureBlobContextBuilder.newBuilder(account, encodedKey).withEndpoint(endpoint)
|
||||
.withModules(modules).buildContext();
|
||||
public static AzureBlobContext createContext(URI endpoint, String account, String encodedKey,
|
||||
Module... modules) {
|
||||
return new AzureBlobContextBuilder(account, encodedKey).withEndpoint(endpoint).withModules(
|
||||
modules).buildContext();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,19 +23,25 @@
|
|||
*/
|
||||
package org.jclouds.azure.storage.blob.config;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Provider;
|
||||
|
||||
import org.jclouds.azure.storage.AzureBlob;
|
||||
import org.jclouds.azure.storage.blob.AzureBlobContext;
|
||||
import org.jclouds.azure.storage.blob.AzureBlobStore;
|
||||
import org.jclouds.azure.storage.blob.domain.Blob;
|
||||
import org.jclouds.azure.storage.blob.domain.BlobMetadata;
|
||||
import org.jclouds.azure.storage.blob.internal.GuiceAzureBlobContext;
|
||||
import org.jclouds.azure.storage.blob.internal.LiveAzureBlobInputStreamMap;
|
||||
import org.jclouds.azure.storage.blob.internal.LiveAzureBlobObjectMap;
|
||||
import org.jclouds.blobstore.functions.ParseBlobFromHeadersAndHttpContent.BlobFactory;
|
||||
import org.jclouds.blobstore.functions.ParseContentTypeFromHeaders.BlobMetadataFactory;
|
||||
import org.jclouds.azure.storage.blob.domain.ContainerMetadata;
|
||||
import org.jclouds.azure.storage.reference.AzureStorageConstants;
|
||||
import org.jclouds.blobstore.BlobStoreContextImpl;
|
||||
import org.jclouds.blobstore.BlobMap.Factory;
|
||||
import org.jclouds.lifecycle.Closer;
|
||||
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.TypeLiteral;
|
||||
import com.google.inject.assistedinject.FactoryProvider;
|
||||
import com.google.inject.Scopes;
|
||||
|
||||
/**
|
||||
* Configures the {@link AzureBlobContext}; requires {@link AzureBlobStore} bound.
|
||||
|
@ -43,29 +49,23 @@ import com.google.inject.assistedinject.FactoryProvider;
|
|||
* @author Adrian Cole
|
||||
*/
|
||||
public class AzureBlobContextModule extends AbstractModule {
|
||||
protected final TypeLiteral<BlobMetadataFactory<BlobMetadata>> objectMetadataFactoryLiteral = new TypeLiteral<BlobMetadataFactory<BlobMetadata>>() {
|
||||
};
|
||||
protected final TypeLiteral<BlobFactory<BlobMetadata, Blob>> objectFactoryLiteral = new TypeLiteral<BlobFactory<BlobMetadata, Blob>>() {
|
||||
};
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
this.requireBinding(AzureBlobStore.class);
|
||||
bind(GuiceAzureBlobContext.AzureBlobObjectMapFactory.class).toProvider(
|
||||
FactoryProvider.newFactory(GuiceAzureBlobContext.AzureBlobObjectMapFactory.class,
|
||||
LiveAzureBlobObjectMap.class));
|
||||
bind(GuiceAzureBlobContext.AzureBlobInputStreamMapFactory.class).toProvider(
|
||||
FactoryProvider.newFactory(
|
||||
GuiceAzureBlobContext.AzureBlobInputStreamMapFactory.class,
|
||||
LiveAzureBlobInputStreamMap.class));
|
||||
bind(AzureBlobContext.class).to(GuiceAzureBlobContext.class);
|
||||
bind(objectMetadataFactoryLiteral).toProvider(
|
||||
FactoryProvider.newFactory(objectMetadataFactoryLiteral,
|
||||
new TypeLiteral<BlobMetadata>() {
|
||||
}));
|
||||
bind(objectFactoryLiteral).toProvider(
|
||||
FactoryProvider.newFactory(objectFactoryLiteral, new TypeLiteral<Blob>() {
|
||||
}));
|
||||
bind(AzureBlobContext.class).to(AzureBlobContextImpl.class).in(Scopes.SINGLETON);
|
||||
}
|
||||
|
||||
public static class AzureBlobContextImpl extends
|
||||
BlobStoreContextImpl<AzureBlobStore, ContainerMetadata, BlobMetadata, Blob> implements
|
||||
AzureBlobContext {
|
||||
@Inject
|
||||
AzureBlobContextImpl(Factory<BlobMetadata, Blob> blobMapFactory,
|
||||
org.jclouds.blobstore.InputStreamMap.Factory<BlobMetadata> inputStreamMapFactory,
|
||||
Closer closer, Provider<Blob> blobProvider, AzureBlobStore defaultApi,
|
||||
@AzureBlob URI endPoint,
|
||||
@Named(AzureStorageConstants.PROPERTY_AZURESTORAGE_ACCOUNT) String account) {
|
||||
super(blobMapFactory, inputStreamMapFactory, closer, blobProvider, defaultApi, endPoint,
|
||||
account);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,9 +23,6 @@
|
|||
*/
|
||||
package org.jclouds.azure.storage.blob.domain;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import com.google.inject.assistedinject.Assisted;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
|
@ -35,8 +32,7 @@ public class Blob extends org.jclouds.blobstore.domain.Blob<BlobMetadata> {
|
|||
super(metadata, data);
|
||||
}
|
||||
|
||||
@Inject
|
||||
public Blob(@Assisted BlobMetadata metadata) {
|
||||
public Blob(BlobMetadata metadata) {
|
||||
super(metadata);
|
||||
}
|
||||
|
||||
|
@ -48,4 +44,8 @@ public class Blob extends org.jclouds.blobstore.domain.Blob<BlobMetadata> {
|
|||
this(new BlobMetadata(key));
|
||||
}
|
||||
|
||||
public Blob() {
|
||||
this(new BlobMetadata());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -25,6 +25,8 @@ package org.jclouds.azure.storage.blob.domain;
|
|||
|
||||
import java.net.URI;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.joda.time.DateTime;
|
||||
|
||||
import com.google.inject.internal.Nullable;
|
||||
|
@ -41,6 +43,7 @@ public class BlobMetadata extends org.jclouds.blobstore.domain.BlobMetadata {
|
|||
private String contentLanguage;
|
||||
protected String dataEncoding;
|
||||
|
||||
@Inject
|
||||
public BlobMetadata() {
|
||||
super();
|
||||
}
|
||||
|
|
|
@ -85,6 +85,10 @@ public class ContainerMetadata extends org.jclouds.blobstore.domain.ContainerMet
|
|||
this.eTag = eTag;
|
||||
}
|
||||
|
||||
public ContainerMetadata() {
|
||||
super();
|
||||
}
|
||||
|
||||
public ContainerMetadata(String name) {
|
||||
super(name);
|
||||
}
|
||||
|
|
|
@ -23,12 +23,13 @@
|
|||
*/
|
||||
package org.jclouds.azure.storage.blob.functions;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Provider;
|
||||
|
||||
import org.jclouds.azure.storage.blob.domain.Blob;
|
||||
import org.jclouds.azure.storage.blob.domain.BlobMetadata;
|
||||
import org.jclouds.blobstore.functions.ParseSystemAndUserMetadataFromHeaders;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
/**
|
||||
* Parses response headers and creates a new Azure Blob from them and the HTTP content.
|
||||
*
|
||||
|
@ -40,7 +41,7 @@ public class ParseBlobFromHeadersAndHttpContent extends
|
|||
@Inject
|
||||
public ParseBlobFromHeadersAndHttpContent(
|
||||
ParseSystemAndUserMetadataFromHeaders<BlobMetadata> metadataParser,
|
||||
BlobFactory<BlobMetadata, Blob> blobFactory) {
|
||||
Provider<Blob> blobFactory) {
|
||||
super(metadataParser, blobFactory);
|
||||
}
|
||||
}
|
|
@ -25,15 +25,15 @@ package org.jclouds.azure.storage.blob.functions;
|
|||
|
||||
import static org.jclouds.blobstore.reference.BlobStoreConstants.PROPERTY_USER_METADATA_PREFIX;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Provider;
|
||||
import javax.ws.rs.core.HttpHeaders;
|
||||
|
||||
import org.jclouds.azure.storage.blob.domain.BlobMetadata;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.jclouds.util.DateService;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
|
||||
/**
|
||||
* This parses @{link {@link org.jclouds.azure.storage.blob.domain.BlobMetadata} from HTTP headers.
|
||||
*
|
||||
|
@ -45,7 +45,7 @@ public class ParseBlobMetadataFromHeaders extends org.jclouds.blobstore.function
|
|||
@Inject
|
||||
public ParseBlobMetadataFromHeaders(DateService dateParser,
|
||||
@Named(PROPERTY_USER_METADATA_PREFIX) String metadataPrefix,
|
||||
BlobMetadataFactory<BlobMetadata> metadataFactory) {
|
||||
Provider<BlobMetadata> metadataFactory) {
|
||||
super(dateParser, metadataPrefix, metadataFactory);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,118 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.azure.storage.blob.internal;
|
||||
|
||||
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.AzureBlob;
|
||||
import org.jclouds.azure.storage.blob.AzureBlobContext;
|
||||
import org.jclouds.azure.storage.blob.AzureBlobStore;
|
||||
import org.jclouds.azure.storage.blob.domain.Blob;
|
||||
import org.jclouds.azure.storage.blob.domain.BlobMetadata;
|
||||
import org.jclouds.azure.storage.reference.AzureStorageConstants;
|
||||
import org.jclouds.blobstore.BlobMap;
|
||||
import org.jclouds.blobstore.InputStreamMap;
|
||||
import org.jclouds.lifecycle.Closer;
|
||||
import org.jclouds.logging.Logger;
|
||||
|
||||
import com.google.inject.Injector;
|
||||
|
||||
/**
|
||||
* Uses a Guice Injector to configure the objects served by AzureBlobContext methods.
|
||||
*
|
||||
* @author Adrian Cole
|
||||
* @see Injector
|
||||
*/
|
||||
public class GuiceAzureBlobContext implements AzureBlobContext {
|
||||
public interface AzureBlobObjectMapFactory {
|
||||
BlobMap<BlobMetadata, Blob> createMapView(String container);
|
||||
}
|
||||
|
||||
public interface AzureBlobInputStreamMapFactory {
|
||||
InputStreamMap<BlobMetadata> createMapView(String container);
|
||||
}
|
||||
|
||||
@Resource
|
||||
private Logger logger = Logger.NULL;
|
||||
private final Injector injector;
|
||||
private final Closer closer;
|
||||
private final AzureBlobInputStreamMapFactory azureInputStreamMapFactory;
|
||||
private final AzureBlobObjectMapFactory azureObjectMapFactory;
|
||||
private final URI endPoint;
|
||||
private final String account;
|
||||
|
||||
@Inject
|
||||
private GuiceAzureBlobContext(Injector injector, Closer closer,
|
||||
AzureBlobObjectMapFactory azureObjectMapFactory,
|
||||
AzureBlobInputStreamMapFactory azureInputStreamMapFactory,
|
||||
@Named(AzureStorageConstants.PROPERTY_AZURESTORAGE_ACCOUNT) String account,
|
||||
@AzureBlob URI endPoint) {
|
||||
this.injector = injector;
|
||||
this.closer = closer;
|
||||
this.azureInputStreamMapFactory = azureInputStreamMapFactory;
|
||||
this.azureObjectMapFactory = azureObjectMapFactory;
|
||||
this.endPoint = endPoint;
|
||||
this.account = account;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @see Closer
|
||||
*/
|
||||
public void close() {
|
||||
try {
|
||||
closer.close();
|
||||
} catch (IOException e) {
|
||||
logger.error(e, "error closing content");
|
||||
}
|
||||
}
|
||||
|
||||
public String getAccount() {
|
||||
return account;
|
||||
}
|
||||
|
||||
public AzureBlobStore getApi() {
|
||||
return injector.getInstance(AzureBlobStore.class);
|
||||
}
|
||||
|
||||
public URI getEndPoint() {
|
||||
return endPoint;
|
||||
}
|
||||
|
||||
public BlobMap<BlobMetadata, Blob> createBlobMap(String container) {
|
||||
getApi().createContainer(container);
|
||||
return azureObjectMapFactory.createMapView(container);
|
||||
}
|
||||
|
||||
public InputStreamMap<BlobMetadata> createInputStreamMap(String container) {
|
||||
getApi().createContainer(container);
|
||||
return azureInputStreamMapFactory.createMapView(container);
|
||||
}
|
||||
}
|
|
@ -1,61 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.azure.storage.blob.internal;
|
||||
|
||||
import org.jclouds.azure.storage.blob.AzureBlobStore;
|
||||
import org.jclouds.azure.storage.blob.domain.Blob;
|
||||
import org.jclouds.azure.storage.blob.domain.BlobMetadata;
|
||||
import org.jclouds.azure.storage.blob.domain.ContainerMetadata;
|
||||
import org.jclouds.blobstore.LiveInputStreamMap;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import com.google.inject.assistedinject.Assisted;
|
||||
|
||||
/**
|
||||
* Map representation of a live connection to AzureBlob. All put operations will result in ETag
|
||||
* calculation. If this is not desired, use {@link LiveAzureBlobObjectMap} instead.
|
||||
*
|
||||
* @author Adrian Cole
|
||||
* @see AzureBlobStore
|
||||
* @see LiveInputStreamMap
|
||||
*/
|
||||
public class LiveAzureBlobInputStreamMap extends
|
||||
LiveInputStreamMap<ContainerMetadata, BlobMetadata, Blob> {
|
||||
|
||||
@Override
|
||||
public boolean containsValue(Object value) {
|
||||
throw new UnsupportedOperationException(
|
||||
"http://code.google.com/p/jclouds/issues/detail?id=90");
|
||||
}
|
||||
|
||||
@Inject
|
||||
public LiveAzureBlobInputStreamMap(AzureBlobStore connection, @Assisted String container) {
|
||||
super(connection, container);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Blob createBlob(String s) {
|
||||
return new Blob(s);
|
||||
}
|
||||
}
|
|
@ -1,55 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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.azure.storage.blob.internal;
|
||||
|
||||
import org.jclouds.azure.storage.blob.AzureBlobStore;
|
||||
import org.jclouds.azure.storage.blob.domain.Blob;
|
||||
import org.jclouds.azure.storage.blob.domain.BlobMetadata;
|
||||
import org.jclouds.azure.storage.blob.domain.ContainerMetadata;
|
||||
import org.jclouds.blobstore.LiveBlobMap;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import com.google.inject.assistedinject.Assisted;
|
||||
|
||||
/**
|
||||
* Map representation of a live connection to AzureBlob.
|
||||
*
|
||||
* @see AzureBlobStore
|
||||
* @see LiveBlobMap
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class LiveAzureBlobObjectMap extends LiveBlobMap<ContainerMetadata, BlobMetadata, Blob> {
|
||||
|
||||
@Inject
|
||||
public LiveAzureBlobObjectMap(AzureBlobStore connection, @Assisted String container) {
|
||||
super(connection, container);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsValue(Object value) {
|
||||
throw new UnsupportedOperationException(
|
||||
"http://code.google.com/p/jclouds/issues/detail?id=90");
|
||||
}
|
||||
}
|
|
@ -32,19 +32,14 @@ import java.util.List;
|
|||
|
||||
import org.jclouds.azure.storage.blob.config.AzureBlobContextModule;
|
||||
import org.jclouds.azure.storage.blob.config.RestAzureBlobStoreModule;
|
||||
import org.jclouds.azure.storage.blob.domain.Blob;
|
||||
import org.jclouds.azure.storage.blob.domain.BlobMetadata;
|
||||
import org.jclouds.azure.storage.blob.internal.GuiceAzureBlobContext;
|
||||
import org.jclouds.azure.storage.blob.config.StubAzureBlobStoreModule;
|
||||
import org.jclouds.azure.storage.blob.config.AzureBlobContextModule.AzureBlobContextImpl;
|
||||
import org.jclouds.azure.storage.reference.AzureStorageConstants;
|
||||
import org.jclouds.blobstore.functions.ParseBlobFromHeadersAndHttpContent.BlobFactory;
|
||||
import org.jclouds.blobstore.functions.ParseContentTypeFromHeaders.BlobMetadataFactory;
|
||||
import org.jclouds.cloud.CloudContext;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.inject.Injector;
|
||||
import com.google.inject.Key;
|
||||
import com.google.inject.Module;
|
||||
import com.google.inject.TypeLiteral;
|
||||
|
||||
/**
|
||||
* Tests behavior of modules configured in AzureBlobContextBuilder
|
||||
|
@ -55,7 +50,8 @@ import com.google.inject.TypeLiteral;
|
|||
public class AzureBlobContextBuilderTest {
|
||||
|
||||
public void testNewBuilder() {
|
||||
AzureBlobContextBuilder builder = AzureBlobContextBuilder.newBuilder("id", "secret");
|
||||
AzureBlobContextBuilder builder = new AzureBlobContextBuilder("id", "secret")
|
||||
.withModules(new StubAzureBlobStoreModule());
|
||||
assertEquals(builder.getProperties().getProperty(PROPERTY_USER_METADATA_PREFIX), "x-ms-meta-");
|
||||
assertEquals(builder.getProperties().getProperty(
|
||||
AzureStorageConstants.PROPERTY_AZURESTORAGE_ACCOUNT), "id");
|
||||
|
@ -64,27 +60,22 @@ public class AzureBlobContextBuilderTest {
|
|||
}
|
||||
|
||||
public void testBuildContext() {
|
||||
CloudContext<AzureBlobStore> context = AzureBlobContextBuilder.newBuilder("id", "secret")
|
||||
.buildContext();
|
||||
assertEquals(context.getClass(), GuiceAzureBlobContext.class);
|
||||
CloudContext<AzureBlobStore> context = new AzureBlobContextBuilder("id", "secret")
|
||||
.withModules(new StubAzureBlobStoreModule()).buildContext();
|
||||
assertEquals(context.getClass(), AzureBlobContextImpl.class);
|
||||
assertEquals(context.getAccount(), "id");
|
||||
assertEquals(context.getEndPoint(), URI.create("https://id.blob.core.windows.net"));
|
||||
}
|
||||
|
||||
public void testBuildInjector() {
|
||||
Injector i = AzureBlobContextBuilder.newBuilder("id", "secret").buildInjector();
|
||||
Injector i = new AzureBlobContextBuilder("id", "secret").withModules(
|
||||
new StubAzureBlobStoreModule()).buildInjector();
|
||||
assert i.getInstance(AzureBlobContext.class) != null;
|
||||
assert i.getInstance(GuiceAzureBlobContext.AzureBlobObjectMapFactory.class) != null;
|
||||
assert i.getInstance(GuiceAzureBlobContext.AzureBlobInputStreamMapFactory.class) != null;
|
||||
assert i.getInstance(Key.get(new TypeLiteral<BlobMetadataFactory<BlobMetadata>>() {
|
||||
})) != null;
|
||||
assert i.getInstance(Key.get(new TypeLiteral<BlobFactory<BlobMetadata, Blob>>() {
|
||||
})) != null;
|
||||
}
|
||||
|
||||
protected void testAddContextModule() {
|
||||
List<Module> modules = new ArrayList<Module>();
|
||||
AzureBlobContextBuilder builder = AzureBlobContextBuilder.newBuilder("id", "secret");
|
||||
AzureBlobContextBuilder builder = new AzureBlobContextBuilder("id", "secret");
|
||||
builder.addContextModule(modules);
|
||||
assertEquals(modules.size(), 1);
|
||||
assertEquals(modules.get(0).getClass(), AzureBlobContextModule.class);
|
||||
|
@ -92,8 +83,8 @@ public class AzureBlobContextBuilderTest {
|
|||
|
||||
protected void addConnectionModule() {
|
||||
List<Module> modules = new ArrayList<Module>();
|
||||
AzureBlobContextBuilder builder = AzureBlobContextBuilder.newBuilder("id", "secret");
|
||||
builder.addApiModule(modules);
|
||||
AzureBlobContextBuilder builder = new AzureBlobContextBuilder("id", "secret");
|
||||
builder.addConnectionModule(modules);
|
||||
assertEquals(modules.size(), 1);
|
||||
assertEquals(modules.get(0).getClass(), RestAzureBlobStoreModule.class);
|
||||
}
|
||||
|
|
|
@ -72,8 +72,8 @@ public class AzureBlobStoreLiveTest {
|
|||
public void setupConnection() {
|
||||
account = System.getProperty("jclouds.test.user");
|
||||
String key = System.getProperty("jclouds.test.key");
|
||||
connection = AzureBlobContextFactory.createAzureBlobContext(account, key,
|
||||
new Log4JLoggingModule()).getApi();
|
||||
connection = AzureBlobContextFactory.createContext(account, key, new Log4JLoggingModule())
|
||||
.getApi();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -24,14 +24,18 @@
|
|||
package org.jclouds.azure.storage.blob.config;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.jclouds.azure.storage.AzureBlob;
|
||||
import org.jclouds.azure.storage.blob.AzureBlobStore;
|
||||
import org.jclouds.azure.storage.blob.domain.Blob;
|
||||
import org.jclouds.azure.storage.blob.internal.StubAzureBlobStore;
|
||||
import org.jclouds.cloud.ConfiguresCloudConnection;
|
||||
import org.jclouds.http.functions.config.ParserModule;
|
||||
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.TypeLiteral;
|
||||
|
||||
/**
|
||||
* adds a stub alternative to invoking AzureBlob
|
||||
|
@ -40,10 +44,16 @@ import com.google.inject.AbstractModule;
|
|||
*/
|
||||
@ConfiguresCloudConnection
|
||||
public class StubAzureBlobStoreModule extends AbstractModule {
|
||||
|
||||
static final ConcurrentHashMap<String, Map<String, Blob>> map = new ConcurrentHashMap<String, Map<String, Blob>>();
|
||||
|
||||
protected void configure() {
|
||||
install(new ParserModule());
|
||||
bind(AzureBlobStore.class).to(StubAzureBlobStore.class);
|
||||
bind(URI.class).annotatedWith(AzureBlob.class)
|
||||
.toInstance(URI.create("http://localhost:8080"));
|
||||
bind(new TypeLiteral<Map<String, Map<String, Blob>>>() {
|
||||
}).toInstance(map);
|
||||
bind(AzureBlobStore.class).to(StubAzureBlobStore.class).asEagerSingleton();
|
||||
bind(URI.class).annotatedWith(AzureBlob.class).toInstance(
|
||||
URI.create("https://id.blob.core.windows.net"));
|
||||
}
|
||||
|
||||
}
|
|
@ -23,18 +23,16 @@
|
|||
*/
|
||||
package org.jclouds.azure.storage.blob.integration;
|
||||
|
||||
import org.jclouds.azure.storage.blob.AzureBlobContext;
|
||||
import org.jclouds.azure.storage.blob.AzureBlobContextBuilder;
|
||||
import org.jclouds.azure.storage.blob.AzureBlobContextFactory;
|
||||
import org.jclouds.azure.storage.blob.AzureBlobStore;
|
||||
import org.jclouds.azure.storage.blob.config.StubAzureBlobStoreModule;
|
||||
import org.jclouds.azure.storage.blob.domain.Blob;
|
||||
import org.jclouds.azure.storage.blob.domain.BlobMetadata;
|
||||
import org.jclouds.azure.storage.blob.domain.ContainerMetadata;
|
||||
import org.jclouds.blobstore.BlobStoreContext;
|
||||
import org.jclouds.blobstore.integration.internal.BaseBlobStoreIntegrationTest;
|
||||
import org.jclouds.blobstore.integration.internal.BaseBlobStoreIntegrationTest.BlobStoreObjectFactory;
|
||||
import org.jclouds.blobstore.integration.internal.BaseTestInitializer;
|
||||
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
|
||||
import org.testng.ITestContext;
|
||||
|
||||
import com.google.inject.Module;
|
||||
|
||||
|
@ -42,75 +40,18 @@ import com.google.inject.Module;
|
|||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class AzureBlobTestInitializer
|
||||
implements
|
||||
BaseBlobStoreIntegrationTest.TestInitializer<AzureBlobStore, ContainerMetadata, BlobMetadata, Blob> {
|
||||
public class AzureBlobTestInitializer extends
|
||||
BaseTestInitializer<AzureBlobStore, ContainerMetadata, BlobMetadata, Blob> {
|
||||
|
||||
public BaseBlobStoreIntegrationTest.TestInitializer.Result<AzureBlobStore, ContainerMetadata, BlobMetadata, Blob> init(
|
||||
Module configurationModule, ITestContext testContext) throws Exception {
|
||||
String account = System.getProperty("jclouds.test.user");
|
||||
String key = System.getProperty("jclouds.test.key");
|
||||
if (account != null)
|
||||
testContext.setAttribute("jclouds.test.user", account);
|
||||
if (key != null)
|
||||
testContext.setAttribute("jclouds.test.key", key);
|
||||
|
||||
final AzureBlobContext context;
|
||||
if (account != null) {
|
||||
context = createLiveAzureBlobContext(configurationModule, account, key);
|
||||
} else {
|
||||
context = createStubAzureBlobContext();
|
||||
}
|
||||
assert context != null;
|
||||
|
||||
final AzureBlobStore client = context.getApi();
|
||||
assert client != null;
|
||||
|
||||
final BlobStoreObjectFactory<ContainerMetadata, Blob> objectFactory = new BaseBlobStoreIntegrationTest.BlobStoreObjectFactory<ContainerMetadata, Blob>() {
|
||||
|
||||
public Blob createBlob(String key) {
|
||||
return new Blob(key);
|
||||
|
||||
}
|
||||
|
||||
public ContainerMetadata createContainerMetadata(String key) {
|
||||
return new ContainerMetadata(key);
|
||||
}
|
||||
|
||||
};
|
||||
assert objectFactory != null;
|
||||
|
||||
return new BaseBlobStoreIntegrationTest.TestInitializer.Result<AzureBlobStore, ContainerMetadata, BlobMetadata, Blob>() {
|
||||
|
||||
public AzureBlobStore getClient() {
|
||||
return client;
|
||||
}
|
||||
|
||||
public BlobStoreContext<AzureBlobStore, BlobMetadata, Blob> getContext() {
|
||||
return (BlobStoreContext<AzureBlobStore, BlobMetadata, Blob>) context;
|
||||
}
|
||||
|
||||
public BlobStoreObjectFactory<ContainerMetadata, Blob> getObjectFactory() {
|
||||
return objectFactory;
|
||||
}
|
||||
|
||||
};
|
||||
@Override
|
||||
protected BlobStoreContext<AzureBlobStore, ContainerMetadata, BlobMetadata, Blob> createLiveContext(
|
||||
Module configurationModule, String url, String app, String account, String key) {
|
||||
return new AzureBlobContextBuilder(account, key).withSaxDebug().relaxSSLHostname()
|
||||
.withModules(configurationModule, new Log4JLoggingModule()).buildContext();
|
||||
}
|
||||
|
||||
protected AzureBlobContext createStubAzureBlobContext() {
|
||||
return AzureBlobContextBuilder.newBuilder("stub", "stub").withModules(
|
||||
new StubAzureBlobStoreModule()).buildContext();
|
||||
@Override
|
||||
protected BlobStoreContext<AzureBlobStore, ContainerMetadata, BlobMetadata, Blob> createStubContext() {
|
||||
return AzureBlobContextFactory.createContext("user", "pass", new StubAzureBlobStoreModule());
|
||||
}
|
||||
|
||||
protected AzureBlobContext createLiveAzureBlobContext(Module configurationModule,
|
||||
String account, String key) {
|
||||
return buildAzureBlobContextFactory(configurationModule, account, key).buildContext();
|
||||
}
|
||||
|
||||
protected AzureBlobContextBuilder buildAzureBlobContextFactory(Module configurationModule,
|
||||
String account, String key) {
|
||||
return (AzureBlobContextBuilder) AzureBlobContextBuilder.newBuilder(account, key)
|
||||
.relaxSSLHostname().withModules(configurationModule, new Log4JLoggingModule());
|
||||
}
|
||||
|
||||
}
|
|
@ -26,10 +26,12 @@ package org.jclouds.azure.storage.blob.internal;
|
|||
import java.net.URI;
|
||||
import java.util.Map;
|
||||
import java.util.SortedSet;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Provider;
|
||||
|
||||
import org.jclouds.azure.storage.blob.AzureBlobStore;
|
||||
import org.jclouds.azure.storage.blob.domain.ArrayListBlobsResponse;
|
||||
import org.jclouds.azure.storage.blob.domain.Blob;
|
||||
|
@ -42,6 +44,7 @@ import org.jclouds.azure.storage.options.CreateOptions;
|
|||
import org.jclouds.azure.storage.options.ListOptions;
|
||||
import org.jclouds.blobstore.ContainerNotFoundException;
|
||||
import org.jclouds.blobstore.integration.internal.StubBlobStore;
|
||||
import org.jclouds.util.DateService;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.Iterables;
|
||||
|
@ -56,29 +59,11 @@ import com.google.common.collect.Sets;
|
|||
public class StubAzureBlobStore extends StubBlobStore<ContainerMetadata, BlobMetadata, Blob>
|
||||
implements AzureBlobStore {
|
||||
|
||||
@Override
|
||||
protected Blob createBlob(String name) {
|
||||
return new Blob(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Blob createBlob(BlobMetadata metadata) {
|
||||
return new Blob(metadata);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ContainerMetadata createContainerMetadata(String name) {
|
||||
return new ContainerMetadata(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* note this must be final and static so that tests coming from multiple threads will pass.
|
||||
*/
|
||||
private static final Map<String, Map<String, Blob>> containerToBlobs = new ConcurrentHashMap<String, Map<String, Blob>>();
|
||||
|
||||
@Override
|
||||
public Map<String, Map<String, Blob>> getContainerToBlobs() {
|
||||
return containerToBlobs;
|
||||
@Inject
|
||||
protected StubAzureBlobStore(Map<String, Map<String, Blob>> containerToBlobs,
|
||||
DateService dateService, Provider<ContainerMetadata> containerMetaProvider,
|
||||
Provider<Blob> blobProvider) {
|
||||
super(containerToBlobs, dateService, containerMetaProvider, blobProvider);
|
||||
}
|
||||
|
||||
public BoundedList<ContainerMetadata> listContainers(ListOptions options) {
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
*/
|
||||
package org.jclouds.azure.storage.config;
|
||||
|
||||
import org.jclouds.azure.storage.filters.SharedKeyAuthentication;
|
||||
import org.jclouds.azure.storage.handlers.ParseAzureStorageErrorFromXmlContent;
|
||||
import org.jclouds.cloud.ConfiguresCloudConnection;
|
||||
import org.jclouds.http.HttpErrorHandler;
|
||||
|
@ -31,10 +30,8 @@ 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.rest.config.JaxrsModule;
|
||||
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Scopes;
|
||||
|
||||
/**
|
||||
* Configures the AzureStorage connection, including logging and http transport.
|
||||
|
@ -47,8 +44,6 @@ public class RestAzureStorageConnectionModule extends AbstractModule {
|
|||
|
||||
@Override
|
||||
protected void configure() {
|
||||
install(new JaxrsModule());
|
||||
bind(SharedKeyAuthentication.class).in(Scopes.SINGLETON);
|
||||
bindErrorHandlers();
|
||||
bindRetryHandlers();
|
||||
}
|
||||
|
|
|
@ -23,8 +23,11 @@
|
|||
*/
|
||||
package org.jclouds.azure.storage.queue;
|
||||
|
||||
import org.jclouds.azure.storage.queue.internal.GuiceAzureQueueContext;
|
||||
import org.jclouds.cloud.CloudContext;
|
||||
|
||||
import com.google.inject.ImplementedBy;
|
||||
|
||||
/**
|
||||
* Represents an authenticated context to Azure Queue Service.
|
||||
*
|
||||
|
@ -34,6 +37,7 @@ import org.jclouds.cloud.CloudContext;
|
|||
* @author Adrian Cole
|
||||
*
|
||||
*/
|
||||
@ImplementedBy(GuiceAzureQueueContext.class)
|
||||
public interface AzureQueueContext extends CloudContext<AzureQueueConnection> {
|
||||
|
||||
}
|
|
@ -28,6 +28,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
|||
import java.net.URI;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
|
||||
import org.jclouds.azure.storage.queue.config.AzureQueueContextModule;
|
||||
import org.jclouds.azure.storage.queue.config.RestAzureQueueConnectionModule;
|
||||
|
@ -39,6 +40,7 @@ import org.jclouds.logging.jdk.config.JDKLoggingModule;
|
|||
|
||||
import com.google.inject.Injector;
|
||||
import com.google.inject.Module;
|
||||
import com.google.inject.TypeLiteral;
|
||||
|
||||
/**
|
||||
* Creates {@link AzureQueueContext} or {@link Injector} instances based on the most commonly
|
||||
|
@ -53,29 +55,12 @@ import com.google.inject.Module;
|
|||
* @author Adrian Cole
|
||||
* @see AzureQueueContext
|
||||
*/
|
||||
public class AzureQueueContextBuilder extends CloudContextBuilder<AzureQueueContext> {
|
||||
public class AzureQueueContextBuilder extends CloudContextBuilder<AzureQueueConnection> {
|
||||
private static final TypeLiteral<AzureQueueConnection> connectionType = new TypeLiteral<AzureQueueConnection>() {
|
||||
};
|
||||
|
||||
public AzureQueueContextBuilder(Properties props) {
|
||||
super(props);
|
||||
properties.setProperty(AzureQueueConstants.PROPERTY_AZUREQUEUE_ENDPOINT,
|
||||
"https://{account}.queue.core.windows.net");
|
||||
}
|
||||
|
||||
public static AzureQueueContextBuilder newBuilder(String id, String secret) {
|
||||
Properties properties = new Properties();
|
||||
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) {
|
||||
public AzureQueueContextBuilder(String id, String secret) {
|
||||
this(new Properties());
|
||||
properties.setProperty(AzureStorageConstants.PROPERTY_AZURESTORAGE_ACCOUNT, checkNotNull(id,
|
||||
"azureStorageAccount"));
|
||||
properties.setProperty(AzureStorageConstants.PROPERTY_AZURESTORAGE_KEY, checkNotNull(secret,
|
||||
|
@ -85,16 +70,106 @@ public class AzureQueueContextBuilder extends CloudContextBuilder<AzureQueueCont
|
|||
"\\{account\\}", id));
|
||||
}
|
||||
|
||||
public AzureQueueContext buildContext() {
|
||||
return buildInjector().getInstance(AzureQueueContext.class);
|
||||
public AzureQueueContextBuilder(Properties properties) {
|
||||
super(connectionType, properties);
|
||||
properties.setProperty(AzureQueueConstants.PROPERTY_AZUREQUEUE_ENDPOINT,
|
||||
"https://{account}.queue.core.windows.net");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addContextModule(List<Module> modules) {
|
||||
modules.add(new AzureQueueContextModule());
|
||||
}
|
||||
|
||||
protected void addApiModule(List<Module> modules) {
|
||||
@Override
|
||||
protected void addConnectionModule(List<Module> modules) {
|
||||
modules.add(new RestAzureQueueConnectionModule());
|
||||
}
|
||||
|
||||
@Override
|
||||
public AzureQueueContextBuilder withEndpoint(URI endpoint) {
|
||||
String account = checkNotNull(properties
|
||||
.getProperty(AzureStorageConstants.PROPERTY_AZURESTORAGE_ACCOUNT),
|
||||
"azureStorageAccount");
|
||||
properties.setProperty(AzureQueueConstants.PROPERTY_AZUREQUEUE_ENDPOINT, checkNotNull(
|
||||
endpoint, "endpoint").toString());
|
||||
properties.setProperty(AzureQueueConstants.PROPERTY_AZUREQUEUE_ENDPOINT, endpoint.toString()
|
||||
.replaceAll("\\{account\\}", account));
|
||||
return this;
|
||||
}
|
||||
|
||||
// below is to cast the builder to the correct type so that chained builder methods end correctly
|
||||
|
||||
@Override
|
||||
public AzureQueueContext buildContext() {
|
||||
Injector injector = buildInjector();
|
||||
return injector.getInstance(AzureQueueContext.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AzureQueueContextBuilder relaxSSLHostname() {
|
||||
return (AzureQueueContextBuilder) super.relaxSSLHostname();
|
||||
}
|
||||
|
||||
@Override
|
||||
public AzureQueueContextBuilder withExecutorService(ExecutorService service) {
|
||||
return (AzureQueueContextBuilder) super.withExecutorService(service);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AzureQueueContextBuilder withHttpMaxRedirects(int httpMaxRedirects) {
|
||||
return (AzureQueueContextBuilder) super.withHttpMaxRedirects(httpMaxRedirects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AzureQueueContextBuilder withHttpMaxRetries(int httpMaxRetries) {
|
||||
return (AzureQueueContextBuilder) super.withHttpMaxRetries(httpMaxRetries);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AzureQueueContextBuilder withJsonDebug() {
|
||||
return (AzureQueueContextBuilder) super.withJsonDebug();
|
||||
}
|
||||
|
||||
@Override
|
||||
public AzureQueueContextBuilder withModule(Module module) {
|
||||
return (AzureQueueContextBuilder) super.withModule(module);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AzureQueueContextBuilder withModules(Module... modules) {
|
||||
return (AzureQueueContextBuilder) super.withModules(modules);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AzureQueueContextBuilder withPoolIoWorkerThreads(int poolIoWorkerThreads) {
|
||||
return (AzureQueueContextBuilder) super.withPoolIoWorkerThreads(poolIoWorkerThreads);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AzureQueueContextBuilder withPoolMaxConnectionReuse(int poolMaxConnectionReuse) {
|
||||
return (AzureQueueContextBuilder) super.withPoolMaxConnectionReuse(poolMaxConnectionReuse);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AzureQueueContextBuilder withPoolMaxConnections(int poolMaxConnections) {
|
||||
return (AzureQueueContextBuilder) super.withPoolMaxConnections(poolMaxConnections);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AzureQueueContextBuilder withPoolMaxSessionFailures(int poolMaxSessionFailures) {
|
||||
return (AzureQueueContextBuilder) super.withPoolMaxSessionFailures(poolMaxSessionFailures);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AzureQueueContextBuilder withPoolRequestInvokerThreads(int poolRequestInvokerThreads) {
|
||||
return (AzureQueueContextBuilder) super
|
||||
.withPoolRequestInvokerThreads(poolRequestInvokerThreads);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AzureQueueContextBuilder withSaxDebug() {
|
||||
return (AzureQueueContextBuilder) super.withSaxDebug();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -39,20 +39,19 @@ import com.google.inject.Module;
|
|||
* If no <code>Module</code>s are specified, the default {@link JDKLoggingModule logging} and
|
||||
* {@link JavaUrlHttpCommandExecutorServiceModule http transports} will be installed.
|
||||
*
|
||||
* @author Adrian Cole, Andrew Newdigate
|
||||
* @author Adrian Cole
|
||||
* @see AzureQueueContext
|
||||
*/
|
||||
public class AzureQueueContextFactory {
|
||||
|
||||
public static AzureQueueContext createAzureQueueContext(String account, String encodedKey,
|
||||
public static AzureQueueContext createContext(String account, String encodedKey,
|
||||
Module... modules) {
|
||||
return AzureQueueContextBuilder.newBuilder(account, encodedKey).withModules(modules)
|
||||
.buildContext();
|
||||
return new AzureQueueContextBuilder(account, encodedKey).withModules(modules).buildContext();
|
||||
}
|
||||
|
||||
public static AzureQueueContext createAzureQueueContext(URI endpoint, String account,
|
||||
String encodedKey, Module... modules) {
|
||||
return AzureQueueContextBuilder.newBuilder(account, encodedKey).withEndpoint(endpoint)
|
||||
.withModules(modules).buildContext();
|
||||
public static AzureQueueContext createContext(URI endpoint, String account, String encodedKey,
|
||||
Module... modules) {
|
||||
return new AzureQueueContextBuilder(account, encodedKey).withEndpoint(endpoint).withModules(
|
||||
modules).buildContext();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,22 +23,39 @@
|
|||
*/
|
||||
package org.jclouds.azure.storage.queue.config;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
|
||||
import org.jclouds.azure.storage.AzureQueue;
|
||||
import org.jclouds.azure.storage.queue.AzureQueueConnection;
|
||||
import org.jclouds.azure.storage.queue.AzureQueueContext;
|
||||
import org.jclouds.azure.storage.queue.internal.GuiceAzureQueueContext;
|
||||
import org.jclouds.azure.storage.reference.AzureStorageConstants;
|
||||
import org.jclouds.cloud.internal.CloudContextImpl;
|
||||
import org.jclouds.http.RequiresHttp;
|
||||
import org.jclouds.lifecycle.Closer;
|
||||
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Scopes;
|
||||
|
||||
/**
|
||||
* Configures the {@link AzureQueueContext}; requires {@link AzureQueueConnection} bound.
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@RequiresHttp
|
||||
public class AzureQueueContextModule extends AbstractModule {
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
this.requireBinding(AzureQueueConnection.class);
|
||||
bind(AzureQueueContext.class).to(GuiceAzureQueueContext.class);
|
||||
bind(AzureQueueContext.class).to(AzureQueueContextImpl.class).in(Scopes.SINGLETON);
|
||||
}
|
||||
}
|
||||
|
||||
public static class AzureQueueContextImpl extends CloudContextImpl<AzureQueueConnection>
|
||||
implements AzureQueueContext {
|
||||
@Inject
|
||||
public AzureQueueContextImpl(Closer closer, AzureQueueConnection defaultApi,
|
||||
@AzureQueue URI endPoint,
|
||||
@Named(AzureStorageConstants.PROPERTY_AZURESTORAGE_ACCOUNT) String account) {
|
||||
super(closer, defaultApi, endPoint, account);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -58,7 +58,7 @@ public class AzureQueueConnectionLiveTest {
|
|||
public void setupConnection() {
|
||||
account = System.getProperty("jclouds.test.user");
|
||||
String key = System.getProperty("jclouds.test.key");
|
||||
Injector injector = AzureQueueContextBuilder.newBuilder(account, key).withModules(
|
||||
Injector injector = new AzureQueueContextBuilder(account, key).withModules(
|
||||
new Log4JLoggingModule()).withSaxDebug().buildInjector();
|
||||
connection = injector.getInstance(AzureQueueConnection.class);
|
||||
}
|
||||
|
|
|
@ -28,9 +28,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
|||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
@ -40,6 +38,10 @@ import java.util.concurrent.Future;
|
|||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Provider;
|
||||
|
||||
import org.jclouds.blobstore.domain.Blob;
|
||||
import org.jclouds.blobstore.domain.BlobMetadata;
|
||||
import org.jclouds.blobstore.domain.ContainerMetadata;
|
||||
|
@ -48,10 +50,10 @@ import org.jclouds.rest.BoundedList;
|
|||
import org.jclouds.util.Utils;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import javax.inject.Inject;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.inject.assistedinject.Assisted;
|
||||
import javax.inject.Named;
|
||||
|
||||
/**
|
||||
* Implements core Map functionality with an {@link BlobStore}
|
||||
|
@ -67,6 +69,7 @@ public abstract class BaseBlobMap<C extends ContainerMetadata, M extends BlobMet
|
|||
|
||||
protected final BlobStore<C, M, B> connection;
|
||||
protected final String container;
|
||||
protected final Provider<B> blobFactory;
|
||||
|
||||
/**
|
||||
* maximum duration of an blob Request
|
||||
|
@ -83,9 +86,11 @@ public abstract class BaseBlobMap<C extends ContainerMetadata, M extends BlobMet
|
|||
protected long requestRetryMilliseconds = 10;
|
||||
|
||||
@Inject
|
||||
public BaseBlobMap(BlobStore<C, M, B> connection, @Assisted String containerName) {
|
||||
public BaseBlobMap(BlobStore<C, M, B> connection, Provider<B> blobFactory,
|
||||
@Assisted String containerName) {
|
||||
this.connection = checkNotNull(connection, "connection");
|
||||
this.container = checkNotNull(containerName, "container");
|
||||
this.blobFactory = checkNotNull(blobFactory, "blobFactory");
|
||||
checkArgument(!container.equals(""), "container name must not be a blank string!");
|
||||
}
|
||||
|
||||
|
@ -120,7 +125,8 @@ public abstract class BaseBlobMap<C extends ContainerMetadata, M extends BlobMet
|
|||
if (value instanceof Blob<?>) {
|
||||
object = (Blob<?>) value;
|
||||
} else {
|
||||
object = new Blob<BlobMetadata>("dummy", value);
|
||||
object = blobFactory.get();
|
||||
object.setData(value);
|
||||
}
|
||||
if (object.getMetadata().getContentMD5() == null)
|
||||
object.generateMD5();
|
||||
|
@ -133,7 +139,7 @@ public abstract class BaseBlobMap<C extends ContainerMetadata, M extends BlobMet
|
|||
* @see BlobStore#getBlob(String, String)
|
||||
*/
|
||||
protected Set<B> getAllObjects() {
|
||||
Set<B> objects = new HashSet<B>();
|
||||
Set<B> objects = Sets.newHashSet();
|
||||
Map<String, Future<B>> futureObjects = Maps.newHashMap();
|
||||
for (String key : keySet()) {
|
||||
futureObjects.put(key, connection.getBlob(container, key));
|
||||
|
@ -153,7 +159,7 @@ public abstract class BaseBlobMap<C extends ContainerMetadata, M extends BlobMet
|
|||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void ifNotFoundRetryOtherwiseAddToSet(String key, Future<B> value, Set<B> objects)
|
||||
public void ifNotFoundRetryOtherwiseAddToSet(String key, Future<B> value, Set<B> objects)
|
||||
throws InterruptedException, ExecutionException, TimeoutException {
|
||||
for (int i = 0; i < 3; i++) {
|
||||
try {
|
||||
|
@ -203,7 +209,7 @@ public abstract class BaseBlobMap<C extends ContainerMetadata, M extends BlobMet
|
|||
|
||||
public void clear() {
|
||||
try {
|
||||
List<Future<Boolean>> deletes = new ArrayList<Future<Boolean>>();
|
||||
List<Future<Boolean>> deletes = Lists.newArrayList();
|
||||
for (String key : keySet()) {
|
||||
deletes.add(connection.removeBlob(container, key));
|
||||
}
|
||||
|
@ -229,7 +235,7 @@ public abstract class BaseBlobMap<C extends ContainerMetadata, M extends BlobMet
|
|||
|
||||
public Set<String> keySet() {
|
||||
try {
|
||||
Set<String> keys = new HashSet<String>();
|
||||
Set<String> keys = Sets.newHashSet();
|
||||
for (BlobMetadata object : refreshContainer())
|
||||
keys.add(object.getKey());
|
||||
return keys;
|
||||
|
|
|
@ -33,6 +33,9 @@ import org.jclouds.blobstore.domain.BlobMetadata;
|
|||
* @author Adrian Cole
|
||||
*
|
||||
*/
|
||||
public interface BlobMap<M extends BlobMetadata, B extends Blob<M>> extends ListableMap<M, String, B> {
|
||||
|
||||
public interface BlobMap<M extends BlobMetadata, B extends Blob<M>> extends
|
||||
ListableMap<M, String, B> {
|
||||
public static interface Factory<M extends BlobMetadata, B extends Blob<M>> {
|
||||
BlobMap<M, B> create(String containerName);
|
||||
}
|
||||
}
|
|
@ -25,8 +25,11 @@ package org.jclouds.blobstore;
|
|||
|
||||
import org.jclouds.blobstore.domain.Blob;
|
||||
import org.jclouds.blobstore.domain.BlobMetadata;
|
||||
import org.jclouds.blobstore.domain.ContainerMetadata;
|
||||
import org.jclouds.cloud.CloudContext;
|
||||
|
||||
import com.google.inject.ImplementedBy;
|
||||
|
||||
/**
|
||||
* Represents a cloud that has key-value storage functionality.
|
||||
*
|
||||
|
@ -34,7 +37,8 @@ import org.jclouds.cloud.CloudContext;
|
|||
* @author Adrian Cole
|
||||
*
|
||||
*/
|
||||
public interface BlobStoreContext<S extends BlobStore<?, M, B>, M extends BlobMetadata, B extends Blob<M>>
|
||||
@ImplementedBy(BlobStoreContextImpl.class)
|
||||
public interface BlobStoreContext<S extends BlobStore<C, M, B>, C extends ContainerMetadata, M extends BlobMetadata, B extends Blob<M>>
|
||||
extends CloudContext<S> {
|
||||
|
||||
/**
|
||||
|
@ -51,4 +55,5 @@ public interface BlobStoreContext<S extends BlobStore<?, M, B>, M extends BlobMe
|
|||
*/
|
||||
BlobMap<M, B> createBlobMap(String container);
|
||||
|
||||
B newBlob(String key);
|
||||
}
|
|
@ -0,0 +1,156 @@
|
|||
/**
|
||||
*
|
||||
* 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.blobstore;
|
||||
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
|
||||
import org.jclouds.blobstore.domain.Blob;
|
||||
import org.jclouds.blobstore.domain.BlobMetadata;
|
||||
import org.jclouds.blobstore.domain.ContainerMetadata;
|
||||
import org.jclouds.cloud.CloudContextBuilder;
|
||||
|
||||
import com.google.inject.Key;
|
||||
import com.google.inject.Module;
|
||||
import com.google.inject.TypeLiteral;
|
||||
import com.google.inject.util.Types;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public abstract class BlobStoreContextBuilder<S extends BlobStore<C, M, B>, C extends ContainerMetadata, M extends BlobMetadata, B extends Blob<M>>
|
||||
extends CloudContextBuilder<S> {
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public BlobStoreContextBuilder<S, C, M, B> withExecutorService(ExecutorService service) {
|
||||
return (BlobStoreContextBuilder<S, C, M, B>) super.withExecutorService(service);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public BlobStoreContextBuilder<S, C, M, B> withHttpMaxRedirects(int httpMaxRedirects) {
|
||||
return (BlobStoreContextBuilder<S, C, M, B>) super.withHttpMaxRedirects(httpMaxRedirects);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public BlobStoreContextBuilder<S, C, M, B> withHttpMaxRetries(int httpMaxRetries) {
|
||||
return (BlobStoreContextBuilder<S, C, M, B>) super.withHttpMaxRetries(httpMaxRetries);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public BlobStoreContextBuilder<S, C, M, B> withJsonDebug() {
|
||||
return (BlobStoreContextBuilder<S, C, M, B>) super.withJsonDebug();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public BlobStoreContextBuilder<S, C, M, B> withModule(Module module) {
|
||||
return (BlobStoreContextBuilder<S, C, M, B>) super.withModule(module);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public BlobStoreContextBuilder<S, C, M, B> withModules(Module... modules) {
|
||||
return (BlobStoreContextBuilder<S, C, M, B>) super.withModules(modules);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public BlobStoreContextBuilder<S, C, M, B> withPoolIoWorkerThreads(int poolIoWorkerThreads) {
|
||||
return (BlobStoreContextBuilder<S, C, M, B>) super
|
||||
.withPoolIoWorkerThreads(poolIoWorkerThreads);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public BlobStoreContextBuilder<S, C, M, B> withPoolMaxConnectionReuse(int poolMaxConnectionReuse) {
|
||||
return (BlobStoreContextBuilder<S, C, M, B>) super
|
||||
.withPoolMaxConnectionReuse(poolMaxConnectionReuse);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public BlobStoreContextBuilder<S, C, M, B> withPoolMaxConnections(int poolMaxConnections) {
|
||||
return (BlobStoreContextBuilder<S, C, M, B>) super.withPoolMaxConnections(poolMaxConnections);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public BlobStoreContextBuilder<S, C, M, B> withPoolMaxSessionFailures(int poolMaxSessionFailures) {
|
||||
return (BlobStoreContextBuilder<S, C, M, B>) super
|
||||
.withPoolMaxSessionFailures(poolMaxSessionFailures);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public BlobStoreContextBuilder<S, C, M, B> withPoolRequestInvokerThreads(
|
||||
int poolRequestInvokerThreads) {
|
||||
return (BlobStoreContextBuilder<S, C, M, B>) super
|
||||
.withPoolRequestInvokerThreads(poolRequestInvokerThreads);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public BlobStoreContextBuilder<S, C, M, B> withSaxDebug() {
|
||||
return (BlobStoreContextBuilder<S, C, M, B>) super.withSaxDebug();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public BlobStoreContextBuilder<S, C, M, B> relaxSSLHostname() {
|
||||
return (BlobStoreContextBuilder<S, C, M, B>) super.relaxSSLHostname();
|
||||
}
|
||||
|
||||
protected final TypeLiteral<C> containerMetadataType;
|
||||
protected final TypeLiteral<M> blobMetadataType;
|
||||
protected final TypeLiteral<B> blobType;
|
||||
|
||||
public BlobStoreContextBuilder(TypeLiteral<S> connectionType,
|
||||
TypeLiteral<C> containerMetadataType, TypeLiteral<M> blobMetadataType,
|
||||
TypeLiteral<B> blobType) {
|
||||
this(connectionType, containerMetadataType, blobMetadataType, blobType, new Properties());
|
||||
}
|
||||
|
||||
public BlobStoreContextBuilder(TypeLiteral<S> connectionType,
|
||||
TypeLiteral<C> containerMetadataType, TypeLiteral<M> blobMetadataType,
|
||||
TypeLiteral<B> blobType, Properties properties) {
|
||||
super(connectionType, properties);
|
||||
this.containerMetadataType = containerMetadataType;
|
||||
this.blobMetadataType = blobMetadataType;
|
||||
this.blobType = blobType;
|
||||
modules.add(new BlobStoreMapsModule<S, C, M, B>(connectionType,
|
||||
containerMetadataType, blobMetadataType, blobType));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public BlobStoreContext<S, C, M, B> buildContext() {
|
||||
return (BlobStoreContext<S, C, M, B>) this.buildInjector().getInstance(
|
||||
Key.get(Types.newParameterizedType(BlobStoreContext.class, connectionType.getType(),
|
||||
containerMetadataType.getType(), blobMetadataType.getType(), blobType
|
||||
.getType())));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
/**
|
||||
*
|
||||
* 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.blobstore;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
import javax.inject.Provider;
|
||||
|
||||
import org.jclouds.blobstore.domain.Blob;
|
||||
import org.jclouds.blobstore.domain.BlobMetadata;
|
||||
import org.jclouds.blobstore.domain.ContainerMetadata;
|
||||
import org.jclouds.cloud.internal.CloudContextImpl;
|
||||
import org.jclouds.lifecycle.Closer;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class BlobStoreContextImpl<S extends BlobStore<C, M, B>, C extends ContainerMetadata, M extends BlobMetadata, B extends Blob<M>>
|
||||
extends CloudContextImpl<S> implements BlobStoreContext<S, C, M, B> {
|
||||
private final BlobMap.Factory<M, B> blobMapFactory;
|
||||
private final InputStreamMap.Factory<M> inputStreamMapFactory;
|
||||
private final Provider<B> blobProvider;
|
||||
|
||||
public BlobStoreContextImpl(BlobMap.Factory<M, B> blobMapFactory,
|
||||
InputStreamMap.Factory<M> inputStreamMapFactory, Closer closer,
|
||||
Provider<B> blobProvider, S defaultApi, URI endPoint, String account) {
|
||||
super(closer, defaultApi, endPoint, account);
|
||||
this.blobMapFactory = blobMapFactory;
|
||||
this.inputStreamMapFactory = inputStreamMapFactory;
|
||||
this.blobProvider = blobProvider;
|
||||
}
|
||||
|
||||
public BlobMap<M, B> createBlobMap(String container) {
|
||||
return blobMapFactory.create(container);
|
||||
}
|
||||
|
||||
public InputStreamMap<M> createInputStreamMap(String container) {
|
||||
return inputStreamMapFactory.create(container);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public B newBlob(String key) {
|
||||
Object object = blobProvider.get();
|
||||
B blob = (B) object;
|
||||
blob.getMetadata().setKey(key);
|
||||
return blob;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,80 @@
|
|||
/**
|
||||
*
|
||||
* 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.blobstore;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.jclouds.blobstore.domain.Blob;
|
||||
import org.jclouds.blobstore.domain.BlobMetadata;
|
||||
import org.jclouds.blobstore.domain.ContainerMetadata;
|
||||
import org.jclouds.blobstore.internal.BlobMapImpl;
|
||||
import org.jclouds.blobstore.internal.InputStreamMapImpl;
|
||||
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.TypeLiteral;
|
||||
import com.google.inject.assistedinject.FactoryProvider;
|
||||
import com.google.inject.util.Types;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class BlobStoreMapsModule<S extends BlobStore<C, M, B>, C extends ContainerMetadata, M extends BlobMetadata, B extends Blob<M>>
|
||||
extends AbstractModule {
|
||||
|
||||
// code is unchecked here as we are getting types at runtime. Due to type erasure, we cannot pass
|
||||
// generic types into provider methods. This is why we are sending in TypeLiterals.
|
||||
@SuppressWarnings("unchecked")
|
||||
private final TypeLiteral blobMapFactoryType;
|
||||
@SuppressWarnings("unchecked")
|
||||
private final TypeLiteral blobMapImplType;
|
||||
@SuppressWarnings("unchecked")
|
||||
private final TypeLiteral inputStreamMapFactoryType;
|
||||
@SuppressWarnings("unchecked")
|
||||
private final TypeLiteral inputStreamMapImplType;
|
||||
|
||||
@Inject
|
||||
public BlobStoreMapsModule(TypeLiteral<S> connectionType, TypeLiteral<C> containerMetadataType,
|
||||
TypeLiteral<M> blobMetadataType, TypeLiteral<B> blobType) {
|
||||
blobMapFactoryType = TypeLiteral.get(Types.newParameterizedTypeWithOwner(BlobMap.class,
|
||||
BlobMap.Factory.class, blobMetadataType.getType(), blobType.getType()));
|
||||
blobMapImplType = TypeLiteral.get(Types.newParameterizedType(BlobMapImpl.class,
|
||||
connectionType.getType(), containerMetadataType.getType(), blobMetadataType
|
||||
.getType(), blobType.getType()));
|
||||
inputStreamMapFactoryType = TypeLiteral.get(Types.newParameterizedTypeWithOwner(
|
||||
InputStreamMap.class, InputStreamMap.Factory.class, blobMetadataType.getType()));
|
||||
inputStreamMapImplType = TypeLiteral.get(Types.newParameterizedType(InputStreamMapImpl.class,
|
||||
connectionType.getType(), containerMetadataType.getType(), blobMetadataType
|
||||
.getType(), blobType.getType()));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
protected void configure() {
|
||||
bind(blobMapFactoryType).toProvider(
|
||||
FactoryProvider.newFactory(blobMapFactoryType, blobMapImplType));
|
||||
bind(inputStreamMapFactoryType).toProvider(
|
||||
FactoryProvider.newFactory(inputStreamMapFactoryType, inputStreamMapImplType));
|
||||
}
|
||||
|
||||
}
|
|
@ -41,7 +41,11 @@ import org.jclouds.blobstore.domain.BlobMetadata;
|
|||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public interface InputStreamMap<B extends BlobMetadata> extends ListableMap<B, String, InputStream> {
|
||||
public interface InputStreamMap<M extends BlobMetadata> extends ListableMap<M, String, InputStream> {
|
||||
public static interface Factory<M extends BlobMetadata> {
|
||||
InputStreamMap<M> create(String containerName);
|
||||
}
|
||||
|
||||
InputStream putString(String key, String value);
|
||||
|
||||
InputStream putFile(String key, File value);
|
||||
|
|
|
@ -30,12 +30,11 @@ import java.awt.Container;
|
|||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.jclouds.http.HttpUtils;
|
||||
import org.jclouds.http.HttpUtils.MD5InputStreamResult;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import com.google.inject.assistedinject.Assisted;
|
||||
|
||||
/**
|
||||
* Value type for an HTTP Blob service. Blobs are stored in {@link Container containers} and consist
|
||||
* of a {@link org.jclouds.blobstore.domain.Value#getData() value}, a {@link Blob#getKey key and
|
||||
|
@ -68,10 +67,10 @@ public class Blob<M extends BlobMetadata> {
|
|||
return false;
|
||||
} else if (!data.equals(other.data))
|
||||
return false;
|
||||
if (metadata == null) {
|
||||
if (other.metadata != null)
|
||||
if (getMetadata() == null) {
|
||||
if (other.getMetadata() != null)
|
||||
return false;
|
||||
} else if (!metadata.equals(other.metadata))
|
||||
} else if (!getMetadata().equals(other.getMetadata()))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
@ -79,11 +78,11 @@ public class Blob<M extends BlobMetadata> {
|
|||
@Override
|
||||
public String toString() {
|
||||
return "Blob [contentLength=" + contentLength + ", contentRange=" + contentRange + ", data="
|
||||
+ data + ", metadata=" + metadata + "]";
|
||||
+ data + ", metadata=" + getMetadata() + "]";
|
||||
}
|
||||
|
||||
protected Object data;
|
||||
protected final M metadata;
|
||||
private M metadata;
|
||||
protected long contentLength = -1;
|
||||
protected String contentRange;
|
||||
|
||||
|
@ -93,9 +92,14 @@ public class Blob<M extends BlobMetadata> {
|
|||
this((M) new BlobMetadata(key));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Inject
|
||||
public Blob(@Assisted M metadata) {
|
||||
this.metadata = metadata;
|
||||
public Blob() {
|
||||
this((M) new BlobMetadata());
|
||||
}
|
||||
|
||||
public Blob(M metadata) {
|
||||
this.setMetadata(metadata);
|
||||
}
|
||||
|
||||
public Blob(M metadata, Object data) {
|
||||
|
@ -112,7 +116,7 @@ public class Blob<M extends BlobMetadata> {
|
|||
* @see BlobMetadata#getKey()
|
||||
*/
|
||||
public String getKey() {
|
||||
return metadata.getKey();
|
||||
return getMetadata().getKey();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -172,7 +176,7 @@ public class Blob<M extends BlobMetadata> {
|
|||
result = prime * result + (int) (contentLength ^ (contentLength >>> 32));
|
||||
result = prime * result + ((contentRange == null) ? 0 : contentRange.hashCode());
|
||||
result = prime * result + ((data == null) ? 0 : data.hashCode());
|
||||
result = prime * result + ((metadata == null) ? 0 : metadata.hashCode());
|
||||
result = prime * result + ((getMetadata() == null) ? 0 : getMetadata().hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -209,4 +213,8 @@ public class Blob<M extends BlobMetadata> {
|
|||
return contentRange;
|
||||
}
|
||||
|
||||
public void setMetadata(M metadata) {
|
||||
this.metadata = metadata;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
|||
import java.io.Serializable;
|
||||
import java.util.Arrays;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
|
||||
import org.joda.time.DateTime;
|
||||
|
@ -114,6 +115,7 @@ public class BlobMetadata implements Comparable<BlobMetadata>, Serializable {
|
|||
return true;
|
||||
}
|
||||
|
||||
@Inject
|
||||
public BlobMetadata() {
|
||||
super();
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
package org.jclouds.blobstore.functions;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Provider;
|
||||
import javax.ws.rs.core.HttpHeaders;
|
||||
|
||||
import org.jclouds.blobstore.domain.Blob;
|
||||
|
@ -45,15 +46,11 @@ import com.google.common.base.Function;
|
|||
public class ParseBlobFromHeadersAndHttpContent<M extends BlobMetadata, B extends Blob<M>>
|
||||
implements Function<HttpResponse, B>, RestContext {
|
||||
private final ParseContentTypeFromHeaders<M> metadataParser;
|
||||
private final BlobFactory<M, B> blobFactory;
|
||||
|
||||
public static interface BlobFactory<M extends BlobMetadata, B extends Blob<M>> {
|
||||
B create(M metadata);
|
||||
}
|
||||
private final Provider<B> blobFactory;
|
||||
|
||||
@Inject
|
||||
public ParseBlobFromHeadersAndHttpContent(ParseContentTypeFromHeaders<M> metadataParser,
|
||||
BlobFactory<M, B> blobFactory) {
|
||||
Provider<B> blobFactory) {
|
||||
this.metadataParser = metadataParser;
|
||||
this.blobFactory = blobFactory;
|
||||
}
|
||||
|
@ -68,9 +65,10 @@ public class ParseBlobFromHeadersAndHttpContent<M extends BlobMetadata, B extend
|
|||
*/
|
||||
public B apply(HttpResponse from) {
|
||||
M metadata = metadataParser.apply(from);
|
||||
B object = blobFactory.create(metadata);
|
||||
assert object.getMetadata() == metadata;
|
||||
B object = blobFactory.get();
|
||||
object.setMetadata(metadata);
|
||||
object.setData(from.getContent());
|
||||
assert object.getMetadata() == metadata;
|
||||
attemptToParseSizeAndRangeFromHeaders(from, object);
|
||||
return object;
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
package org.jclouds.blobstore.functions;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Provider;
|
||||
import javax.ws.rs.core.HttpHeaders;
|
||||
|
||||
import org.jclouds.blobstore.domain.BlobMetadata;
|
||||
|
@ -40,22 +41,19 @@ import com.google.common.base.Function;
|
|||
*/
|
||||
public class ParseContentTypeFromHeaders<M extends BlobMetadata> implements
|
||||
Function<HttpResponse, M>, RestContext {
|
||||
private final BlobMetadataFactory<M> metadataFactory;
|
||||
private final Provider<M> metadataFactory;
|
||||
private HttpRequest request;
|
||||
private Object[] args;
|
||||
|
||||
public static interface BlobMetadataFactory<M extends BlobMetadata> {
|
||||
M create(String key);
|
||||
}
|
||||
|
||||
@Inject
|
||||
public ParseContentTypeFromHeaders(BlobMetadataFactory<M> metadataFactory) {
|
||||
public ParseContentTypeFromHeaders(Provider<M> metadataFactory) {
|
||||
this.metadataFactory = metadataFactory;
|
||||
}
|
||||
|
||||
public M apply(HttpResponse from) {
|
||||
String objectKey = getKeyFor(from);
|
||||
M to = metadataFactory.create(objectKey);
|
||||
M to = metadataFactory.get();
|
||||
to.setKey(objectKey);
|
||||
addAllHeadersTo(from, to);
|
||||
setContentTypeOrThrowException(from, to);
|
||||
return to;
|
||||
|
|
|
@ -29,6 +29,7 @@ import java.util.Map.Entry;
|
|||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Provider;
|
||||
import javax.ws.rs.core.HttpHeaders;
|
||||
|
||||
import org.jclouds.blobstore.domain.BlobMetadata;
|
||||
|
@ -50,7 +51,7 @@ public class ParseSystemAndUserMetadataFromHeaders<M extends BlobMetadata> exten
|
|||
@Inject
|
||||
public ParseSystemAndUserMetadataFromHeaders(DateService dateParser,
|
||||
@Named(PROPERTY_USER_METADATA_PREFIX) String metadataPrefix,
|
||||
BlobMetadataFactory<M> metadataFactory) {
|
||||
Provider<M> metadataFactory) {
|
||||
super(metadataFactory);
|
||||
this.dateParser = dateParser;
|
||||
this.metadataPrefix = metadataPrefix;
|
||||
|
|
|
@ -1,20 +0,0 @@
|
|||
package org.jclouds.blobstore.functions;
|
||||
|
||||
import org.jclouds.blobstore.KeyNotFoundException;
|
||||
import org.jclouds.http.functions.ReturnTrueOn404;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
|
||||
public class ReturnTrueOnKeyNotFoundOr404 implements Function<Exception, Boolean> {
|
||||
ReturnTrueOn404 rto404 = new ReturnTrueOn404();
|
||||
|
||||
public Boolean apply(Exception from) {
|
||||
if (from instanceof KeyNotFoundException) {
|
||||
return true;
|
||||
} else {
|
||||
return rto404.apply(from);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -21,8 +21,24 @@
|
|||
* under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
/**
|
||||
* This package contains implementation classes for the jclouds-s3 public api
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
package org.jclouds.aws.s3.internal;
|
||||
package org.jclouds.blobstore.functions;
|
||||
|
||||
import org.jclouds.blobstore.ContainerNotFoundException;
|
||||
import org.jclouds.blobstore.KeyNotFoundException;
|
||||
import org.jclouds.http.functions.ReturnTrueOn404;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
|
||||
public class ReturnTrueOnNotFoundOr404 implements Function<Exception, Boolean> {
|
||||
ReturnTrueOn404 rto404 = new ReturnTrueOn404();
|
||||
|
||||
public Boolean apply(Exception from) {
|
||||
if (from instanceof KeyNotFoundException||from instanceof ContainerNotFoundException) {
|
||||
return true;
|
||||
} else {
|
||||
return rto404.apply(from);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -21,7 +21,7 @@
|
|||
* under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
package org.jclouds.blobstore;
|
||||
package org.jclouds.blobstore.internal;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
|
@ -32,12 +32,18 @@ import java.util.Set;
|
|||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Provider;
|
||||
|
||||
import org.jclouds.blobstore.BaseBlobMap;
|
||||
import org.jclouds.blobstore.BlobMap;
|
||||
import org.jclouds.blobstore.BlobStore;
|
||||
import org.jclouds.blobstore.KeyNotFoundException;
|
||||
import org.jclouds.blobstore.domain.Blob;
|
||||
import org.jclouds.blobstore.domain.BlobMetadata;
|
||||
import org.jclouds.blobstore.domain.ContainerMetadata;
|
||||
import org.jclouds.util.Utils;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import com.google.inject.assistedinject.Assisted;
|
||||
|
||||
/**
|
||||
|
@ -48,12 +54,13 @@ import com.google.inject.assistedinject.Assisted;
|
|||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class LiveBlobMap<C extends ContainerMetadata, M extends BlobMetadata, B extends Blob<M>>
|
||||
public class BlobMapImpl<S extends BlobStore<C, M, B>, C extends ContainerMetadata, M extends BlobMetadata, B extends Blob<M>>
|
||||
extends BaseBlobMap<C, M, B, B> implements BlobMap<M, B> {
|
||||
|
||||
@Inject
|
||||
public LiveBlobMap(BlobStore<C, M, B> connection, @Assisted String containerName) {
|
||||
super(connection, containerName);
|
||||
public BlobMapImpl(S connection, Provider<B> blobFactory,
|
||||
@Assisted String containerName) {
|
||||
super(connection, blobFactory, containerName);
|
||||
}
|
||||
|
||||
/**
|
|
@ -21,7 +21,7 @@
|
|||
* under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
package org.jclouds.blobstore;
|
||||
package org.jclouds.blobstore.internal;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
|
@ -35,13 +35,19 @@ import java.util.Set;
|
|||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Provider;
|
||||
|
||||
import org.jclouds.blobstore.BaseBlobMap;
|
||||
import org.jclouds.blobstore.BlobStore;
|
||||
import org.jclouds.blobstore.InputStreamMap;
|
||||
import org.jclouds.blobstore.KeyNotFoundException;
|
||||
import org.jclouds.blobstore.domain.Blob;
|
||||
import org.jclouds.blobstore.domain.BlobMetadata;
|
||||
import org.jclouds.blobstore.domain.ContainerMetadata;
|
||||
import org.jclouds.util.Utils;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import javax.inject.Inject;
|
||||
import com.google.inject.assistedinject.Assisted;
|
||||
|
||||
/**
|
||||
|
@ -53,12 +59,13 @@ import com.google.inject.assistedinject.Assisted;
|
|||
* @see InputStreamMap
|
||||
* @see BaseBlobMap
|
||||
*/
|
||||
public abstract class LiveInputStreamMap<C extends ContainerMetadata, M extends BlobMetadata, B extends Blob<M>>
|
||||
public class InputStreamMapImpl<S extends BlobStore<C, M, B>, C extends ContainerMetadata, M extends BlobMetadata, B extends Blob<M>>
|
||||
extends BaseBlobMap<C, M, B, InputStream> implements InputStreamMap<M> {
|
||||
|
||||
@Inject
|
||||
public LiveInputStreamMap(BlobStore<C, M, B> connection, @Assisted String container) {
|
||||
super(connection, container);
|
||||
public InputStreamMapImpl(S connection, Provider<B> blobFactory,
|
||||
@Assisted String container) {
|
||||
super(connection, blobFactory, container);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -155,7 +162,7 @@ public abstract class LiveInputStreamMap<C extends ContainerMetadata, M extends
|
|||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @see LiveInputStreamMap#put(String, InputStream)
|
||||
* @see InputStreamMapImpl#put(String, InputStream)
|
||||
*/
|
||||
public InputStream setValue(InputStream value) {
|
||||
return put(key, value);
|
||||
|
@ -210,7 +217,8 @@ public abstract class LiveInputStreamMap<C extends ContainerMetadata, M extends
|
|||
try {
|
||||
List<Future<byte[]>> puts = new ArrayList<Future<byte[]>>();
|
||||
for (Map.Entry<? extends String, ? extends Object> entry : map.entrySet()) {
|
||||
B object = createBlob(entry.getKey());
|
||||
B object = blobFactory.get();
|
||||
object.getMetadata().setKey(entry.getKey());
|
||||
object.setData(entry.getValue());
|
||||
object.generateMD5();
|
||||
puts.add(connection.putBlob(container, object));
|
||||
|
@ -271,7 +279,8 @@ public abstract class LiveInputStreamMap<C extends ContainerMetadata, M extends
|
|||
*/
|
||||
@VisibleForTesting
|
||||
InputStream putInternal(String s, Object o) {
|
||||
B object = createBlob(s);
|
||||
B object = blobFactory.get();
|
||||
object.getMetadata().setKey(s);
|
||||
try {
|
||||
InputStream returnVal = containsKey(s) ? get(s) : null;
|
||||
object.setData(o);
|
||||
|
@ -286,6 +295,4 @@ public abstract class LiveInputStreamMap<C extends ContainerMetadata, M extends
|
|||
}
|
||||
}
|
||||
|
||||
protected abstract B createBlob(String s);
|
||||
|
||||
}
|
|
@ -27,8 +27,8 @@ import static org.easymock.EasyMock.expect;
|
|||
import static org.easymock.classextension.EasyMock.createMock;
|
||||
import static org.easymock.classextension.EasyMock.createNiceMock;
|
||||
import static org.easymock.classextension.EasyMock.replay;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
@ -40,8 +40,14 @@ import java.util.concurrent.TimeoutException;
|
|||
import org.jclouds.blobstore.domain.Blob;
|
||||
import org.jclouds.blobstore.domain.BlobMetadata;
|
||||
import org.jclouds.blobstore.domain.ContainerMetadata;
|
||||
import org.jclouds.blobstore.integration.StubBlobStoreContextBuilder;
|
||||
import org.jclouds.blobstore.internal.InputStreamMapImpl;
|
||||
import org.testng.annotations.BeforeClass;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.inject.TypeLiteral;
|
||||
import com.google.inject.util.Types;
|
||||
|
||||
/**
|
||||
*
|
||||
* Tests retry logic.
|
||||
|
@ -49,53 +55,67 @@ import org.testng.annotations.Test;
|
|||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = { "unit" }, testName = "blobstore.BaseBlobMapTest")
|
||||
public abstract class BaseBlobMapTest<C extends ContainerMetadata, M extends BlobMetadata, B extends Blob<M>, V> {
|
||||
public class BaseBlobMapTest {
|
||||
|
||||
class MockBaseBlobMap extends BaseBlobMap<C, M, B, String> {
|
||||
BlobStoreContext<BlobStore<ContainerMetadata, BlobMetadata, Blob<BlobMetadata>>, ContainerMetadata, BlobMetadata, Blob<BlobMetadata>> context;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public MockBaseBlobMap(String container) {
|
||||
super(createNiceMock(BlobStore.class), container);
|
||||
}
|
||||
InputStreamMapImpl<BlobStore<ContainerMetadata, BlobMetadata, Blob<BlobMetadata>>, ContainerMetadata, BlobMetadata, Blob<BlobMetadata>> map;
|
||||
|
||||
public Set<java.util.Map.Entry<String, String>> entrySet() {
|
||||
return null;
|
||||
}
|
||||
@SuppressWarnings("unchecked")
|
||||
@BeforeClass
|
||||
void addDefaultObjectsSoThatTestsWillPass() {
|
||||
context = new StubBlobStoreContextBuilder().buildContext();
|
||||
map = (InputStreamMapImpl<BlobStore<ContainerMetadata, BlobMetadata, Blob<BlobMetadata>>, ContainerMetadata, BlobMetadata, Blob<BlobMetadata>>) context
|
||||
.createInputStreamMap("test");
|
||||
}
|
||||
|
||||
public String get(Object key) {
|
||||
return null;
|
||||
}
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testTypes() {
|
||||
TypeLiteral type0 = new TypeLiteral<Map<String, Map<String, Blob<BlobMetadata>>>>() {
|
||||
};
|
||||
TypeLiteral type1 = TypeLiteral.get(Types.newParameterizedType(Map.class, String.class, Types
|
||||
.newParameterizedType(Map.class, String.class, Types.newParameterizedType(
|
||||
Blob.class, BlobMetadata.class))));
|
||||
assertEquals(type0, type1);
|
||||
|
||||
public String put(String key, String value) {
|
||||
return null;
|
||||
}
|
||||
TypeLiteral type2 = new TypeLiteral<BlobMap.Factory<BlobMetadata, Blob<BlobMetadata>>>() {
|
||||
};
|
||||
TypeLiteral type3 = TypeLiteral.get(Types.newParameterizedTypeWithOwner(BlobMap.class,
|
||||
BlobMap.Factory.class, BlobMetadata.class, Types.newParameterizedType(Blob.class,
|
||||
BlobMetadata.class)));
|
||||
|
||||
public void putAll(Map<? extends String, ? extends String> t) {
|
||||
assertEquals(type2, type3);
|
||||
|
||||
}
|
||||
TypeLiteral type4 = new TypeLiteral<Blob<BlobMetadata>>() {
|
||||
};
|
||||
TypeLiteral type5 = TypeLiteral.get(Types
|
||||
.newParameterizedType(Blob.class, BlobMetadata.class));
|
||||
|
||||
public String remove(Object key) {
|
||||
return null;
|
||||
}
|
||||
assertEquals(type4, type5);
|
||||
|
||||
public Collection<String> values() {
|
||||
return null;
|
||||
}
|
||||
TypeLiteral type6 = new TypeLiteral<BlobStoreContextImpl<BlobStore<ContainerMetadata, BlobMetadata, Blob<BlobMetadata>>, ContainerMetadata, BlobMetadata, Blob<BlobMetadata>>>() {
|
||||
};
|
||||
|
||||
TypeLiteral type7 = TypeLiteral.get(Types.newParameterizedType(BlobStoreContextImpl.class,
|
||||
Types.newParameterizedType(BlobStore.class, ContainerMetadata.class,
|
||||
BlobMetadata.class, Types.newParameterizedType(Blob.class,
|
||||
BlobMetadata.class)), ContainerMetadata.class, BlobMetadata.class,
|
||||
Types.newParameterizedType(Blob.class, BlobMetadata.class)));
|
||||
assertEquals(type6, type7);
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testIfNotFoundRetryOtherwiseAddToSet() throws InterruptedException,
|
||||
ExecutionException, TimeoutException {
|
||||
BaseBlobMap<C, M, B, String> map = new MockBaseBlobMap("test");
|
||||
Future<B> futureObject = createMock(Future.class);
|
||||
B object = createBlob();
|
||||
Future<Blob<BlobMetadata>> futureObject = createMock(Future.class);
|
||||
Blob<BlobMetadata> object = context.newBlob("key");
|
||||
expect(futureObject.get(map.requestTimeoutMilliseconds, TimeUnit.MILLISECONDS)).andThrow(
|
||||
new KeyNotFoundException());
|
||||
expect(futureObject.get(map.requestTimeoutMilliseconds, TimeUnit.MILLISECONDS)).andReturn(
|
||||
object);
|
||||
replay(futureObject);
|
||||
Set<B> objects = new HashSet<B>();
|
||||
Set<Blob<BlobMetadata>> objects = new HashSet<Blob<BlobMetadata>>();
|
||||
long time = System.currentTimeMillis();
|
||||
map.ifNotFoundRetryOtherwiseAddToSet("key", futureObject, objects);
|
||||
// should have retried once
|
||||
|
@ -104,18 +124,15 @@ public abstract class BaseBlobMapTest<C extends ContainerMetadata, M extends Blo
|
|||
assert !objects.contains(null);
|
||||
}
|
||||
|
||||
protected abstract B createBlob();
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testIfNotFoundRetryOtherwiseAddToSetButNeverGetsIt() throws InterruptedException,
|
||||
ExecutionException, TimeoutException {
|
||||
BaseBlobMap<C, M, B, String> map = new MockBaseBlobMap("test");
|
||||
Future<B> futureObject = createMock(Future.class);
|
||||
Future<Blob<BlobMetadata>> futureObject = createMock(Future.class);
|
||||
Blob object = createNiceMock(Blob.class);
|
||||
expect(futureObject.get(map.requestTimeoutMilliseconds, TimeUnit.MILLISECONDS)).andThrow(
|
||||
new KeyNotFoundException()).atLeastOnce();
|
||||
replay(futureObject);
|
||||
Set<B> objects = new HashSet<B>();
|
||||
Set<Blob<BlobMetadata>> objects = new HashSet<Blob<BlobMetadata>>();
|
||||
long time = System.currentTimeMillis();
|
||||
map.ifNotFoundRetryOtherwiseAddToSet("key", futureObject, objects);
|
||||
// should have retried thrice
|
||||
|
@ -125,8 +142,4 @@ public abstract class BaseBlobMapTest<C extends ContainerMetadata, M extends Blo
|
|||
assert !objects.contains(null);
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = IllegalArgumentException.class)
|
||||
public void testBlankContainerName() {
|
||||
new MockBaseBlobMap("test");
|
||||
}
|
||||
}
|
|
@ -28,6 +28,9 @@ import static org.easymock.classextension.EasyMock.createMock;
|
|||
import static org.easymock.classextension.EasyMock.replay;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
import javax.inject.Provider;
|
||||
import javax.ws.rs.core.HttpHeaders;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
|
@ -48,9 +51,8 @@ public class ParseBlobFromHeadersAndHttpContentTest {
|
|||
@Test(expectedExceptions = NullPointerException.class)
|
||||
public void testCall() throws HttpException {
|
||||
ParseSystemAndUserMetadataFromHeaders<BlobMetadata> metadataParser = createMock(ParseSystemAndUserMetadataFromHeaders.class);
|
||||
ParseBlobFromHeadersAndHttpContent.BlobFactory<BlobMetadata, Blob<BlobMetadata>> objectFactory = createMock(ParseBlobFromHeadersAndHttpContent.BlobFactory.class);
|
||||
ParseBlobFromHeadersAndHttpContent<BlobMetadata, Blob<BlobMetadata>> callable = new ParseBlobFromHeadersAndHttpContent(
|
||||
metadataParser, objectFactory);
|
||||
metadataParser, blobProvider);
|
||||
HttpResponse response = createMock(HttpResponse.class);
|
||||
expect(response.getFirstHeaderOrNull("Content-Length")).andReturn("100");
|
||||
expect(response.getFirstHeaderOrNull("Content-Range")).andReturn(null);
|
||||
|
@ -60,22 +62,26 @@ public class ParseBlobFromHeadersAndHttpContentTest {
|
|||
callable.apply(response);
|
||||
}
|
||||
|
||||
private Provider<Blob<BlobMetadata>> blobProvider = new Provider<Blob<BlobMetadata>>() {
|
||||
|
||||
public Blob<BlobMetadata> get() {
|
||||
return new Blob<BlobMetadata>("key");
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test
|
||||
@Test(enabled = false)
|
||||
// TODO.. very complicated test.
|
||||
public void testParseContentLengthWhenContentRangeSet() throws HttpException {
|
||||
ParseSystemAndUserMetadataFromHeaders<BlobMetadata> metadataParser = createMock(ParseSystemAndUserMetadataFromHeaders.class);
|
||||
ParseBlobFromHeadersAndHttpContent.BlobFactory<BlobMetadata, Blob<BlobMetadata>> objectFactory = new ParseBlobFromHeadersAndHttpContent.BlobFactory<BlobMetadata, Blob<BlobMetadata>>() {
|
||||
|
||||
public Blob<BlobMetadata> create(BlobMetadata metadata) {
|
||||
return new Blob<BlobMetadata>(metadata);
|
||||
}
|
||||
|
||||
};
|
||||
ParseBlobFromHeadersAndHttpContent<BlobMetadata, Blob<BlobMetadata>> callable = new ParseBlobFromHeadersAndHttpContent(
|
||||
metadataParser, objectFactory);
|
||||
metadataParser, blobProvider);
|
||||
HttpResponse response = createMock(HttpResponse.class);
|
||||
BlobMetadata meta = createMock(BlobMetadata.class);
|
||||
expect(metadataParser.apply(response)).andReturn(meta);
|
||||
InputStream test = IOUtils.toInputStream("test");
|
||||
|
||||
expect(meta.getSize()).andReturn(-1l);
|
||||
meta.setSize(-1l);
|
||||
expect(response.getFirstHeaderOrNull(HttpHeaders.CONTENT_LENGTH)).andReturn("10485760")
|
||||
|
@ -86,13 +92,13 @@ public class ParseBlobFromHeadersAndHttpContentTest {
|
|||
ImmutableMultimap.of("Content-Length", "10485760", "Content-Range",
|
||||
"0-10485759/20232760"));
|
||||
meta.setSize(20232760l);
|
||||
expect(meta.getSize()).andReturn(20232760l);
|
||||
|
||||
expect(response.getStatusCode()).andReturn(200).atLeastOnce();
|
||||
expect(response.getContent()).andReturn(IOUtils.toInputStream("test"));
|
||||
expect(response.getContent()).andReturn(test);
|
||||
expect(meta.getSize()).andReturn(20232760l);
|
||||
|
||||
replay(response);
|
||||
replay(metadataParser);
|
||||
replay(meta);
|
||||
|
||||
Blob<BlobMetadata> object = callable.apply(response);
|
||||
assertEquals(object.getContentLength(), 10485760);
|
||||
|
|
|
@ -28,11 +28,11 @@ import static org.testng.Assert.assertEquals;
|
|||
import java.net.URI;
|
||||
import java.util.Collections;
|
||||
|
||||
import javax.inject.Provider;
|
||||
import javax.ws.rs.core.HttpHeaders;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
|
||||
import org.jclouds.blobstore.domain.BlobMetadata;
|
||||
import org.jclouds.blobstore.functions.ParseContentTypeFromHeaders.BlobMetadataFactory;
|
||||
import org.jclouds.http.HttpException;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
|
@ -47,15 +47,19 @@ import com.google.common.collect.Multimap;
|
|||
public class ParseBlobMetadataFromHeadersTest {
|
||||
|
||||
private ParseSystemAndUserMetadataFromHeaders<BlobMetadata> parser;
|
||||
private Provider<BlobMetadata> blobMetadataProvider = new Provider<BlobMetadata>() {
|
||||
|
||||
public BlobMetadata get() {
|
||||
return new BlobMetadata("key");
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
@BeforeTest
|
||||
void setUp() {
|
||||
|
||||
parser = new ParseSystemAndUserMetadataFromHeaders<BlobMetadata>(new DateService(), "prefix",
|
||||
new BlobMetadataFactory<BlobMetadata>() {
|
||||
public BlobMetadata create(String key) {
|
||||
return new BlobMetadata(key);
|
||||
}
|
||||
});
|
||||
blobMetadataProvider);
|
||||
parser
|
||||
.setContext(new HttpRequest("GET", URI.create("http://localhost/key")),
|
||||
new Object[] {});
|
||||
|
|
|
@ -0,0 +1,100 @@
|
|||
/**
|
||||
*
|
||||
* 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.blobstore.integration;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.List;
|
||||
|
||||
import javax.inject.Provider;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.blobstore.BlobMap;
|
||||
import org.jclouds.blobstore.BlobStore;
|
||||
import org.jclouds.blobstore.BlobStoreContext;
|
||||
import org.jclouds.blobstore.BlobStoreContextBuilder;
|
||||
import org.jclouds.blobstore.BlobStoreContextImpl;
|
||||
import org.jclouds.blobstore.InputStreamMap;
|
||||
import org.jclouds.blobstore.domain.Blob;
|
||||
import org.jclouds.blobstore.domain.BlobMetadata;
|
||||
import org.jclouds.blobstore.domain.ContainerMetadata;
|
||||
import org.jclouds.blobstore.integration.config.StubBlobStoreConnectionModule;
|
||||
import org.jclouds.cloud.CloudContextBuilder;
|
||||
import org.jclouds.lifecycle.Closer;
|
||||
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Module;
|
||||
import com.google.inject.Provides;
|
||||
import com.google.inject.TypeLiteral;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class StubBlobStoreContextBuilder
|
||||
extends
|
||||
BlobStoreContextBuilder<BlobStore<ContainerMetadata, BlobMetadata, Blob<BlobMetadata>>, ContainerMetadata, BlobMetadata, Blob<BlobMetadata>> {
|
||||
|
||||
public StubBlobStoreContextBuilder() {
|
||||
super(new TypeLiteral<BlobStore<ContainerMetadata, BlobMetadata, Blob<BlobMetadata>>>() {
|
||||
}, new TypeLiteral<ContainerMetadata>() {
|
||||
}, new TypeLiteral<BlobMetadata>() {
|
||||
}, new TypeLiteral<Blob<BlobMetadata>>() {
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addContextModule(List<Module> modules) {
|
||||
modules.add(new AbstractModule() {
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@Provides
|
||||
@Singleton
|
||||
BlobStoreContext<BlobStore<ContainerMetadata, BlobMetadata, Blob<BlobMetadata>>, ContainerMetadata, BlobMetadata, Blob<BlobMetadata>> provideContext(
|
||||
BlobMap.Factory<BlobMetadata, Blob<BlobMetadata>> blobMapFactory,
|
||||
InputStreamMap.Factory<BlobMetadata> inputStreamMapFactory, Closer closer,
|
||||
Provider<Blob<BlobMetadata>> blobProvider,
|
||||
BlobStore<ContainerMetadata, BlobMetadata, Blob<BlobMetadata>> api) {
|
||||
return new BlobStoreContextImpl<BlobStore<ContainerMetadata, BlobMetadata, Blob<BlobMetadata>>, ContainerMetadata, BlobMetadata, Blob<BlobMetadata>>(
|
||||
blobMapFactory, inputStreamMapFactory, closer, blobProvider, api, URI
|
||||
.create("http://localhost/blobstub"), "foo");
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public CloudContextBuilder<BlobStore<ContainerMetadata, BlobMetadata, Blob<BlobMetadata>>> withEndpoint(
|
||||
URI endpoint) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addConnectionModule(List<Module> modules) {
|
||||
modules.add(new StubBlobStoreConnectionModule());
|
||||
}
|
||||
|
||||
}
|
|
@ -23,277 +23,32 @@
|
|||
*/
|
||||
package org.jclouds.blobstore.integration;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
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;
|
||||
import org.jclouds.blobstore.BlobStoreContext;
|
||||
import org.jclouds.blobstore.InputStreamMap;
|
||||
import org.jclouds.blobstore.LiveBlobMap;
|
||||
import org.jclouds.blobstore.LiveInputStreamMap;
|
||||
import org.jclouds.blobstore.domain.Blob;
|
||||
import org.jclouds.blobstore.domain.BlobMetadata;
|
||||
import org.jclouds.blobstore.domain.ContainerMetadata;
|
||||
import org.jclouds.blobstore.integration.internal.BaseBlobStoreIntegrationTest;
|
||||
import org.jclouds.blobstore.integration.internal.StubBlobStore;
|
||||
import org.jclouds.blobstore.integration.internal.BaseBlobStoreIntegrationTest.BlobStoreObjectFactory;
|
||||
import org.jclouds.cloud.CloudContextBuilder;
|
||||
import org.jclouds.lifecycle.Closer;
|
||||
import org.jclouds.logging.Logger;
|
||||
import org.testng.ITestContext;
|
||||
import org.jclouds.blobstore.integration.internal.BaseTestInitializer;
|
||||
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Injector;
|
||||
import com.google.inject.Key;
|
||||
import com.google.inject.Module;
|
||||
import com.google.inject.Scopes;
|
||||
import com.google.inject.TypeLiteral;
|
||||
import com.google.inject.assistedinject.Assisted;
|
||||
import com.google.inject.assistedinject.FactoryProvider;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class StubTestInitializer
|
||||
implements
|
||||
BaseBlobStoreIntegrationTest.TestInitializer<BlobStore<ContainerMetadata, BlobMetadata, Blob<BlobMetadata>>, ContainerMetadata, BlobMetadata, Blob<BlobMetadata>> {
|
||||
extends
|
||||
BaseTestInitializer<BlobStore<ContainerMetadata, BlobMetadata, Blob<BlobMetadata>>, ContainerMetadata, BlobMetadata, Blob<BlobMetadata>> {
|
||||
|
||||
public BaseBlobStoreIntegrationTest.TestInitializer.Result<BlobStore<ContainerMetadata, BlobMetadata, Blob<BlobMetadata>>, ContainerMetadata, BlobMetadata, Blob<BlobMetadata>> init(
|
||||
Module configurationModule, ITestContext testContext) throws Exception {
|
||||
|
||||
final StubBlobStoreContext context = createStubContext();
|
||||
assert context != null;
|
||||
|
||||
final BlobStore<ContainerMetadata, BlobMetadata, Blob<BlobMetadata>> client = context
|
||||
.getApi();
|
||||
assert client != null;
|
||||
|
||||
final BlobStoreObjectFactory<ContainerMetadata, Blob<BlobMetadata>> objectFactory = new BaseBlobStoreIntegrationTest.BlobStoreObjectFactory<ContainerMetadata, Blob<BlobMetadata>>() {
|
||||
|
||||
public Blob<BlobMetadata> createBlob(String key) {
|
||||
return new Blob<BlobMetadata>(key);
|
||||
|
||||
}
|
||||
|
||||
public ContainerMetadata createContainerMetadata(String key) {
|
||||
return new ContainerMetadata(key);
|
||||
}
|
||||
|
||||
};
|
||||
assert objectFactory != null;
|
||||
|
||||
return new BaseBlobStoreIntegrationTest.TestInitializer.Result<BlobStore<ContainerMetadata, BlobMetadata, Blob<BlobMetadata>>, ContainerMetadata, BlobMetadata, Blob<BlobMetadata>>() {
|
||||
|
||||
public BlobStore<ContainerMetadata, BlobMetadata, Blob<BlobMetadata>> getClient() {
|
||||
return client;
|
||||
}
|
||||
|
||||
public BlobStoreContext<BlobStore<ContainerMetadata, BlobMetadata, Blob<BlobMetadata>>, BlobMetadata, Blob<BlobMetadata>> getContext() {
|
||||
return context;
|
||||
}
|
||||
|
||||
public BlobStoreObjectFactory<ContainerMetadata, Blob<BlobMetadata>> getObjectFactory() {
|
||||
return objectFactory;
|
||||
}
|
||||
|
||||
};
|
||||
@Override
|
||||
protected BlobStoreContext<BlobStore<ContainerMetadata, BlobMetadata, Blob<BlobMetadata>>, ContainerMetadata, BlobMetadata, Blob<BlobMetadata>> createLiveContext(
|
||||
Module configurationModule, String url, String app, String account, String key) {
|
||||
return createStubContext();
|
||||
}
|
||||
|
||||
protected StubBlobStoreContext createStubContext() {
|
||||
return new StubContextBuilder().buildContext();
|
||||
@Override
|
||||
protected BlobStoreContext<BlobStore<ContainerMetadata, BlobMetadata, Blob<BlobMetadata>>, ContainerMetadata, BlobMetadata, Blob<BlobMetadata>> createStubContext() {
|
||||
return new StubBlobStoreContextBuilder().buildContext();
|
||||
}
|
||||
|
||||
public static interface BlobMapFactory {
|
||||
BlobMap<BlobMetadata, Blob<BlobMetadata>> createMapView(String container);
|
||||
}
|
||||
|
||||
public static interface InputStreamMapFactory {
|
||||
InputStreamMap<BlobMetadata> createMapView(String container);
|
||||
}
|
||||
|
||||
public static class GuiceStubBlobStoreContext implements StubBlobStoreContext {
|
||||
|
||||
@Resource
|
||||
private Logger logger = Logger.NULL;
|
||||
private final Injector injector;
|
||||
private final InputStreamMapFactory inputStreamMapFactory;
|
||||
private final BlobMapFactory objectMapFactory;
|
||||
private final Closer closer;
|
||||
|
||||
@Inject
|
||||
private GuiceStubBlobStoreContext(Injector injector, Closer closer,
|
||||
BlobMapFactory objectMapFactory, InputStreamMapFactory inputStreamMapFactory) {
|
||||
this.injector = injector;
|
||||
this.inputStreamMapFactory = inputStreamMapFactory;
|
||||
this.objectMapFactory = objectMapFactory;
|
||||
this.closer = closer;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public InputStreamMap<BlobMetadata> createInputStreamMap(String container) {
|
||||
getApi().createContainer(container);
|
||||
return inputStreamMapFactory.createMapView(container);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public BlobMap<BlobMetadata, Blob<BlobMetadata>> createBlobMap(String container) {
|
||||
getApi().createContainer(container);
|
||||
return objectMapFactory.createMapView(container);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @see Closer
|
||||
*/
|
||||
public void close() {
|
||||
try {
|
||||
closer.close();
|
||||
} catch (IOException e) {
|
||||
logger.error(e, "error closing content");
|
||||
}
|
||||
}
|
||||
|
||||
public String getAccount() {
|
||||
// throw org.jboss.util.NotImplementedException("FIXME NYI getAccount");
|
||||
return null;
|
||||
}
|
||||
|
||||
public URI getEndPoint() {
|
||||
// throw org.jboss.util.NotImplementedException("FIXME NYI getEndPoint");
|
||||
return null;
|
||||
}
|
||||
|
||||
public BlobStore<ContainerMetadata, BlobMetadata, Blob<BlobMetadata>> getApi() {
|
||||
return injector
|
||||
.getInstance(Key
|
||||
.get(new TypeLiteral<BlobStore<ContainerMetadata, BlobMetadata, Blob<BlobMetadata>>>() {
|
||||
}));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public interface StubBlobStoreContext
|
||||
extends
|
||||
BlobStoreContext<BlobStore<ContainerMetadata, BlobMetadata, Blob<BlobMetadata>>, BlobMetadata, Blob<BlobMetadata>> {
|
||||
|
||||
}
|
||||
|
||||
public static class StubContextBuilder extends CloudContextBuilder<StubBlobStoreContext> {
|
||||
|
||||
public StubContextBuilder() {
|
||||
super(new Properties());
|
||||
}
|
||||
|
||||
public void authenticate(String id, String secret) {
|
||||
}
|
||||
|
||||
public StubBlobStoreContext buildContext() {
|
||||
return buildInjector().getInstance(StubBlobStoreContext.class);
|
||||
}
|
||||
|
||||
protected void addContextModule(List<Module> modules) {
|
||||
modules.add(new AbstractModule() {
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
|
||||
requireBinding(TestStubBlobStore.class);
|
||||
bind(URI.class).toInstance(URI.create("http://localhost:8080"));
|
||||
bind(new TypeLiteral<BlobMapFactory>() {
|
||||
})
|
||||
.toProvider(
|
||||
FactoryProvider
|
||||
.newFactory(
|
||||
new TypeLiteral<BlobMapFactory>() {
|
||||
},
|
||||
new TypeLiteral<LiveBlobMap<ContainerMetadata, BlobMetadata, Blob<BlobMetadata>>>() {
|
||||
}));
|
||||
bind(new TypeLiteral<InputStreamMapFactory>() {
|
||||
}).toProvider(FactoryProvider.newFactory(new TypeLiteral<InputStreamMapFactory>() {
|
||||
}, new TypeLiteral<StubInputStreamMap>() {
|
||||
}));
|
||||
bind(StubBlobStoreContext.class).to(GuiceStubBlobStoreContext.class);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected void addApiModule(List<Module> modules) {
|
||||
modules.add(new AbstractModule() {
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
bind(
|
||||
new TypeLiteral<BlobStore<ContainerMetadata, BlobMetadata, Blob<BlobMetadata>>>() {
|
||||
}).to(TestStubBlobStore.class).in(Scopes.SINGLETON);
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public CloudContextBuilder<StubBlobStoreContext> withEndpoint(URI endpoint) {
|
||||
// throw org.jboss.util.NotImplementedException("FIXME NYI withEndpoint");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static class StubInputStreamMap extends
|
||||
LiveInputStreamMap<ContainerMetadata, BlobMetadata, Blob<BlobMetadata>> {
|
||||
|
||||
@Inject
|
||||
public StubInputStreamMap(
|
||||
BlobStore<ContainerMetadata, BlobMetadata, Blob<BlobMetadata>> connection,
|
||||
@Assisted String container) {
|
||||
super(connection, container);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Blob<BlobMetadata> createBlob(String s) {
|
||||
return new Blob<BlobMetadata>(s);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class TestStubBlobStore extends
|
||||
StubBlobStore<ContainerMetadata, BlobMetadata, Blob<BlobMetadata>> {
|
||||
/**
|
||||
* note this must be final and static so that tests coming from multiple threads will pass.
|
||||
*/
|
||||
private static final Map<String, Map<String, Blob<BlobMetadata>>> containerToBlobs = new ConcurrentHashMap<String, Map<String, Blob<BlobMetadata>>>();
|
||||
|
||||
@Override
|
||||
public Map<String, Map<String, Blob<BlobMetadata>>> getContainerToBlobs() {
|
||||
return containerToBlobs;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Blob<BlobMetadata> createBlob(String name) {
|
||||
return new Blob<BlobMetadata>(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Blob<BlobMetadata> createBlob(BlobMetadata metadata) {
|
||||
return new Blob<BlobMetadata>(metadata);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ContainerMetadata createContainerMetadata(String name) {
|
||||
return new ContainerMetadata(name);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -21,35 +21,33 @@
|
|||
* under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
package org.jclouds.rackspace.cloudfiles.internal;
|
||||
package org.jclouds.blobstore.integration.config;
|
||||
|
||||
import org.jclouds.blobstore.LiveInputStreamMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.jclouds.blobstore.BlobStore;
|
||||
import org.jclouds.blobstore.domain.Blob;
|
||||
import org.jclouds.blobstore.domain.BlobMetadata;
|
||||
import org.jclouds.rackspace.cloudfiles.CloudFilesBlobStore;
|
||||
import org.jclouds.rackspace.cloudfiles.domain.ContainerMetadata;
|
||||
import org.jclouds.blobstore.domain.ContainerMetadata;
|
||||
import org.jclouds.blobstore.integration.internal.StubBlobStore;
|
||||
import org.jclouds.cloud.ConfiguresCloudConnection;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import com.google.inject.assistedinject.Assisted;
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.TypeLiteral;
|
||||
|
||||
/**
|
||||
* Map representation of a live connection to CloudFiles. All put operations will result in ETag
|
||||
* calculation. If this is not desired, use {@link LiveCloudFilesObjectMap} instead.
|
||||
*
|
||||
* @author Adrian Cole
|
||||
* @see CloudFilesBlobStore
|
||||
* @see LiveInputStreamMap
|
||||
*/
|
||||
public class LiveCloudFilesInputStreamMap extends
|
||||
LiveInputStreamMap<ContainerMetadata, BlobMetadata, Blob<BlobMetadata>> {
|
||||
@ConfiguresCloudConnection
|
||||
public class StubBlobStoreConnectionModule extends AbstractModule {
|
||||
|
||||
@Inject
|
||||
public LiveCloudFilesInputStreamMap(CloudFilesBlobStore connection, @Assisted String container) {
|
||||
super(connection, container);
|
||||
}
|
||||
// must be singleton for all threads and all objects or tests may fail;
|
||||
static final ConcurrentHashMap<String, Map<String, Blob<BlobMetadata>>> map = new ConcurrentHashMap<String, Map<String, Blob<BlobMetadata>>>();
|
||||
|
||||
@Override
|
||||
protected Blob<BlobMetadata> createBlob(String s) {
|
||||
return new Blob<BlobMetadata>(s);
|
||||
protected void configure() {
|
||||
bind(new TypeLiteral<Map<String, Map<String, Blob<BlobMetadata>>>>() {
|
||||
}).toInstance(map);
|
||||
bind(new TypeLiteral<BlobStore<ContainerMetadata, BlobMetadata, Blob<BlobMetadata>>>() {
|
||||
}).to(new TypeLiteral<StubBlobStore<ContainerMetadata, BlobMetadata, Blob<BlobMetadata>>>() {
|
||||
}).asEagerSingleton();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -45,6 +45,7 @@ import java.util.concurrent.TimeoutException;
|
|||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.jclouds.blobstore.BlobStore;
|
||||
import org.jclouds.blobstore.ContainerNotFoundException;
|
||||
import org.jclouds.blobstore.domain.Blob;
|
||||
import org.jclouds.blobstore.domain.BlobMetadata;
|
||||
import org.jclouds.blobstore.domain.ContainerMetadata;
|
||||
|
@ -75,11 +76,13 @@ public class BaseBlobIntegrationTest<S extends BlobStore<C, M, B>, C extends Con
|
|||
addObjectAndValidateContent(containerName, key);
|
||||
DateTime after = new DateTime().plusSeconds(1);
|
||||
|
||||
client.getBlob(containerName, key, ifModifiedSince(before)).get(10, TimeUnit.SECONDS);
|
||||
context.getApi().getBlob(containerName, key, ifModifiedSince(before)).get(10,
|
||||
TimeUnit.SECONDS);
|
||||
validateContent(containerName, key);
|
||||
|
||||
try {
|
||||
client.getBlob(containerName, key, ifModifiedSince(after)).get(10, TimeUnit.SECONDS);
|
||||
context.getApi().getBlob(containerName, key, ifModifiedSince(after)).get(10,
|
||||
TimeUnit.SECONDS);
|
||||
validateContent(containerName, key);
|
||||
} catch (ExecutionException e) {
|
||||
if (e.getCause() instanceof HttpResponseException) {
|
||||
|
@ -109,11 +112,13 @@ public class BaseBlobIntegrationTest<S extends BlobStore<C, M, B>, C extends Con
|
|||
addObjectAndValidateContent(containerName, key);
|
||||
DateTime after = new DateTime().plusSeconds(1);
|
||||
|
||||
client.getBlob(containerName, key, ifUnmodifiedSince(after)).get(10, TimeUnit.SECONDS);
|
||||
context.getApi().getBlob(containerName, key, ifUnmodifiedSince(after)).get(10,
|
||||
TimeUnit.SECONDS);
|
||||
validateContent(containerName, key);
|
||||
|
||||
try {
|
||||
client.getBlob(containerName, key, ifUnmodifiedSince(before)).get(10, TimeUnit.SECONDS);
|
||||
context.getApi().getBlob(containerName, key, ifUnmodifiedSince(before)).get(10,
|
||||
TimeUnit.SECONDS);
|
||||
validateContent(containerName, key);
|
||||
} catch (ExecutionException e) {
|
||||
if (e.getCause() instanceof HttpResponseException) {
|
||||
|
@ -140,11 +145,13 @@ public class BaseBlobIntegrationTest<S extends BlobStore<C, M, B>, C extends Con
|
|||
|
||||
addObjectAndValidateContent(containerName, key);
|
||||
|
||||
client.getBlob(containerName, key, ifETagMatches(goodETag)).get(10, TimeUnit.SECONDS);
|
||||
context.getApi().getBlob(containerName, key, ifETagMatches(goodETag)).get(10,
|
||||
TimeUnit.SECONDS);
|
||||
validateContent(containerName, key);
|
||||
|
||||
try {
|
||||
client.getBlob(containerName, key, ifETagMatches(badETag)).get(10, TimeUnit.SECONDS);
|
||||
context.getApi().getBlob(containerName, key, ifETagMatches(badETag)).get(10,
|
||||
TimeUnit.SECONDS);
|
||||
validateContent(containerName, key);
|
||||
} catch (ExecutionException e) {
|
||||
if (e.getCause() instanceof HttpResponseException) {
|
||||
|
@ -171,11 +178,12 @@ public class BaseBlobIntegrationTest<S extends BlobStore<C, M, B>, C extends Con
|
|||
|
||||
addObjectAndValidateContent(containerName, key);
|
||||
|
||||
client.getBlob(containerName, key, ifETagDoesntMatch(badETag)).get(10, TimeUnit.SECONDS);
|
||||
context.getApi().getBlob(containerName, key, ifETagDoesntMatch(badETag)).get(10,
|
||||
TimeUnit.SECONDS);
|
||||
validateContent(containerName, key);
|
||||
|
||||
try {
|
||||
client.getBlob(containerName, key, ifETagDoesntMatch(goodETag)).get(10,
|
||||
context.getApi().getBlob(containerName, key, ifETagDoesntMatch(goodETag)).get(10,
|
||||
TimeUnit.SECONDS);
|
||||
validateContent(containerName, key);
|
||||
} catch (ExecutionException e) {
|
||||
|
@ -200,12 +208,13 @@ public class BaseBlobIntegrationTest<S extends BlobStore<C, M, B>, C extends Con
|
|||
String key = "apples";
|
||||
|
||||
addObjectAndValidateContent(containerName, key);
|
||||
B object1 = client.getBlob(containerName, key, range(0, 5)).get(10, TimeUnit.SECONDS);
|
||||
B object1 = context.getApi().getBlob(containerName, key, range(0, 5)).get(10,
|
||||
TimeUnit.SECONDS);
|
||||
assertEquals(BlobStoreUtils.getContentAsStringAndClose(object1), TEST_STRING.substring(0,
|
||||
6));
|
||||
|
||||
B object2 = client.getBlob(containerName, key, range(6, TEST_STRING.length())).get(10,
|
||||
TimeUnit.SECONDS);
|
||||
B object2 = context.getApi().getBlob(containerName, key, range(6, TEST_STRING.length()))
|
||||
.get(10, TimeUnit.SECONDS);
|
||||
assertEquals(BlobStoreUtils.getContentAsStringAndClose(object2), TEST_STRING.substring(6,
|
||||
TEST_STRING.length()));
|
||||
} finally {
|
||||
|
@ -222,8 +231,8 @@ public class BaseBlobIntegrationTest<S extends BlobStore<C, M, B>, C extends Con
|
|||
String key = "apples";
|
||||
|
||||
addObjectAndValidateContent(containerName, key);
|
||||
B object = client.getBlob(containerName, key, range(0, 5).range(6, TEST_STRING.length()))
|
||||
.get(10, TimeUnit.SECONDS);
|
||||
B object = context.getApi().getBlob(containerName, key,
|
||||
range(0, 5).range(6, TEST_STRING.length())).get(10, TimeUnit.SECONDS);
|
||||
|
||||
assertEquals(BlobStoreUtils.getContentAsStringAndClose(object), TEST_STRING);
|
||||
} finally {
|
||||
|
@ -240,7 +249,7 @@ public class BaseBlobIntegrationTest<S extends BlobStore<C, M, B>, C extends Con
|
|||
String key = "apples";
|
||||
|
||||
addObjectAndValidateContent(containerName, key);
|
||||
B object = client.getBlob(containerName, key, tail(5)).get(10, TimeUnit.SECONDS);
|
||||
B object = context.getApi().getBlob(containerName, key, tail(5)).get(10, TimeUnit.SECONDS);
|
||||
assertEquals(BlobStoreUtils.getContentAsStringAndClose(object), TEST_STRING
|
||||
.substring(TEST_STRING.length() - 5));
|
||||
assertEquals(object.getContentLength(), 5);
|
||||
|
@ -258,7 +267,8 @@ public class BaseBlobIntegrationTest<S extends BlobStore<C, M, B>, C extends Con
|
|||
String key = "apples";
|
||||
|
||||
addObjectAndValidateContent(containerName, key);
|
||||
B object = client.getBlob(containerName, key, startAt(5)).get(10, TimeUnit.SECONDS);
|
||||
B object = context.getApi().getBlob(containerName, key, startAt(5)).get(10,
|
||||
TimeUnit.SECONDS);
|
||||
assertEquals(BlobStoreUtils.getContentAsStringAndClose(object), TEST_STRING.substring(5,
|
||||
TEST_STRING.length()));
|
||||
assertEquals(object.getContentLength(), TEST_STRING.length() - 5);
|
||||
|
@ -279,7 +289,7 @@ public class BaseBlobIntegrationTest<S extends BlobStore<C, M, B>, C extends Con
|
|||
String containerName = getContainerName();
|
||||
String key = "test";
|
||||
try {
|
||||
assert client.removeBlob(containerName, key).get(10, TimeUnit.SECONDS);
|
||||
assert context.getApi().removeBlob(containerName, key).get(10, TimeUnit.SECONDS);
|
||||
} finally {
|
||||
returnContainer(containerName);
|
||||
}
|
||||
|
@ -287,7 +297,7 @@ public class BaseBlobIntegrationTest<S extends BlobStore<C, M, B>, C extends Con
|
|||
|
||||
@DataProvider(name = "delete")
|
||||
public Object[][] createData() {
|
||||
return new Object[][] { { "sp ace" }, { "unic¿de" }, { "qu?stion" } };
|
||||
return new Object[][] { { "sp ace" }, { "qu?stion" }, { "unic¿de" }, { "path/" } };
|
||||
}
|
||||
|
||||
@Test(groups = { "integration", "live" }, dataProvider = "delete")
|
||||
|
@ -295,7 +305,7 @@ public class BaseBlobIntegrationTest<S extends BlobStore<C, M, B>, C extends Con
|
|||
String containerName = getContainerName();
|
||||
try {
|
||||
addBlobToContainer(containerName, key);
|
||||
assert client.removeBlob(containerName, key).get(10, TimeUnit.SECONDS);
|
||||
assert context.getApi().removeBlob(containerName, key).get(10, TimeUnit.SECONDS);
|
||||
assertContainerEmptyDeleting(containerName, key);
|
||||
} finally {
|
||||
returnContainer(containerName);
|
||||
|
@ -304,7 +314,7 @@ public class BaseBlobIntegrationTest<S extends BlobStore<C, M, B>, C extends Con
|
|||
|
||||
private void assertContainerEmptyDeleting(String containerName, String key)
|
||||
throws InterruptedException, ExecutionException, TimeoutException {
|
||||
List<M> listing = client.listBlobs(containerName).get(10, TimeUnit.SECONDS);
|
||||
List<M> listing = context.getApi().listBlobs(containerName).get(10, TimeUnit.SECONDS);
|
||||
assertEquals(listing.size(), 0, String.format(
|
||||
"deleting %s, we still have %s left in container %s, using encoding %s", key,
|
||||
listing.size(), containerName, LOCAL_ENCODING));
|
||||
|
@ -313,10 +323,11 @@ public class BaseBlobIntegrationTest<S extends BlobStore<C, M, B>, C extends Con
|
|||
@Test(groups = { "integration", "live" })
|
||||
public void deleteObjectNoContainer() throws Exception {
|
||||
try {
|
||||
client.removeBlob("donb", "test").get(10, TimeUnit.SECONDS);
|
||||
context.getApi().removeBlob("donb", "test").get(10, TimeUnit.SECONDS);
|
||||
} catch (ExecutionException e) {
|
||||
assert e.getCause() instanceof HttpResponseException;
|
||||
assertEquals(((HttpResponseException) e.getCause()).getResponse().getStatusCode(), 404);
|
||||
assert (e.getCause() instanceof HttpResponseException || e.getCause() instanceof ContainerNotFoundException);
|
||||
if (e.getCause() instanceof HttpResponseException)
|
||||
assertEquals(((HttpResponseException) e.getCause()).getResponse().getStatusCode(), 404);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -333,7 +344,7 @@ public class BaseBlobIntegrationTest<S extends BlobStore<C, M, B>, C extends Con
|
|||
@Test(groups = { "integration", "live" }, dataProvider = "putTests")
|
||||
public void testPutObject(String key, String type, Object content, Object realObject)
|
||||
throws Exception {
|
||||
B object = objectFactory.createBlob(key);
|
||||
B object = context.newBlob(key);
|
||||
object.getMetadata().setContentType(type);
|
||||
object.setData(content);
|
||||
if (content instanceof InputStream) {
|
||||
|
@ -341,11 +352,12 @@ public class BaseBlobIntegrationTest<S extends BlobStore<C, M, B>, C extends Con
|
|||
}
|
||||
String containerName = getContainerName();
|
||||
try {
|
||||
assertNotNull(client.putBlob(containerName, object).get(10, TimeUnit.SECONDS));
|
||||
object = client.getBlob(containerName, object.getKey()).get(10, TimeUnit.SECONDS);
|
||||
assertNotNull(context.getApi().putBlob(containerName, object).get(10, TimeUnit.SECONDS));
|
||||
object = context.getApi().getBlob(containerName, object.getKey())
|
||||
.get(10, TimeUnit.SECONDS);
|
||||
String returnedString = BlobStoreUtils.getContentAsStringAndClose(object);
|
||||
assertEquals(returnedString, realObject);
|
||||
assertEquals(client.listBlobs(containerName).get(10, TimeUnit.SECONDS).size(), 1);
|
||||
assertEquals(context.getApi().listBlobs(containerName).get(10, TimeUnit.SECONDS).size(), 1);
|
||||
} finally {
|
||||
returnContainer(containerName);
|
||||
}
|
||||
|
@ -355,7 +367,7 @@ public class BaseBlobIntegrationTest<S extends BlobStore<C, M, B>, C extends Con
|
|||
public void testMetadata() throws Exception {
|
||||
String key = "hello";
|
||||
|
||||
B object = objectFactory.createBlob(key);
|
||||
B object = context.newBlob(key);
|
||||
object.setData(TEST_STRING);
|
||||
object.getMetadata().setContentType("text/plain");
|
||||
object.getMetadata().setSize(TEST_STRING.length());
|
||||
|
@ -371,7 +383,7 @@ public class BaseBlobIntegrationTest<S extends BlobStore<C, M, B>, C extends Con
|
|||
M metadata = newObject.getMetadata();
|
||||
|
||||
validateMetadata(metadata);
|
||||
validateMetadata(client.blobMetadata(containerName, key));
|
||||
validateMetadata(context.getApi().blobMetadata(containerName, key));
|
||||
} finally {
|
||||
returnContainer(containerName);
|
||||
}
|
||||
|
|
|
@ -75,15 +75,15 @@ public class BaseBlobLiveTest<S extends BlobStore<C, M, B>, C extends ContainerM
|
|||
int length = connection.getContentLength();
|
||||
InputStream input = connection.getInputStream();
|
||||
|
||||
B object = objectFactory.createBlob(key);
|
||||
B object = context.newBlob(key);
|
||||
object.setData(input);
|
||||
object.setContentLength(length);
|
||||
object.getMetadata().setContentMD5(md5);
|
||||
object.getMetadata().setSize(length);
|
||||
String bucketName = getContainerName();
|
||||
try {
|
||||
client.putBlob(bucketName, object).get(180, TimeUnit.SECONDS);
|
||||
assertEquals(client.blobMetadata(bucketName, key).getContentMD5(), md5);
|
||||
context.getApi().putBlob(bucketName, object).get(180, TimeUnit.SECONDS);
|
||||
assertEquals(context.getApi().blobMetadata(bucketName, key).getContentMD5(), md5);
|
||||
} finally {
|
||||
returnContainer(bucketName);
|
||||
}
|
||||
|
|
|
@ -138,7 +138,7 @@ public class BaseBlobMapIntegrationTest<S extends BlobStore<C, M, B>, C extends
|
|||
try {
|
||||
Map<String, B> map = createMap(context, bucketName);
|
||||
putString(map, "one", "apple");
|
||||
B object = objectFactory.createBlob("one");
|
||||
B object = context.newBlob("one");
|
||||
object.setData("apple");
|
||||
assertEventuallyContainsValue(map, object);
|
||||
} finally {
|
||||
|
@ -166,7 +166,7 @@ public class BaseBlobMapIntegrationTest<S extends BlobStore<C, M, B>, C extends
|
|||
String bucketName = getContainerName();
|
||||
try {
|
||||
Map<String, B> map = createMap(context, bucketName);
|
||||
B object = objectFactory.createBlob("one");
|
||||
B object = context.newBlob("one");
|
||||
object.setData(IOUtils.toInputStream("apple"));
|
||||
object.generateMD5();
|
||||
B old = map.put(object.getKey(), object);
|
||||
|
@ -187,7 +187,7 @@ public class BaseBlobMapIntegrationTest<S extends BlobStore<C, M, B>, C extends
|
|||
Map<String, B> map = createMap(context, bucketName);
|
||||
Map<String, B> newMap = new HashMap<String, B>();
|
||||
for (String key : fiveInputs.keySet()) {
|
||||
B object = objectFactory.createBlob(key);
|
||||
B object = context.newBlob(key);
|
||||
object.setData(fiveInputs.get(key));
|
||||
object.getMetadata().setSize(fiveBytes.get(key).length);
|
||||
newMap.put(key, object);
|
||||
|
@ -203,7 +203,7 @@ public class BaseBlobMapIntegrationTest<S extends BlobStore<C, M, B>, C extends
|
|||
|
||||
@Override
|
||||
protected void putString(Map<String, B> map, String key, String value) {
|
||||
B object = objectFactory.createBlob(key);
|
||||
B object = context.newBlob(key);
|
||||
object.setData(value);
|
||||
map.put(key, object);
|
||||
}
|
||||
|
@ -211,7 +211,7 @@ public class BaseBlobMapIntegrationTest<S extends BlobStore<C, M, B>, C extends
|
|||
protected void putFiveStrings(Map<String, B> map) {
|
||||
Map<String, B> newMap = new HashMap<String, B>();
|
||||
for (Map.Entry<String, String> entry : fiveStrings.entrySet()) {
|
||||
B object = objectFactory.createBlob(entry.getKey());
|
||||
B object = context.newBlob(entry.getKey());
|
||||
object.setData(entry.getValue());
|
||||
newMap.put(entry.getKey(), object);
|
||||
}
|
||||
|
|
|
@ -46,7 +46,6 @@ import org.jclouds.blobstore.BlobStoreContext;
|
|||
import org.jclouds.blobstore.domain.Blob;
|
||||
import org.jclouds.blobstore.domain.BlobMetadata;
|
||||
import org.jclouds.blobstore.domain.ContainerMetadata;
|
||||
import org.jclouds.blobstore.integration.internal.BaseBlobStoreIntegrationTest.TestInitializer.Result;
|
||||
import org.jclouds.blobstore.util.BlobStoreUtils;
|
||||
import org.jclouds.http.HttpResponseException;
|
||||
import org.jclouds.http.HttpUtils;
|
||||
|
@ -67,33 +66,13 @@ public class BaseBlobStoreIntegrationTest<S extends BlobStore<C, M, B>, C extend
|
|||
protected static final String LOCAL_ENCODING = System.getProperty("file.encoding");
|
||||
protected static final String TEST_STRING = "<apples><apple name=\"fuji\"></apple> </apples>";
|
||||
|
||||
public static interface BlobStoreObjectFactory<C, B> {
|
||||
B createBlob(String key);
|
||||
|
||||
C createContainerMetadata(String key);
|
||||
}
|
||||
|
||||
public static interface TestInitializer<S extends BlobStore<C, M, B>, C extends ContainerMetadata, M extends BlobMetadata, B extends Blob<M>> {
|
||||
Result<S, C, M, B> init(Module configurationModule, ITestContext context) throws Exception;
|
||||
|
||||
public static interface Result<S extends BlobStore<C, M, B>, C extends ContainerMetadata, M extends BlobMetadata, B extends Blob<M>> {
|
||||
BlobStoreObjectFactory<C, B> getObjectFactory();
|
||||
|
||||
S getClient();
|
||||
|
||||
BlobStoreContext<S, M, B> getContext();
|
||||
}
|
||||
}
|
||||
|
||||
public static long INCONSISTENCY_WINDOW = 5000;
|
||||
protected static volatile AtomicInteger containerIndex = new AtomicInteger(0);
|
||||
|
||||
protected byte[] goodETag;
|
||||
protected byte[] badETag;
|
||||
|
||||
protected volatile BlobStoreObjectFactory<C, B> objectFactory;
|
||||
protected volatile S client;
|
||||
protected volatile BlobStoreContext<S, M, B> context;
|
||||
protected volatile BlobStoreContext<S, C, M, B> context;
|
||||
protected static volatile int containerCount = 20;
|
||||
public static final String CONTAINER_PREFIX = System.getProperty("user.name") + "-blobstore";
|
||||
/**
|
||||
|
@ -117,31 +96,28 @@ public class BaseBlobStoreIntegrationTest<S extends BlobStore<C, M, B>, C extend
|
|||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private Result<S, C, M, B> getCloudResources(ITestContext testContext)
|
||||
private BlobStoreContext<S, C, M, B> getCloudResources(ITestContext testContext)
|
||||
throws ClassNotFoundException, InstantiationException, IllegalAccessException,
|
||||
Exception {
|
||||
String initializerClass = checkNotNull(System.getProperty("jclouds.test.initializer"),
|
||||
"jclouds.test.initializer");
|
||||
Class<TestInitializer<S, C, M, B>> clazz = (Class<TestInitializer<S, C, M, B>>) Class
|
||||
Class<BaseTestInitializer<S, C, M, B>> clazz = (Class<BaseTestInitializer<S, C, M, B>>) Class
|
||||
.forName(initializerClass);
|
||||
TestInitializer<S, C, M, B> initializer = clazz.newInstance();
|
||||
BaseTestInitializer<S, C, M, B> initializer = clazz.newInstance();
|
||||
return initializer.init(createHttpModule(), testContext);
|
||||
}
|
||||
|
||||
protected ExecutorService exec;
|
||||
|
||||
/**
|
||||
* we are doing this at a class level, as the client object is going to be shared for all methods
|
||||
* in the class. We don't want to do this for group, as some test classes may want to have a
|
||||
* different implementation of client. For example, one class may want non-blocking i/o and
|
||||
* another class google appengine.
|
||||
* we are doing this at a class level, as the context.getApi() object is going to be shared for
|
||||
* all methods in the class. We don't want to do this for group, as some test classes may want to
|
||||
* have a different implementation of context.getApi(). For example, one class may want
|
||||
* non-blocking i/o and another class google appengine.
|
||||
*/
|
||||
@BeforeClass(groups = { "integration", "live" })
|
||||
public void setUpResourcesOnThisThread(ITestContext testContext) throws Exception {
|
||||
TestInitializer.Result<S, C, M, B> result = getCloudResources(testContext);
|
||||
objectFactory = result.getObjectFactory();
|
||||
client = result.getClient();
|
||||
context = result.getContext();
|
||||
context = getCloudResources(testContext);
|
||||
exec = Executors.newCachedThreadPool();
|
||||
}
|
||||
|
||||
|
@ -154,25 +130,23 @@ public class BaseBlobStoreIntegrationTest<S extends BlobStore<C, M, B>, C extend
|
|||
|
||||
private static volatile boolean initialized = false;
|
||||
|
||||
protected void createContainersSharedByAllThreads(Result<S, C, M, B> result,
|
||||
protected void createContainersSharedByAllThreads(BlobStoreContext<S, C, M, B> context,
|
||||
ITestContext testContext) throws Exception {
|
||||
while (!initialized) {
|
||||
synchronized (BaseBlobStoreIntegrationTest.class) {
|
||||
if (!initialized) {
|
||||
S client = result.getClient();
|
||||
BlobStoreContext<S, M, B> context = result.getContext();
|
||||
deleteEverything(client, context);
|
||||
deleteEverything(context);
|
||||
for (; containerIndex.get() < containerCount; containerIndex.incrementAndGet()) {
|
||||
String containerName = CONTAINER_PREFIX + containerIndex;
|
||||
if (blackListContainers.contains(containerName)) {
|
||||
containerCount++;
|
||||
} else {
|
||||
try {
|
||||
createContainerAndEnsureEmpty(client, context, containerName);
|
||||
createContainerAndEnsureEmpty(context, containerName);
|
||||
containerJsr330.put(containerName);
|
||||
} catch (Throwable e) {
|
||||
// throw away the container and try again with the next index
|
||||
deleteContainerOrWarnIfUnable(client, context, containerName);
|
||||
deleteContainerOrWarnIfUnable(context, containerName);
|
||||
containerCount++;
|
||||
}
|
||||
}
|
||||
|
@ -187,10 +161,10 @@ public class BaseBlobStoreIntegrationTest<S extends BlobStore<C, M, B>, C extend
|
|||
}
|
||||
}
|
||||
|
||||
private static void deleteContainerOrWarnIfUnable(BlobStore<?, ?, ?> client,
|
||||
BlobStoreContext<?, ?, ?> context, String containerName) {
|
||||
private static void deleteContainerOrWarnIfUnable(BlobStoreContext<?, ?, ?, ?> context,
|
||||
String containerName) {
|
||||
try {
|
||||
deleteContainer(client, context, containerName);
|
||||
deleteContainer(context, containerName);
|
||||
} catch (Throwable ex) {
|
||||
System.err.printf("unable to delete container %s, ignoring...%n", containerName);
|
||||
blackListContainers.add(containerName);
|
||||
|
@ -203,12 +177,12 @@ public class BaseBlobStoreIntegrationTest<S extends BlobStore<C, M, B>, C extend
|
|||
* Tries to delete all containers, runs up to two times
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
protected static void deleteEverything(final BlobStore<?, ?, ?> client,
|
||||
final BlobStoreContext<?, ?, ?> context) throws Exception {
|
||||
protected static void deleteEverything(final BlobStoreContext<?, ?, ?, ?> context)
|
||||
throws Exception {
|
||||
try {
|
||||
for (int i = 0; i < 2; i++) {
|
||||
Iterable<ContainerMetadata> testContainers = Iterables.filter(
|
||||
(List<ContainerMetadata>) client.listContainers(),
|
||||
(List<ContainerMetadata>) context.getApi().listContainers(),
|
||||
new Predicate<ContainerMetadata>() {
|
||||
public boolean apply(ContainerMetadata input) {
|
||||
return input.getName().startsWith(CONTAINER_PREFIX.toLowerCase());
|
||||
|
@ -219,7 +193,7 @@ public class BaseBlobStoreIntegrationTest<S extends BlobStore<C, M, B>, C extend
|
|||
for (final ContainerMetadata metaDatum : testContainers) {
|
||||
executor.execute(new Runnable() {
|
||||
public void run() {
|
||||
deleteContainerOrWarnIfUnable(client, context, metaDatum.getName());
|
||||
deleteContainerOrWarnIfUnable(context, metaDatum.getName());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -257,29 +231,31 @@ public class BaseBlobStoreIntegrationTest<S extends BlobStore<C, M, B>, C extend
|
|||
throw error;
|
||||
}
|
||||
|
||||
protected static void createContainerAndEnsureEmpty(BlobStore<?, ?, ?> client,
|
||||
BlobStoreContext<?, ?, ?> context, final String containerName)
|
||||
throws InterruptedException, ExecutionException, TimeoutException {
|
||||
attemptToCreateContainerButRetryOn409(client, containerName);
|
||||
emptyContainer(client, context, containerName);
|
||||
protected static void createContainerAndEnsureEmpty(BlobStoreContext<?, ?, ?, ?> context,
|
||||
final String containerName) throws InterruptedException, ExecutionException,
|
||||
TimeoutException {
|
||||
attemptToCreateContainerButRetryOn409(context, containerName);
|
||||
emptyContainer(context, containerName);
|
||||
}
|
||||
|
||||
/**
|
||||
* 409 could be a resolvable conflict, ex. container delete in progress. FIXME Comment this
|
||||
*
|
||||
* @param client
|
||||
* @param context
|
||||
* .getApi()
|
||||
* @param containerName
|
||||
* @throws InterruptedException
|
||||
* @throws TimeoutException
|
||||
* @throws ExecutionException
|
||||
*/
|
||||
private static void attemptToCreateContainerButRetryOn409(BlobStore<?, ?, ?> client,
|
||||
private static void attemptToCreateContainerButRetryOn409(
|
||||
BlobStoreContext<? extends BlobStore<?, ?, ?>, ?, ?, ?> context,
|
||||
final String containerName) throws InterruptedException, TimeoutException,
|
||||
ExecutionException {
|
||||
ExecutionException error = null;
|
||||
OUTER: for (int i = 0; i < 10; i++) {
|
||||
try {
|
||||
client.createContainer(containerName).get(10, TimeUnit.SECONDS);
|
||||
context.getApi().createContainer(containerName).get(10, TimeUnit.SECONDS);
|
||||
break OUTER;
|
||||
} catch (ExecutionException e) {
|
||||
error = e;
|
||||
|
@ -298,12 +274,12 @@ public class BaseBlobStoreIntegrationTest<S extends BlobStore<C, M, B>, C extend
|
|||
|
||||
protected void createContainerAndEnsureEmpty(String containerName) throws InterruptedException,
|
||||
ExecutionException, TimeoutException {
|
||||
createContainerAndEnsureEmpty(client, context, containerName);
|
||||
createContainerAndEnsureEmpty(context, containerName);
|
||||
}
|
||||
|
||||
protected void addBlobToContainer(String sourceContainer, String key)
|
||||
throws InterruptedException, ExecutionException, TimeoutException, IOException {
|
||||
B sourceObject = objectFactory.createBlob(key);
|
||||
B sourceObject = context.newBlob(key);
|
||||
sourceObject.getMetadata().setContentType("text/xml");
|
||||
sourceObject.setData(TEST_STRING);
|
||||
addBlobToContainer(sourceContainer, sourceObject);
|
||||
|
@ -311,13 +287,13 @@ public class BaseBlobStoreIntegrationTest<S extends BlobStore<C, M, B>, C extend
|
|||
|
||||
protected void addBlobToContainer(String sourceContainer, B object) throws InterruptedException,
|
||||
ExecutionException, TimeoutException, IOException {
|
||||
client.putBlob(sourceContainer, object).get(10, TimeUnit.SECONDS);
|
||||
context.getApi().putBlob(sourceContainer, object).get(10, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
protected B validateContent(String sourceContainer, String key) throws InterruptedException,
|
||||
ExecutionException, TimeoutException, IOException {
|
||||
assertEventuallyContainerSize(sourceContainer, 1);
|
||||
B newObject = client.getBlob(sourceContainer, key).get(10, TimeUnit.SECONDS);
|
||||
B newObject = context.getApi().getBlob(sourceContainer, key).get(10, TimeUnit.SECONDS);
|
||||
assert newObject != null;
|
||||
assertEquals(BlobStoreUtils.getContentAsStringAndClose(newObject), TEST_STRING);
|
||||
return newObject;
|
||||
|
@ -328,7 +304,8 @@ public class BaseBlobStoreIntegrationTest<S extends BlobStore<C, M, B>, C extend
|
|||
assertEventually(new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
assertEquals(client.listBlobs(containerName).get(10, TimeUnit.SECONDS).size(), count);
|
||||
assertEquals(context.getApi().listBlobs(containerName).get(10, TimeUnit.SECONDS)
|
||||
.size(), count);
|
||||
} catch (Exception e) {
|
||||
Utils.<RuntimeException> rethrowIfRuntimeOrSameType(e);
|
||||
}
|
||||
|
@ -340,7 +317,8 @@ public class BaseBlobStoreIntegrationTest<S extends BlobStore<C, M, B>, C extend
|
|||
TimeoutException {
|
||||
String containerName = containerJsr330.poll(30, TimeUnit.SECONDS);
|
||||
assert containerName != null : "unable to get a container for the test";
|
||||
emptyContainer(containerName);
|
||||
if (!emptyContainer(containerName))
|
||||
this.createContainerAndEnsureEmpty(containerName);
|
||||
return containerName;
|
||||
}
|
||||
|
||||
|
@ -367,11 +345,12 @@ public class BaseBlobStoreIntegrationTest<S extends BlobStore<C, M, B>, C extend
|
|||
* *substantially* slow down tests on a real server over a network.
|
||||
*/
|
||||
if (SANITY_CHECK_RETURNED_BUCKET_NAME) {
|
||||
if (!Iterables.any(client.listContainers(), new Predicate<ContainerMetadata>() {
|
||||
public boolean apply(ContainerMetadata md) {
|
||||
return containerName.equals(md.getName());
|
||||
}
|
||||
})) {
|
||||
if (!Iterables.any(context.getApi().listContainers(),
|
||||
new Predicate<ContainerMetadata>() {
|
||||
public boolean apply(ContainerMetadata md) {
|
||||
return containerName.equals(md.getName());
|
||||
}
|
||||
})) {
|
||||
throw new IllegalStateException(
|
||||
"Test returned the name of a non-existent container: " + containerName);
|
||||
}
|
||||
|
@ -405,7 +384,7 @@ public class BaseBlobStoreIntegrationTest<S extends BlobStore<C, M, B>, C extend
|
|||
private String allocateNewContainerName(final String container) {
|
||||
exec.submit(new Runnable() {
|
||||
public void run() {
|
||||
deleteContainerOrWarnIfUnable(client, context, container);
|
||||
deleteContainerOrWarnIfUnable(context, container);
|
||||
}
|
||||
});
|
||||
String newScratchContainer = container + containerIndex.incrementAndGet();
|
||||
|
@ -417,20 +396,21 @@ public class BaseBlobStoreIntegrationTest<S extends BlobStore<C, M, B>, C extend
|
|||
return new JavaUrlHttpCommandExecutorServiceModule();
|
||||
}
|
||||
|
||||
protected void emptyContainer(String name) throws InterruptedException, ExecutionException,
|
||||
protected boolean emptyContainer(String name) throws InterruptedException, ExecutionException,
|
||||
TimeoutException {
|
||||
emptyContainer(client, context, name);
|
||||
return emptyContainer(context, name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove any objects in a container, leaving it empty.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
protected static void emptyContainer(BlobStore<?, ?, ?> client,
|
||||
final BlobStoreContext<?, ?, ?> context, final String name)
|
||||
throws InterruptedException, ExecutionException, TimeoutException {
|
||||
if (client.containerExists(name)) {
|
||||
protected static boolean emptyContainer(final BlobStoreContext<?, ?, ?, ?> context,
|
||||
final String name) throws InterruptedException, ExecutionException, TimeoutException {
|
||||
if (context.getApi().containerExists(name)) {
|
||||
// This can fail to be zero length because of stale container lists. Ex.
|
||||
// client.listContainer()
|
||||
// context.getApi().listContainer()
|
||||
// could return 9 keys, when there are 10. When all the deletions finish, one entry would
|
||||
// be left in this case. Instead of failing, we will attempt this entire container deletion
|
||||
// operation multiple times to ensure we can acheive a zero length container.
|
||||
|
@ -454,21 +434,23 @@ public class BaseBlobStoreIntegrationTest<S extends BlobStore<C, M, B>, C extend
|
|||
}
|
||||
}
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected static void deleteContainer(final BlobStore<?, ?, ?> client,
|
||||
BlobStoreContext<?, ?, ?> context, final String name) throws InterruptedException,
|
||||
ExecutionException, TimeoutException {
|
||||
if (client.containerExists(name)) {
|
||||
protected static void deleteContainer(
|
||||
final BlobStoreContext<? extends BlobStore<?, ?, ?>, ?, ?, ?> context, final String name)
|
||||
throws InterruptedException, ExecutionException, TimeoutException {
|
||||
if (context.getApi().containerExists(name)) {
|
||||
System.err.printf("*** deleting container %s...%n", name);
|
||||
emptyContainer(client, context, name);
|
||||
client.deleteContainer(name).get(10, TimeUnit.SECONDS);
|
||||
emptyContainer(context, name);
|
||||
context.getApi().deleteContainer(name).get(10, TimeUnit.SECONDS);
|
||||
assertEventually(new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
assert !client.containerExists(name) : "container " + name + " still exists";
|
||||
assert !context.getApi().containerExists(name) : "container " + name
|
||||
+ " still exists";
|
||||
} catch (Exception e) {
|
||||
Utils.<RuntimeException> rethrowIfRuntimeOrSameType(e);
|
||||
}
|
||||
|
|
|
@ -46,15 +46,15 @@ public class BaseContainerIntegrationTest<S extends BlobStore<C, M, B>, C extend
|
|||
|
||||
@Test(groups = { "integration", "live" })
|
||||
public void containerDoesntExist() throws Exception {
|
||||
assert !client.containerExists("forgetaboutit");
|
||||
assert !context.getApi().containerExists("forgetaboutit");
|
||||
}
|
||||
|
||||
@Test(groups = { "integration", "live" })
|
||||
public void testPutTwiceIsOk() throws Exception {
|
||||
String containerName = getContainerName();
|
||||
try {
|
||||
client.createContainer(containerName).get(10, TimeUnit.SECONDS);
|
||||
client.createContainer(containerName).get(10, TimeUnit.SECONDS);
|
||||
context.getApi().createContainer(containerName).get(10, TimeUnit.SECONDS);
|
||||
context.getApi().createContainer(containerName).get(10, TimeUnit.SECONDS);
|
||||
} finally {
|
||||
returnContainer(containerName);
|
||||
}
|
||||
|
@ -64,7 +64,7 @@ public class BaseContainerIntegrationTest<S extends BlobStore<C, M, B>, C extend
|
|||
public void containerExists() throws Exception {
|
||||
String containerName = getContainerName();
|
||||
try {
|
||||
assert client.containerExists(containerName);
|
||||
assert context.getApi().containerExists(containerName);
|
||||
} finally {
|
||||
returnContainer(containerName);
|
||||
}
|
||||
|
@ -75,7 +75,7 @@ public class BaseContainerIntegrationTest<S extends BlobStore<C, M, B>, C extend
|
|||
*/
|
||||
@Test(groups = { "integration", "live" })
|
||||
public void deleteContainerIfEmptyNotFound() throws Exception {
|
||||
assert client.deleteContainer("dbienf").get(10, TimeUnit.SECONDS);
|
||||
assert context.getApi().deleteContainer("dbienf").get(10, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
@Test(groups = { "integration", "live" })
|
||||
|
@ -83,7 +83,7 @@ public class BaseContainerIntegrationTest<S extends BlobStore<C, M, B>, C extend
|
|||
String containerName = getContainerName();
|
||||
try {
|
||||
addBlobToContainer(containerName, "test");
|
||||
assert !client.deleteContainer(containerName).get(10, TimeUnit.SECONDS);
|
||||
assert !context.getApi().deleteContainer(containerName).get(10, TimeUnit.SECONDS);
|
||||
} finally {
|
||||
returnContainer(containerName);
|
||||
}
|
||||
|
@ -93,13 +93,13 @@ public class BaseContainerIntegrationTest<S extends BlobStore<C, M, B>, C extend
|
|||
public void deleteContainerIfEmpty() throws Exception {
|
||||
final String containerName = getContainerName();
|
||||
try {
|
||||
assert client.deleteContainer(containerName).get(10, TimeUnit.SECONDS);
|
||||
assert context.getApi().deleteContainer(containerName).get(10, TimeUnit.SECONDS);
|
||||
|
||||
assertEventually(new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
assert !client.containerExists(containerName) : "container " + containerName
|
||||
+ " still exists";
|
||||
assert !context.getApi().containerExists(containerName) : "container "
|
||||
+ containerName + " still exists";
|
||||
} catch (Exception e) {
|
||||
Utils.<RuntimeException> rethrowIfRuntimeOrSameType(e);
|
||||
}
|
||||
|
@ -114,9 +114,9 @@ public class BaseContainerIntegrationTest<S extends BlobStore<C, M, B>, C extend
|
|||
protected void addAlphabetUnderRoot(String containerName) throws InterruptedException,
|
||||
ExecutionException, TimeoutException {
|
||||
for (char letter = 'a'; letter <= 'z'; letter++) {
|
||||
B blob = objectFactory.createBlob(letter + "");
|
||||
B blob = context.newBlob(letter + "");
|
||||
blob.setData(letter + "content");
|
||||
client.putBlob(containerName, blob).get(10, TimeUnit.SECONDS);
|
||||
context.getApi().putBlob(containerName, blob).get(10, TimeUnit.SECONDS);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -125,10 +125,9 @@ public class BaseContainerIntegrationTest<S extends BlobStore<C, M, B>, C extend
|
|||
TimeoutException, UnsupportedEncodingException {
|
||||
String containerName = getContainerName();
|
||||
try {
|
||||
String prefix = "apps";
|
||||
addTenObjectsUnderPrefix(containerName, prefix);
|
||||
List<M> container = client.listBlobs(containerName).get(10, TimeUnit.SECONDS);
|
||||
assertEquals(container.size(), 10);
|
||||
add15UnderRoot(containerName);
|
||||
List<M> container = context.getApi().listBlobs(containerName).get(10, TimeUnit.SECONDS);
|
||||
assertEquals(container.size(), 15);
|
||||
} finally {
|
||||
returnContainer(containerName);
|
||||
}
|
||||
|
@ -138,18 +137,18 @@ public class BaseContainerIntegrationTest<S extends BlobStore<C, M, B>, C extend
|
|||
protected void add15UnderRoot(String containerName) throws InterruptedException,
|
||||
ExecutionException, TimeoutException {
|
||||
for (int i = 0; i < 15; i++) {
|
||||
B blob = objectFactory.createBlob(i + "");
|
||||
B blob = context.newBlob(i + "");
|
||||
blob.setData(i + "content");
|
||||
client.putBlob(containerName, blob).get(10, TimeUnit.SECONDS);
|
||||
context.getApi().putBlob(containerName, blob).get(10, TimeUnit.SECONDS);
|
||||
}
|
||||
}
|
||||
|
||||
protected void addTenObjectsUnderPrefix(String containerName, String prefix)
|
||||
throws InterruptedException, ExecutionException, TimeoutException {
|
||||
for (int i = 0; i < 10; i++) {
|
||||
B blob = objectFactory.createBlob(prefix + "/" + i);
|
||||
B blob = context.newBlob(prefix + "/" + i);
|
||||
blob.setData(i + "content");
|
||||
client.putBlob(containerName, blob).get(10, TimeUnit.SECONDS);
|
||||
context.getApi().putBlob(containerName, blob).get(10, TimeUnit.SECONDS);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -77,6 +77,13 @@ public abstract class BaseMapIntegrationTest<S extends BlobStore<C, M, B>, C ext
|
|||
protected Map<String, File> fiveFiles;
|
||||
String tmpDirectory;
|
||||
|
||||
@BeforeMethod(groups = { "integration", "live" })
|
||||
protected void setUpInputStreams() {
|
||||
fiveInputs = ImmutableMap.of("one", IOUtils.toInputStream("apple"), "two", IOUtils
|
||||
.toInputStream("bear"), "three", IOUtils.toInputStream("candy"), "four", IOUtils
|
||||
.toInputStream("dogma"), "five", IOUtils.toInputStream("emma"));
|
||||
}
|
||||
|
||||
@BeforeMethod(groups = { "integration", "live" })
|
||||
@Parameters( { "basedir" })
|
||||
protected void setUpTempDir(@Optional String basedir) throws InterruptedException,
|
||||
|
@ -96,12 +103,9 @@ public abstract class BaseMapIntegrationTest<S extends BlobStore<C, M, B>, C ext
|
|||
IOUtils.write(file.getName(), new FileOutputStream(file));
|
||||
}
|
||||
|
||||
fiveInputs = ImmutableMap.of("one", IOUtils.toInputStream("apple"), "two", IOUtils
|
||||
.toInputStream("bear"), "three", IOUtils.toInputStream("candy"), "four", IOUtils
|
||||
.toInputStream("dogma"), "five", IOUtils.toInputStream("emma"));
|
||||
}
|
||||
|
||||
protected abstract Map<String, V> createMap(BlobStoreContext<?, ?, ?> context, String bucket);
|
||||
protected abstract Map<String, V> createMap(BlobStoreContext<?, ?, ?, ?> context, String bucket);
|
||||
|
||||
@Test(groups = { "integration", "live" })
|
||||
public void testClear() throws InterruptedException, ExecutionException, TimeoutException {
|
||||
|
@ -280,8 +284,8 @@ public abstract class BaseMapIntegrationTest<S extends BlobStore<C, M, B>, C ext
|
|||
}
|
||||
}
|
||||
|
||||
protected void assertEventuallyListContainer(final ListableMap<?, ?, ?> map, final String bucketName)
|
||||
throws InterruptedException {
|
||||
protected void assertEventuallyListContainer(final ListableMap<?, ?, ?> map,
|
||||
final String bucketName) throws InterruptedException {
|
||||
assertEventually(new Runnable() {
|
||||
public void run() {
|
||||
assertTrue(map.listContainer().size() >= 0);
|
||||
|
|
|
@ -40,8 +40,8 @@ public class BaseServiceIntegrationTest<S extends BlobStore<C, M, B>, C extends
|
|||
|
||||
@Test(groups = { "integration", "live" })
|
||||
void containerDoesntExist() throws Exception {
|
||||
List<C> list = client.listContainers();
|
||||
assert !list.contains(objectFactory.createContainerMetadata("shouldntexist"));
|
||||
List<C> list = context.getApi().listContainers();
|
||||
assert !list.contains(new ContainerMetadata("shouldntexist"));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
/**
|
||||
*
|
||||
* 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.blobstore.integration.internal;
|
||||
|
||||
import org.jclouds.blobstore.BlobStore;
|
||||
import org.jclouds.blobstore.BlobStoreContext;
|
||||
import org.jclouds.blobstore.domain.Blob;
|
||||
import org.jclouds.blobstore.domain.BlobMetadata;
|
||||
import org.jclouds.blobstore.domain.ContainerMetadata;
|
||||
import org.testng.ITestContext;
|
||||
|
||||
import com.google.inject.Module;
|
||||
|
||||
public abstract class BaseTestInitializer<S extends BlobStore<C, M, B>, C extends ContainerMetadata, M extends BlobMetadata, B extends Blob<M>> {
|
||||
|
||||
public BlobStoreContext<S, C, M, B> init(Module configurationModule, ITestContext testContext)
|
||||
throws Exception {
|
||||
String endpoint = System.getProperty("jclouds.test.endpoint");
|
||||
String app = System.getProperty("jclouds.test.app");
|
||||
String account = System.getProperty("jclouds.test.user");
|
||||
String key = System.getProperty("jclouds.test.key");
|
||||
if (endpoint != null)
|
||||
testContext.setAttribute("jclouds.test.endpoint", endpoint);
|
||||
if (app != null)
|
||||
testContext.setAttribute("jclouds.test.app", app);
|
||||
if (account != null)
|
||||
testContext.setAttribute("jclouds.test.user", account);
|
||||
if (key != null)
|
||||
testContext.setAttribute("jclouds.test.key", key);
|
||||
if (account != null) {
|
||||
return createLiveContext(configurationModule, endpoint, app, account, key);
|
||||
} else {
|
||||
return createStubContext();
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract BlobStoreContext<S, C, M, B> createStubContext();
|
||||
|
||||
protected abstract BlobStoreContext<S, C, M, B> createLiveContext(Module configurationModule,
|
||||
String url, String app, String account, String key);
|
||||
}
|
|
@ -46,6 +46,8 @@ import java.util.concurrent.Future;
|
|||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Provider;
|
||||
import javax.ws.rs.core.HttpHeaders;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
|
@ -82,10 +84,22 @@ import com.google.inject.internal.Nullable;
|
|||
* @author Adrian Cole
|
||||
* @author James Murty
|
||||
*/
|
||||
public abstract class StubBlobStore<C extends ContainerMetadata, M extends BlobMetadata, B extends Blob<M>>
|
||||
public class StubBlobStore<C extends ContainerMetadata, M extends BlobMetadata, B extends Blob<M>>
|
||||
implements BlobStore<C, M, B> {
|
||||
|
||||
protected DateService dateService = new DateService();
|
||||
protected final DateService dateService;
|
||||
private final Map<String, Map<String, B>> containerToBlobs;
|
||||
protected final Provider<C> containerMetaProvider;
|
||||
protected final Provider<B> blobProvider;
|
||||
|
||||
@Inject
|
||||
protected StubBlobStore(Map<String, Map<String, B>> containerToBlobs, DateService dateService,
|
||||
Provider<C> containerMetaProvider, Provider<B> blobProvider) {
|
||||
this.dateService = dateService;
|
||||
this.containerToBlobs = containerToBlobs;
|
||||
this.containerMetaProvider = containerMetaProvider;
|
||||
this.blobProvider = blobProvider;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws java.io.IOException
|
||||
|
@ -119,10 +133,9 @@ public abstract class StubBlobStore<C extends ContainerMetadata, M extends BlobM
|
|||
throw new KeyNotFoundException(bucketName, key);
|
||||
|
||||
B object = realContents.get(key);
|
||||
|
||||
B returnVal = createBlob(copy(object.getMetadata()), object.getData());
|
||||
|
||||
returnVal.setData(new ByteArrayInputStream((byte[]) returnVal.getData()));
|
||||
B returnVal = blobProvider.get();
|
||||
returnVal.setMetadata(copy(object.getMetadata()));
|
||||
returnVal.setData(new ByteArrayInputStream((byte[]) object.getData()));
|
||||
return returnVal;
|
||||
}
|
||||
};
|
||||
|
@ -198,7 +211,6 @@ public abstract class StubBlobStore<C extends ContainerMetadata, M extends BlobM
|
|||
}
|
||||
|
||||
public Future<Boolean> deleteContainer(final String container) {
|
||||
new Exception().printStackTrace();
|
||||
return new FutureBase<Boolean>() {
|
||||
public Boolean get() throws InterruptedException, ExecutionException {
|
||||
if (getContainerToBlobs().containsKey(container)) {
|
||||
|
@ -239,18 +251,14 @@ public abstract class StubBlobStore<C extends ContainerMetadata, M extends BlobM
|
|||
return Lists.newArrayList(Iterables.transform(getContainerToBlobs().keySet(),
|
||||
new Function<String, C>() {
|
||||
public C apply(String name) {
|
||||
return createContainerMetadata(name);
|
||||
C cmd = containerMetaProvider.get();
|
||||
cmd.setName(name);
|
||||
return cmd;
|
||||
}
|
||||
|
||||
}));
|
||||
}
|
||||
|
||||
protected abstract C createContainerMetadata(String name);
|
||||
|
||||
protected abstract B createBlob(String name);
|
||||
|
||||
protected abstract B createBlob(M metadata);
|
||||
|
||||
public Future<Boolean> createContainer(final String name) {
|
||||
return new FutureBase<Boolean>() {
|
||||
public Boolean get() throws InterruptedException, ExecutionException {
|
||||
|
@ -378,7 +386,10 @@ public abstract class StubBlobStore<C extends ContainerMetadata, M extends BlobM
|
|||
final byte[] eTag = HttpUtils.md5(data);
|
||||
newMd.setETag(eTag);
|
||||
newMd.setContentType(object.getMetadata().getContentType());
|
||||
B blob = createBlob(newMd, data);
|
||||
|
||||
B blob = blobProvider.get();
|
||||
blob.setMetadata(newMd);
|
||||
blob.setData(data);
|
||||
container.put(object.getKey(), blob);
|
||||
|
||||
// Set HTTP headers to match metadata
|
||||
|
@ -402,12 +413,6 @@ public abstract class StubBlobStore<C extends ContainerMetadata, M extends BlobM
|
|||
|
||||
}
|
||||
|
||||
private B createBlob(M newMd, Object data) {
|
||||
B blob = createBlob(newMd);
|
||||
blob.setData(data);
|
||||
return blob;
|
||||
}
|
||||
|
||||
public Future<B> getBlob(final String bucketName, final String key,
|
||||
@Nullable GetOptions nullableOptions) {
|
||||
final GetOptions options = (nullableOptions == null) ? new GetOptions() : nullableOptions;
|
||||
|
@ -447,7 +452,7 @@ public abstract class StubBlobStore<C extends ContainerMetadata, M extends BlobM
|
|||
"%1$s is after %2$s", object.getMetadata().getLastModified(),
|
||||
unmodifiedSince)));
|
||||
}
|
||||
B returnVal = createBlob(copy(object.getMetadata()), object.getData());
|
||||
B returnVal = copyBlob(object);
|
||||
|
||||
if (options.getRange() != null) {
|
||||
byte[] data = (byte[]) returnVal.getData();
|
||||
|
@ -485,11 +490,20 @@ public abstract class StubBlobStore<C extends ContainerMetadata, M extends BlobM
|
|||
try {
|
||||
return getBlob(container, key).get().getMetadata();
|
||||
} catch (Exception e) {
|
||||
Utils.<ContainerNotFoundException> rethrowIfRuntimeOrSameType(e);
|
||||
Utils.<KeyNotFoundException> rethrowIfRuntimeOrSameType(e);
|
||||
throw new RuntimeException(e);// TODO
|
||||
}
|
||||
}
|
||||
|
||||
abstract public Map<String, Map<String, B>> getContainerToBlobs();
|
||||
private B copyBlob(B object) {
|
||||
B returnVal = blobProvider.get();
|
||||
returnVal.setMetadata(copy(object.getMetadata()));
|
||||
returnVal.setData(object.getData());
|
||||
return returnVal;
|
||||
}
|
||||
|
||||
public Map<String, Map<String, B>> getContainerToBlobs() {
|
||||
return containerToBlobs;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,13 +35,14 @@ import java.net.URI;
|
|||
* @author Adrian Cole
|
||||
*
|
||||
*/
|
||||
public interface CloudContext<S> {
|
||||
public interface CloudContext<C> {
|
||||
|
||||
/**
|
||||
* low-level api to the cloud. Threadsafe implementations will return a singleton.
|
||||
*
|
||||
* @return a connection to the cloud
|
||||
*/
|
||||
S getApi();
|
||||
C getApi();
|
||||
|
||||
URI getEndPoint();
|
||||
|
||||
|
|
|
@ -52,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.rest.config.JaxrsModule;
|
||||
import org.jclouds.util.Jsr330;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
|
@ -61,7 +62,10 @@ 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.Key;
|
||||
import com.google.inject.Module;
|
||||
import com.google.inject.TypeLiteral;
|
||||
import com.google.inject.util.Types;
|
||||
|
||||
/**
|
||||
* Creates {@link CloudContext} or {@link Injector} instances based on the most commonly requested
|
||||
|
@ -76,118 +80,118 @@ import com.google.inject.Module;
|
|||
* @author Adrian Cole, Andrew Newdigate
|
||||
* @see CloudContext
|
||||
*/
|
||||
public abstract class CloudContextBuilder<X extends CloudContext<?>> {
|
||||
public abstract class CloudContextBuilder<C> {
|
||||
|
||||
protected final Properties properties;
|
||||
private final List<Module> modules = new ArrayList<Module>(3);
|
||||
protected final List<Module> modules = new ArrayList<Module>(3);
|
||||
protected final TypeLiteral<C> connectionType;
|
||||
|
||||
protected CloudContextBuilder(Properties properties) {
|
||||
protected CloudContextBuilder(TypeLiteral<C> connectionTypeLiteral, Properties properties) {
|
||||
this.connectionType = connectionTypeLiteral;
|
||||
this.properties = properties;
|
||||
}
|
||||
|
||||
public CloudContextBuilder<X> withSaxDebug() {
|
||||
public CloudContextBuilder<C> withSaxDebug() {
|
||||
properties.setProperty(PROPERTY_SAX_DEBUG, "true");
|
||||
return this;
|
||||
}
|
||||
|
||||
public CloudContextBuilder<X> withJsonDebug() {
|
||||
public CloudContextBuilder<C> withJsonDebug() {
|
||||
properties.setProperty(PROPERTY_JSON_DEBUG, "true");
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* allow mismatches between the certificate and the hostname of ssl requests.
|
||||
*/
|
||||
public CloudContextBuilder<X> relaxSSLHostname() {
|
||||
public CloudContextBuilder<C> relaxSSLHostname() {
|
||||
properties.setProperty(PROPERTY_HTTP_RELAX_HOSTNAME, "true");
|
||||
return this;
|
||||
}
|
||||
|
||||
public CloudContextBuilder<X> withHttpMaxRetries(int httpMaxRetries) {
|
||||
public CloudContextBuilder<C> withHttpMaxRetries(int httpMaxRetries) {
|
||||
properties.setProperty(PROPERTY_HTTP_MAX_RETRIES, Integer.toString(httpMaxRetries));
|
||||
return this;
|
||||
}
|
||||
|
||||
public CloudContextBuilder<X> withHttpMaxRedirects(int httpMaxRedirects) {
|
||||
public CloudContextBuilder<C> withHttpMaxRedirects(int httpMaxRedirects) {
|
||||
properties.setProperty(PROPERTY_HTTP_MAX_REDIRECTS, Integer.toString(httpMaxRedirects));
|
||||
return this;
|
||||
}
|
||||
|
||||
public CloudContextBuilder<X> withExecutorService(ExecutorService service) {
|
||||
public CloudContextBuilder<C> withExecutorService(ExecutorService service) {
|
||||
modules.add(new ExecutorServiceModule(service));
|
||||
return this;
|
||||
}
|
||||
|
||||
public CloudContextBuilder<X> withPoolMaxConnectionReuse(int poolMaxConnectionReuse) {
|
||||
public CloudContextBuilder<C> 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) {
|
||||
public abstract CloudContextBuilder<C> withEndpoint(URI endpoint);
|
||||
|
||||
public CloudContextBuilder<C> withPoolMaxSessionFailures(int poolMaxSessionFailures) {
|
||||
properties.setProperty(PROPERTY_POOL_MAX_SESSION_FAILURES, Integer
|
||||
.toString(poolMaxSessionFailures));
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
public CloudContextBuilder<X> withPoolRequestInvokerThreads(int poolRequestInvokerThreads) {
|
||||
public CloudContextBuilder<C> withPoolRequestInvokerThreads(int poolRequestInvokerThreads) {
|
||||
properties.setProperty(PROPERTY_POOL_REQUEST_INVOKER_THREADS, Integer
|
||||
.toString(poolRequestInvokerThreads));
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
public CloudContextBuilder<X> withPoolIoWorkerThreads(int poolIoWorkerThreads) {
|
||||
public CloudContextBuilder<C> withPoolIoWorkerThreads(int poolIoWorkerThreads) {
|
||||
properties
|
||||
.setProperty(PROPERTY_POOL_IO_WORKER_THREADS, Integer.toString(poolIoWorkerThreads));
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
public CloudContextBuilder<X> withPoolMaxConnections(int poolMaxConnections) {
|
||||
public CloudContextBuilder<C> withPoolMaxConnections(int poolMaxConnections) {
|
||||
properties.setProperty(PROPERTY_POOL_MAX_CONNECTIONS, Integer.toString(poolMaxConnections));
|
||||
return this;
|
||||
}
|
||||
|
||||
public CloudContextBuilder<X> withModule(Module module) {
|
||||
public CloudContextBuilder<C> withModule(Module module) {
|
||||
modules.add(module);
|
||||
return this;
|
||||
}
|
||||
|
||||
public CloudContextBuilder<X> withModules(Module... modules) {
|
||||
public CloudContextBuilder<C> withModules(Module... modules) {
|
||||
this.modules.addAll(Arrays.asList(modules));
|
||||
return this;
|
||||
}
|
||||
|
||||
public Injector buildInjector() {
|
||||
|
||||
addLoggingModuleIfNotPresent(modules);
|
||||
|
||||
addContextModule(modules);
|
||||
addConnectionModuleIfNotPresent(modules);
|
||||
|
||||
addLoggingModuleIfNotPresent(modules);
|
||||
addHttpModuleIfNeededAndNotPresent(modules);
|
||||
|
||||
ifHttpConfigureRestOtherwiseGuiceClientFactory(modules);
|
||||
addExecutorServiceIfNotPresent(modules);
|
||||
|
||||
modules.add(new AbstractModule() {
|
||||
@Override
|
||||
protected void configure() {
|
||||
Jsr330.bindProperties(binder(), checkNotNull(properties, "properties"));
|
||||
}
|
||||
});
|
||||
addContextModule(modules);
|
||||
|
||||
return Guice.createInjector(modules);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
protected void addLoggingModuleIfNotPresent(final List<Module> modules) {
|
||||
if (!Iterables.any(modules, Predicates.instanceOf(LoggingModule.class)))
|
||||
modules.add(new JDKLoggingModule());
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
protected void addHttpModuleIfNeededAndNotPresent(final List<Module> modules) {
|
||||
if (Iterables.any(modules, new Predicate<Module>() {
|
||||
public boolean apply(Module input) {
|
||||
|
@ -203,7 +207,37 @@ public abstract class CloudContextBuilder<X extends CloudContext<?>> {
|
|||
modules.add(new JavaUrlHttpCommandExecutorServiceModule());
|
||||
}
|
||||
|
||||
public static void addExecutorServiceIfNotPresent(final List<Module> modules) {
|
||||
@VisibleForTesting
|
||||
protected abstract void addContextModule(List<Module> modules);
|
||||
|
||||
@VisibleForTesting
|
||||
protected void ifHttpConfigureRestOtherwiseGuiceClientFactory(final List<Module> modules) {
|
||||
if (Iterables.any(modules, new Predicate<Module>() {
|
||||
public boolean apply(Module input) {
|
||||
return input.getClass().isAnnotationPresent(RequiresHttp.class);
|
||||
}
|
||||
|
||||
})) {
|
||||
modules.add(new JaxrsModule());
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
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 abstract void addConnectionModule(final List<Module> modules);
|
||||
|
||||
@VisibleForTesting
|
||||
protected void addExecutorServiceIfNotPresent(final List<Module> modules) {
|
||||
if (!Iterables.any(modules, new Predicate<Module>() {
|
||||
public boolean apply(Module input) {
|
||||
return input.getClass().isAnnotationPresent(ConfiguresExecutorService.class);
|
||||
|
@ -223,28 +257,18 @@ public abstract class CloudContextBuilder<X extends CloudContext<?>> {
|
|||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
})) {
|
||||
addApiModule(modules);
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public Properties getProperties() {
|
||||
return properties;
|
||||
}
|
||||
|
||||
public abstract X buildContext();
|
||||
|
||||
public abstract void authenticate(String id, String secret);
|
||||
|
||||
protected abstract void addContextModule(List<Module> modules);
|
||||
|
||||
protected abstract void addApiModule(List<Module> modules);
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public CloudContext<C> buildContext() {
|
||||
Injector injector = buildInjector();
|
||||
return (CloudContext<C>) injector.getInstance(Key.get(Types.newParameterizedType(
|
||||
CloudContext.class, connectionType.getType())));
|
||||
// return (CloudContext<C>) this.buildInjector().getInstance(
|
||||
// Key.get(new TypeLiteral<CloudContext<?>>() {
|
||||
// }));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,48 +21,36 @@
|
|||
* under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
package org.jclouds.rackspace.cloudservers.internal;
|
||||
package org.jclouds.cloud.internal;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
import org.jclouds.cloud.CloudContext;
|
||||
import org.jclouds.lifecycle.Closer;
|
||||
import org.jclouds.logging.Logger;
|
||||
import org.jclouds.rackspace.Authentication;
|
||||
import org.jclouds.rackspace.cloudservers.CloudServersConnection;
|
||||
import org.jclouds.rackspace.cloudservers.CloudServersContext;
|
||||
import org.jclouds.rackspace.reference.RackspaceConstants;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import com.google.inject.Injector;
|
||||
import javax.inject.Named;
|
||||
|
||||
/**
|
||||
* Uses a Guice Injector to configure the objects served by CloudServersContext methods.
|
||||
*
|
||||
* @author Adrian Cole
|
||||
* @see Injector
|
||||
*/
|
||||
public class GuiceCloudServersContext implements CloudServersContext {
|
||||
public class CloudContextImpl<C> implements CloudContext<C> {
|
||||
|
||||
@Resource
|
||||
private Logger logger = Logger.NULL;
|
||||
private final Injector injector;
|
||||
private final C defaultApi;
|
||||
private final Closer closer;
|
||||
private final URI endPoint;
|
||||
private final String account;
|
||||
|
||||
@Inject
|
||||
private GuiceCloudServersContext(Injector injector, Closer closer,@Authentication URI endPoint,
|
||||
@Named(RackspaceConstants.PROPERTY_RACKSPACE_USER) String account) {
|
||||
this.injector = injector;
|
||||
|
||||
public CloudContextImpl(Closer closer, C defaultApi, URI endPoint, String account) {
|
||||
this.defaultApi = defaultApi;
|
||||
this.closer = closer;
|
||||
this.endPoint = endPoint;
|
||||
this.account = account;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
|
@ -76,13 +64,12 @@ public class GuiceCloudServersContext implements CloudServersContext {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
public String getAccount() {
|
||||
return account;
|
||||
}
|
||||
|
||||
public CloudServersConnection getApi() {
|
||||
return injector.getInstance(CloudServersConnection.class);
|
||||
public C getApi() {
|
||||
return defaultApi;
|
||||
}
|
||||
|
||||
public URI getEndPoint() {
|
|
@ -69,7 +69,7 @@ public class RestClientProxy<T> implements InvocationHandler {
|
|||
@SuppressWarnings("unchecked")
|
||||
@Inject
|
||||
public RestClientProxy(TransformingHttpCommand.Factory factory,
|
||||
JaxrsAnnotationProcessor<T> util, TypeLiteral<T> typeLiteral) {
|
||||
JaxrsAnnotationProcessor<T> util, TypeLiteral<T> typeLiteral) {
|
||||
this.util = util;
|
||||
this.declaring = (Class<T>) typeLiteral.getRawType();
|
||||
this.commandFactory = factory;
|
||||
|
|
|
@ -39,6 +39,8 @@ import org.apache.commons.io.IOUtils;
|
|||
import org.jclouds.http.HttpResponse;
|
||||
import org.jclouds.logging.Logger;
|
||||
|
||||
import com.google.common.collect.ComputationException;
|
||||
|
||||
/**
|
||||
* // TODO: Adrian: Document this!
|
||||
*
|
||||
|
@ -126,7 +128,7 @@ public class Utils {
|
|||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <E extends Exception> void rethrowIfRuntimeOrSameType(Exception e) throws E {
|
||||
if (e instanceof ExecutionException) {
|
||||
if (e instanceof ExecutionException || e instanceof ComputationException) {
|
||||
Throwable nested = e.getCause();
|
||||
if (nested instanceof Error)
|
||||
throw (Error) nested;
|
||||
|
|
|
@ -41,9 +41,10 @@ import org.testng.annotations.Test;
|
|||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Binder;
|
||||
import com.google.inject.Module;
|
||||
import com.google.inject.TypeLiteral;
|
||||
|
||||
/**
|
||||
* Tests behavior of modules configured in CloudContextBuilder
|
||||
* Tests behavior of modules configured in CloudContextBuilder<String>
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
|
@ -78,12 +79,17 @@ public class CloudContextBuilderTest {
|
|||
return URI.create("http://localhost");
|
||||
}
|
||||
|
||||
public <T> T getApi(Class<T> clazz) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class TestCloudContextBuilder extends CloudContextBuilder<TestCloudContext> {
|
||||
class TestCloudContextBuilder extends CloudContextBuilder<String> {
|
||||
|
||||
protected TestCloudContextBuilder(Properties properties) {
|
||||
super(properties);
|
||||
super(new TypeLiteral<String>() {
|
||||
}, properties);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -92,28 +98,18 @@ public class CloudContextBuilderTest {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void addApiModule(List<Module> modules) {
|
||||
modules.add(new Module() {
|
||||
public void configure(Binder arg0) {
|
||||
}
|
||||
});
|
||||
public CloudContextBuilder<String> withEndpoint(URI endpoint) {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addContextModule(List<Module> modules) {
|
||||
modules.add(new Module() {
|
||||
public void configure(Binder arg0) {
|
||||
}
|
||||
});
|
||||
// ignored as we add it directly above without use of injection
|
||||
}
|
||||
|
||||
@Override
|
||||
public void authenticate(String id, String secret) {
|
||||
}
|
||||
protected void addConnectionModule(List<Module> modules) {
|
||||
|
||||
@Override
|
||||
public CloudContextBuilder<TestCloudContext> withEndpoint(URI endpoint) {
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -185,8 +181,6 @@ public class CloudContextBuilderTest {
|
|||
}
|
||||
|
||||
public void testBuilder() {
|
||||
String id = "awsAccessKeyId";
|
||||
String secret = "awsSecretAccessKey";
|
||||
int httpMaxRetries = 9875;
|
||||
int poolIoWorkerThreads = 2727;
|
||||
int poolMaxConnectionReuse = 3932;
|
||||
|
@ -207,7 +201,6 @@ public class CloudContextBuilderTest {
|
|||
}
|
||||
};
|
||||
TestCloudContextBuilder builder = new TestCloudContextBuilder(new Properties());
|
||||
builder.authenticate(id, secret);
|
||||
builder.withHttpMaxRetries(httpMaxRetries);
|
||||
builder.withModule(module1);
|
||||
builder.withModules(module2);
|
||||
|
|
|
@ -29,17 +29,19 @@ import java.util.List;
|
|||
import java.util.Properties;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import javax.inject.Singleton;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.ws.rs.core.HttpHeaders;
|
||||
|
||||
import org.jclouds.cloud.CloudContext;
|
||||
import org.jclouds.cloud.CloudContextBuilder;
|
||||
import org.jclouds.cloud.ConfiguresCloudConnection;
|
||||
import org.jclouds.cloud.internal.CloudContextImpl;
|
||||
import org.jclouds.lifecycle.Closer;
|
||||
import org.jclouds.logging.jdk.config.JDKLoggingModule;
|
||||
import org.jclouds.rest.RestClientFactory;
|
||||
import org.jclouds.rest.JaxrsAnnotationProcessorTest.Localhost;
|
||||
import org.jclouds.rest.config.JaxrsModule;
|
||||
import org.jclouds.util.Jsr330;
|
||||
import org.jclouds.util.Utils;
|
||||
import org.mortbay.jetty.Handler;
|
||||
|
@ -51,22 +53,64 @@ import org.testng.annotations.BeforeTest;
|
|||
import org.testng.annotations.Optional;
|
||||
import org.testng.annotations.Parameters;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Injector;
|
||||
import com.google.inject.Module;
|
||||
import com.google.inject.Provides;
|
||||
import com.google.inject.TypeLiteral;
|
||||
|
||||
public abstract class BaseJettyTest {
|
||||
|
||||
@ConfiguresCloudConnection
|
||||
@RequiresHttp
|
||||
private final class RestIntegrationTestConnectionModule extends AbstractModule {
|
||||
@Override
|
||||
protected void configure() {
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@Provides
|
||||
@Singleton
|
||||
public IntegrationTestClient provideConnection(RestClientFactory factory) {
|
||||
return factory.create(IntegrationTestClient.class);
|
||||
}
|
||||
}
|
||||
|
||||
private final class JettyContextModule extends AbstractModule {
|
||||
private final Properties properties;
|
||||
private final int testPort;
|
||||
|
||||
private JettyContextModule(Properties properties, int testPort) {
|
||||
this.properties = properties;
|
||||
this.testPort = testPort;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
Jsr330.bindProperties(binder(), properties);
|
||||
bind(URI.class).annotatedWith(Localhost.class).toInstance(
|
||||
URI.create("http://localhost:" + testPort));
|
||||
}
|
||||
|
||||
@SuppressWarnings( { "unchecked", "unused" })
|
||||
@Provides
|
||||
@Singleton
|
||||
CloudContext<IntegrationTestClient> provideContext(Closer closer,
|
||||
IntegrationTestClient client, @Localhost URI endPoint) {
|
||||
return new CloudContextImpl(closer, client, endPoint, System.getProperty("user.name"));
|
||||
}
|
||||
}
|
||||
|
||||
protected static final String XML = "<foo><bar>whoppers</bar></foo>";
|
||||
protected static final String XML2 = "<foo><bar>chubbs</bar></foo>";
|
||||
|
||||
protected Server server = null;
|
||||
protected IntegrationTestClient client;
|
||||
protected Injector injector;
|
||||
private Closer closer;
|
||||
private AtomicInteger cycle = new AtomicInteger(0);
|
||||
private Server server2;
|
||||
private CloudContext<IntegrationTestClient> context;
|
||||
|
||||
@BeforeTest
|
||||
@Parameters( { "test-jetty-port" })
|
||||
|
@ -141,27 +185,32 @@ public abstract class BaseJettyTest {
|
|||
|
||||
final Properties properties = new Properties();
|
||||
addConnectionProperties(properties);
|
||||
context = new CloudContextBuilder<IntegrationTestClient>(
|
||||
new TypeLiteral<IntegrationTestClient>() {
|
||||
}, properties) {
|
||||
|
||||
List<Module> modules = Lists.newArrayList(new AbstractModule() {
|
||||
@Override
|
||||
protected void configure() {
|
||||
Jsr330.bindProperties(binder(), properties);
|
||||
bind(URI.class).annotatedWith(Localhost.class).toInstance(
|
||||
URI.create("http://localhost:" + testPort));
|
||||
public CloudContextBuilder<IntegrationTestClient> withEndpoint(URI endpoint) {
|
||||
return this;
|
||||
}
|
||||
|
||||
}, new JDKLoggingModule(), new JaxrsModule(), createClientModule());
|
||||
CloudContextBuilder.addExecutorServiceIfNotPresent(modules);
|
||||
injector = Guice.createInjector(modules);
|
||||
RestClientFactory factory = injector.getInstance(RestClientFactory.class);
|
||||
client = factory.create(IntegrationTestClient.class);
|
||||
closer = injector.getInstance(Closer.class);
|
||||
@Override
|
||||
protected void addContextModule(List<Module> modules) {
|
||||
modules.add(new JettyContextModule(properties, testPort));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addConnectionModule(List<Module> modules) {
|
||||
modules.add(new RestIntegrationTestConnectionModule());
|
||||
}
|
||||
}.withModules(createClientModule()).buildContext();
|
||||
client = context.getApi();
|
||||
assert client != null;
|
||||
}
|
||||
|
||||
@AfterTest
|
||||
public void tearDownJetty() throws Exception {
|
||||
closer.close();
|
||||
context.close();
|
||||
server2.stop();
|
||||
server.stop();
|
||||
}
|
||||
|
|
|
@ -54,7 +54,7 @@ public class BindLoggersAnnotatedWithResourceTest {
|
|||
private Logger logger = Logger.NULL;
|
||||
}
|
||||
|
||||
public static class B {
|
||||
private static class B {
|
||||
@Resource
|
||||
private Logger logger = Logger.NULL;
|
||||
}
|
||||
|
|
|
@ -25,14 +25,11 @@ package org.jclouds.gae;
|
|||
|
||||
import java.io.File;
|
||||
import java.net.MalformedURLException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import org.jclouds.concurrent.SingleThreadCompatible;
|
||||
import org.jclouds.gae.config.GaeHttpCommandExecutorServiceModule;
|
||||
import org.jclouds.http.BaseHttpCommandExecutorServiceTest;
|
||||
import org.testng.annotations.BeforeMethod;
|
||||
|
@ -64,10 +61,10 @@ public class GaeHttpCommandExecutorServiceIntegrationTest extends
|
|||
|
||||
@BeforeTest
|
||||
void validateExecutor() {
|
||||
ExecutorService executorService = injector.getInstance(ExecutorService.class);
|
||||
assert executorService.getClass().isAnnotationPresent(SingleThreadCompatible.class) : Arrays
|
||||
.asList(executorService.getClass().getAnnotations()).toString()
|
||||
+ executorService.getClass().getName();
|
||||
// ExecutorService executorService = injector.getInstance(ExecutorService.class);
|
||||
// assert executorService.getClass().isAnnotationPresent(SingleThreadCompatible.class) : Arrays
|
||||
// .asList(executorService.getClass().getAnnotations()).toString()
|
||||
// + executorService.getClass().getName();
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -23,12 +23,9 @@
|
|||
*/
|
||||
package org.jclouds.http.httpnio.pool;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
import org.jclouds.http.BackoffLimitedRetryJavaIntegrationTest;
|
||||
import org.jclouds.http.handlers.BackoffLimitedRetryHandler;
|
||||
import org.jclouds.http.httpnio.config.NioTransformingHttpCommandExecutorServiceModule;
|
||||
import org.jclouds.http.pool.PoolConstants;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.inject.Module;
|
||||
|
@ -45,14 +42,6 @@ import com.google.inject.Module;
|
|||
public class NioBackoffLimitedRetryJavaIntegrationTest extends
|
||||
BackoffLimitedRetryJavaIntegrationTest {
|
||||
|
||||
protected void addConnectionProperties(Properties properties) {
|
||||
properties.setProperty(PoolConstants.PROPERTY_POOL_MAX_CONNECTION_REUSE, "75");
|
||||
properties.setProperty(PoolConstants.PROPERTY_POOL_MAX_SESSION_FAILURES, "2");
|
||||
properties.setProperty(PoolConstants.PROPERTY_POOL_REQUEST_INVOKER_THREADS, "1");
|
||||
properties.setProperty(PoolConstants.PROPERTY_POOL_IO_WORKER_THREADS, "2");
|
||||
properties.setProperty(PoolConstants.PROPERTY_POOL_MAX_CONNECTIONS, "12");
|
||||
}
|
||||
|
||||
protected Module createClientModule() {
|
||||
return new NioTransformingHttpCommandExecutorServiceModule();
|
||||
}
|
||||
|
|
|
@ -25,35 +25,63 @@ package org.jclouds.nirvanix.sdn;
|
|||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.jclouds.cloud.CloudContext;
|
||||
import org.jclouds.cloud.CloudContextBuilder;
|
||||
import org.jclouds.nirvanix.sdn.config.RestSDNAuthenticationModule;
|
||||
import org.jclouds.nirvanix.sdn.reference.SDNConstants;
|
||||
|
||||
import com.google.inject.Module;
|
||||
import com.google.inject.TypeLiteral;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public abstract class SDNContextBuilder<X extends CloudContext<?>> extends CloudContextBuilder<X> {
|
||||
public abstract class SDNContextBuilder<C> extends CloudContextBuilder<C> {
|
||||
|
||||
public SDNContextBuilder(Properties props) {
|
||||
super(props);
|
||||
properties.setProperty(SDNConstants.PROPERTY_SDN_ENDPOINT, "http://services.nirvanix.com/ws");
|
||||
public SDNContextBuilder(TypeLiteral<C> defaultApiClass, String apikey, String id, String secret) {
|
||||
this(defaultApiClass, new Properties());
|
||||
authenticate(this, apikey, id, secret);
|
||||
}
|
||||
|
||||
public void authenticate(String id, String secret) {
|
||||
checkNotNull(properties.getProperty(SDNConstants.PROPERTY_SDN_APPKEY));
|
||||
properties.setProperty(SDNConstants.PROPERTY_SDN_USERNAME, checkNotNull(id, "user"));
|
||||
properties.setProperty(SDNConstants.PROPERTY_SDN_PASSWORD, checkNotNull(secret, "key"));
|
||||
public SDNContextBuilder(TypeLiteral<C> defaultApiClass, Properties props) {
|
||||
super(defaultApiClass, props);
|
||||
initialize(this);
|
||||
}
|
||||
|
||||
protected void addApiModule(List<Module> modules) {
|
||||
modules.add(new RestSDNAuthenticationModule());
|
||||
@Override
|
||||
protected void addConnectionModule(List<Module> modules) {
|
||||
addAuthenticationModule(this);
|
||||
}
|
||||
|
||||
public static <C> void authenticate(CloudContextBuilder<C> builder, String appkey, String id,
|
||||
String secret) {
|
||||
builder.getProperties().setProperty(SDNConstants.PROPERTY_SDN_APPKEY, checkNotNull(appkey, "appkey"));
|
||||
builder.getProperties().setProperty(SDNConstants.PROPERTY_SDN_USERNAME, checkNotNull(id, "user"));
|
||||
builder.getProperties().setProperty(SDNConstants.PROPERTY_SDN_PASSWORD, checkNotNull(secret, "key"));
|
||||
}
|
||||
|
||||
public static <C> void initialize(CloudContextBuilder<C> builder) {
|
||||
builder.getProperties().setProperty(SDNConstants.PROPERTY_SDN_ENDPOINT, "http://services.nirvanix.com/ws");
|
||||
}
|
||||
|
||||
public static <C> void addAuthenticationModule(CloudContextBuilder<C> builder) {
|
||||
builder.withModule(new RestSDNAuthenticationModule());
|
||||
}
|
||||
|
||||
public static <C> CloudContextBuilder<C> withEndpoint(CloudContextBuilder<C> builder,
|
||||
URI endpoint) {
|
||||
builder.getProperties().setProperty(SDNConstants.PROPERTY_SDN_ENDPOINT,
|
||||
checkNotNull(endpoint, "endpoint").toString());
|
||||
return builder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SDNContextBuilder<C> withEndpoint(URI endpoint) {
|
||||
return (SDNContextBuilder<C>) withEndpoint(this, endpoint);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@ import org.jclouds.blobstore.BlobStoreContext;
|
|||
import org.jclouds.blobstore.domain.Blob;
|
||||
import org.jclouds.blobstore.domain.BlobMetadata;
|
||||
import org.jclouds.cloud.CloudContext;
|
||||
import org.jclouds.rackspace.cloudfiles.domain.ContainerMetadata;
|
||||
|
||||
/**
|
||||
* Represents an authenticated context to Cloud Files.
|
||||
|
@ -38,6 +39,6 @@ import org.jclouds.cloud.CloudContext;
|
|||
*
|
||||
*/
|
||||
public interface CloudFilesContext extends
|
||||
BlobStoreContext<CloudFilesBlobStore, BlobMetadata, Blob<BlobMetadata>> {
|
||||
BlobStoreContext<CloudFilesBlobStore, ContainerMetadata, BlobMetadata, Blob<BlobMetadata>> {
|
||||
|
||||
}
|
|
@ -25,17 +25,24 @@ package org.jclouds.rackspace.cloudfiles;
|
|||
|
||||
import static org.jclouds.blobstore.reference.BlobStoreConstants.PROPERTY_USER_METADATA_PREFIX;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
|
||||
import org.jclouds.blobstore.BlobStoreContextBuilder;
|
||||
import org.jclouds.blobstore.domain.Blob;
|
||||
import org.jclouds.blobstore.domain.BlobMetadata;
|
||||
import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule;
|
||||
import org.jclouds.logging.jdk.config.JDKLoggingModule;
|
||||
import org.jclouds.rackspace.RackspaceContextBuilder;
|
||||
import org.jclouds.rackspace.cloudfiles.config.CloudFilesContextModule;
|
||||
import org.jclouds.rackspace.cloudfiles.config.RestCloudFilesBlobStoreModule;
|
||||
import org.jclouds.rackspace.cloudfiles.domain.ContainerMetadata;
|
||||
|
||||
import com.google.inject.Injector;
|
||||
import com.google.inject.Module;
|
||||
import com.google.inject.TypeLiteral;
|
||||
|
||||
/**
|
||||
* Creates {@link CloudFilesContext} or {@link Injector} instances based on the most commonly
|
||||
|
@ -50,34 +57,111 @@ import com.google.inject.Module;
|
|||
* @author Adrian Cole
|
||||
* @see CloudFilesContext
|
||||
*/
|
||||
public class CloudFilesContextBuilder extends RackspaceContextBuilder<CloudFilesContext> {
|
||||
public class CloudFilesContextBuilder
|
||||
extends
|
||||
BlobStoreContextBuilder<CloudFilesBlobStore, ContainerMetadata, BlobMetadata, Blob<BlobMetadata>> {
|
||||
|
||||
@Override
|
||||
public CloudFilesContext buildContext() {
|
||||
return this.buildInjector().getInstance(CloudFilesContext.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CloudFilesContextBuilder relaxSSLHostname() {
|
||||
return (CloudFilesContextBuilder) (CloudFilesContextBuilder) super.relaxSSLHostname();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CloudFilesContextBuilder withExecutorService(ExecutorService service) {
|
||||
return (CloudFilesContextBuilder) super.withExecutorService(service);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CloudFilesContextBuilder withHttpMaxRedirects(int httpMaxRedirects) {
|
||||
return (CloudFilesContextBuilder) super.withHttpMaxRedirects(httpMaxRedirects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CloudFilesContextBuilder withHttpMaxRetries(int httpMaxRetries) {
|
||||
return (CloudFilesContextBuilder) super.withHttpMaxRetries(httpMaxRetries);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CloudFilesContextBuilder withJsonDebug() {
|
||||
return (CloudFilesContextBuilder) super.withJsonDebug();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CloudFilesContextBuilder withModule(Module module) {
|
||||
return (CloudFilesContextBuilder) super.withModule(module);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CloudFilesContextBuilder withModules(Module... modules) {
|
||||
return (CloudFilesContextBuilder) super.withModules(modules);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CloudFilesContextBuilder withPoolIoWorkerThreads(int poolIoWorkerThreads) {
|
||||
return (CloudFilesContextBuilder) super.withPoolIoWorkerThreads(poolIoWorkerThreads);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CloudFilesContextBuilder withPoolMaxConnectionReuse(int poolMaxConnectionReuse) {
|
||||
return (CloudFilesContextBuilder) super.withPoolMaxConnectionReuse(poolMaxConnectionReuse);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CloudFilesContextBuilder withPoolMaxConnections(int poolMaxConnections) {
|
||||
return (CloudFilesContextBuilder) super.withPoolMaxConnections(poolMaxConnections);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CloudFilesContextBuilder withPoolMaxSessionFailures(int poolMaxSessionFailures) {
|
||||
return (CloudFilesContextBuilder) super.withPoolMaxSessionFailures(poolMaxSessionFailures);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CloudFilesContextBuilder withPoolRequestInvokerThreads(int poolRequestInvokerThreads) {
|
||||
return (CloudFilesContextBuilder) super
|
||||
.withPoolRequestInvokerThreads(poolRequestInvokerThreads);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CloudFilesContextBuilder withSaxDebug() {
|
||||
return (CloudFilesContextBuilder) super.withSaxDebug();
|
||||
}
|
||||
|
||||
public CloudFilesContextBuilder(Properties props) {
|
||||
super(props);
|
||||
}
|
||||
|
||||
public static CloudFilesContextBuilder newBuilder(String id, String secret) {
|
||||
Properties properties = new Properties();
|
||||
super(new TypeLiteral<CloudFilesBlobStore>() {
|
||||
}, new TypeLiteral<ContainerMetadata>() {
|
||||
}, new TypeLiteral<BlobMetadata>() {
|
||||
}, new TypeLiteral<Blob<BlobMetadata>>() {
|
||||
}, props);
|
||||
properties.setProperty(PROPERTY_USER_METADATA_PREFIX, "X-Object-Meta-");
|
||||
CloudFilesContextBuilder builder = new CloudFilesContextBuilder(properties);
|
||||
builder.authenticate(id, secret);
|
||||
return builder;
|
||||
RackspaceContextBuilder.initialize(this);
|
||||
}
|
||||
|
||||
public CloudFilesContextBuilder(String id, String secret) {
|
||||
this(new Properties());
|
||||
RackspaceContextBuilder.authenticate(this, id, secret);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addApiModule(List<Module> modules) {
|
||||
super.addApiModule(modules);
|
||||
protected void addConnectionModule(List<Module> modules) {
|
||||
modules.add(new RestCloudFilesBlobStoreModule());
|
||||
RackspaceContextBuilder.addAuthenticationModule(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addContextModule(List<Module> modules) {
|
||||
public void addContextModule(List<Module> modules) {
|
||||
modules.add(new CloudFilesContextModule());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CloudFilesContext buildContext() {
|
||||
return buildInjector().getInstance(CloudFilesContext.class);
|
||||
public CloudFilesContextBuilder withEndpoint(URI endpoint) {
|
||||
return (CloudFilesContextBuilder) (CloudFilesContextBuilder) RackspaceContextBuilder
|
||||
.withEndpoint(this, endpoint);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -44,15 +44,13 @@ import com.google.inject.Module;
|
|||
*/
|
||||
public class CloudFilesContextFactory {
|
||||
|
||||
public static CloudFilesContext createCloudFilesContext(String user, String key,
|
||||
Module... modules) {
|
||||
return CloudFilesContextBuilder.newBuilder(user, key).withModules(modules)
|
||||
.buildContext();
|
||||
public static CloudFilesContext createContext(String user, String key, Module... modules) {
|
||||
return new CloudFilesContextBuilder(user, key).withModules(modules).buildContext();
|
||||
}
|
||||
|
||||
public static CloudFilesContext createCloudFilesContext(URI endpoint, String user,
|
||||
String key, Module... modules) {
|
||||
return CloudFilesContextBuilder.newBuilder(user, key).withEndpoint(endpoint)
|
||||
.withModules(modules).buildContext();
|
||||
public static CloudFilesContext createContext(URI endpoint, String user, String key,
|
||||
Module... modules) {
|
||||
return new CloudFilesContextBuilder(user, key).withEndpoint(endpoint).withModules(modules)
|
||||
.buildContext();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,53 +23,46 @@
|
|||
*/
|
||||
package org.jclouds.rackspace.cloudfiles.config;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Provider;
|
||||
|
||||
import org.jclouds.blobstore.BlobStoreContextImpl;
|
||||
import org.jclouds.blobstore.BlobMap.Factory;
|
||||
import org.jclouds.blobstore.domain.Blob;
|
||||
import org.jclouds.blobstore.domain.BlobMetadata;
|
||||
import org.jclouds.blobstore.functions.ParseBlobFromHeadersAndHttpContent.BlobFactory;
|
||||
import org.jclouds.blobstore.functions.ParseContentTypeFromHeaders.BlobMetadataFactory;
|
||||
import org.jclouds.cloud.ConfiguresCloudConnection;
|
||||
import org.jclouds.http.RequiresHttp;
|
||||
import org.jclouds.lifecycle.Closer;
|
||||
import org.jclouds.rackspace.CloudFiles;
|
||||
import org.jclouds.rackspace.cloudfiles.CloudFilesBlobStore;
|
||||
import org.jclouds.rackspace.cloudfiles.CloudFilesContext;
|
||||
import org.jclouds.rackspace.cloudfiles.internal.GuiceCloudFilesContext;
|
||||
import org.jclouds.rackspace.cloudfiles.internal.LiveCloudFilesInputStreamMap;
|
||||
import org.jclouds.rackspace.cloudfiles.internal.LiveCloudFilesObjectMap;
|
||||
import org.jclouds.rackspace.cloudfiles.domain.ContainerMetadata;
|
||||
import org.jclouds.rackspace.reference.RackspaceConstants;
|
||||
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.TypeLiteral;
|
||||
import com.google.inject.assistedinject.FactoryProvider;
|
||||
import com.google.inject.Scopes;
|
||||
|
||||
/**
|
||||
* Configures the Cloud Files connection, including logging and http transport.
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@ConfiguresCloudConnection
|
||||
@RequiresHttp
|
||||
public class CloudFilesContextModule extends AbstractModule {
|
||||
protected final TypeLiteral<BlobMetadataFactory<BlobMetadata>> objectMetadataFactoryLiteral = new TypeLiteral<BlobMetadataFactory<BlobMetadata>>() {
|
||||
};
|
||||
protected final TypeLiteral<BlobFactory<BlobMetadata, Blob<BlobMetadata>>> objectFactoryLiteral = new TypeLiteral<BlobFactory<BlobMetadata, Blob<BlobMetadata>>>() {
|
||||
};
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
this.requireBinding(CloudFilesBlobStore.class);
|
||||
bind(GuiceCloudFilesContext.CloudFilesObjectMapFactory.class).toProvider(
|
||||
FactoryProvider.newFactory(GuiceCloudFilesContext.CloudFilesObjectMapFactory.class,
|
||||
LiveCloudFilesObjectMap.class));
|
||||
bind(GuiceCloudFilesContext.CloudFilesInputStreamMapFactory.class).toProvider(
|
||||
FactoryProvider.newFactory(
|
||||
GuiceCloudFilesContext.CloudFilesInputStreamMapFactory.class,
|
||||
LiveCloudFilesInputStreamMap.class));
|
||||
bind(objectMetadataFactoryLiteral).toProvider(
|
||||
FactoryProvider.newFactory(objectMetadataFactoryLiteral,
|
||||
new TypeLiteral<BlobMetadata>() {
|
||||
}));
|
||||
bind(objectFactoryLiteral).toProvider(
|
||||
FactoryProvider.newFactory(objectFactoryLiteral,
|
||||
new TypeLiteral<Blob<BlobMetadata>>() {
|
||||
}));
|
||||
bind(CloudFilesContext.class).to(GuiceCloudFilesContext.class);
|
||||
bind(CloudFilesContext.class).to(CloudFilesContextImpl.class).in(Scopes.SINGLETON);
|
||||
}
|
||||
}
|
||||
|
||||
public static class CloudFilesContextImpl
|
||||
extends
|
||||
BlobStoreContextImpl<CloudFilesBlobStore, ContainerMetadata, BlobMetadata, Blob<BlobMetadata>>
|
||||
implements CloudFilesContext {
|
||||
@Inject
|
||||
CloudFilesContextImpl(Factory<BlobMetadata, Blob<BlobMetadata>> blobMapFactory,
|
||||
org.jclouds.blobstore.InputStreamMap.Factory<BlobMetadata> inputStreamMapFactory,
|
||||
Closer closer, Provider<Blob<BlobMetadata>> blobProvider,
|
||||
CloudFilesBlobStore defaultApi, @CloudFiles URI endPoint,
|
||||
@Named(RackspaceConstants.PROPERTY_RACKSPACE_USER) String account) {
|
||||
super(blobMapFactory, inputStreamMapFactory, closer, blobProvider, defaultApi, endPoint,
|
||||
account);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,22 +34,20 @@ import com.google.inject.AbstractModule;
|
|||
import com.google.inject.Provides;
|
||||
|
||||
/**
|
||||
* Configures the Cloud Files connection, including logging and http transport.
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@ConfiguresCloudConnection
|
||||
@RequiresHttp
|
||||
public class RestCloudFilesBlobStoreModule extends AbstractModule {
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
protected CloudFilesBlobStore provideConnection(RestClientFactory factory) {
|
||||
public CloudFilesBlobStore provideConnection(RestClientFactory factory) {
|
||||
return factory.create(CloudFilesBlobStore.class);
|
||||
}
|
||||
|
||||
}
|
|
@ -23,13 +23,14 @@
|
|||
*/
|
||||
package org.jclouds.rackspace.cloudfiles.functions;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Provider;
|
||||
|
||||
import org.jclouds.blobstore.domain.Blob;
|
||||
import org.jclouds.blobstore.domain.BlobMetadata;
|
||||
import org.jclouds.blobstore.functions.ParseBlobFromHeadersAndHttpContent;
|
||||
import org.jclouds.blobstore.functions.ParseSystemAndUserMetadataFromHeaders;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
/**
|
||||
* Parses response headers and creates a new Rackspace object from them and the HTTP content.
|
||||
*
|
||||
|
@ -39,9 +40,8 @@ import javax.inject.Inject;
|
|||
public class ParseObjectFromHeadersAndHttpContent extends
|
||||
ParseBlobFromHeadersAndHttpContent<BlobMetadata, Blob<BlobMetadata>> {
|
||||
@Inject
|
||||
public ParseObjectFromHeadersAndHttpContent(
|
||||
ParseObjectMetadataFromHeaders metadataParser,
|
||||
BlobFactory<BlobMetadata, Blob<BlobMetadata>> blobFactory) {
|
||||
public ParseObjectFromHeadersAndHttpContent(ParseObjectMetadataFromHeaders metadataParser,
|
||||
Provider<Blob<BlobMetadata>> blobFactory) {
|
||||
super(metadataParser, blobFactory);
|
||||
}
|
||||
}
|
|
@ -25,6 +25,10 @@ package org.jclouds.rackspace.cloudfiles.functions;
|
|||
|
||||
import static org.jclouds.blobstore.reference.BlobStoreConstants.PROPERTY_USER_METADATA_PREFIX;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Provider;
|
||||
|
||||
import org.jclouds.blobstore.domain.BlobMetadata;
|
||||
import org.jclouds.blobstore.functions.ParseSystemAndUserMetadataFromHeaders;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
|
@ -32,18 +36,17 @@ import org.jclouds.http.HttpUtils;
|
|||
import org.jclouds.util.DateService;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class ParseObjectMetadataFromHeaders extends ParseSystemAndUserMetadataFromHeaders<BlobMetadata> {
|
||||
public class ParseObjectMetadataFromHeaders extends
|
||||
ParseSystemAndUserMetadataFromHeaders<BlobMetadata> {
|
||||
|
||||
@Inject
|
||||
public ParseObjectMetadataFromHeaders(DateService dateParser,
|
||||
@Named(PROPERTY_USER_METADATA_PREFIX) String metadataPrefix,
|
||||
BlobMetadataFactory<BlobMetadata> metadataFactory) {
|
||||
Provider<BlobMetadata> metadataFactory) {
|
||||
super(dateParser, metadataPrefix, metadataFactory);
|
||||
}
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue