mirror of https://github.com/apache/jclouds.git
Issue 301: removed encryption service dependency from blob and added helper methods to blobstore.clj
This commit is contained in:
parent
ef496e7262
commit
31d2da3c6f
|
@ -27,7 +27,6 @@ import org.jclouds.atmosonline.saas.domain.SystemMetadata;
|
|||
import org.jclouds.atmosonline.saas.domain.UserMetadata;
|
||||
import org.jclouds.atmosonline.saas.domain.internal.AtmosObjectImpl;
|
||||
import org.jclouds.blobstore.config.BlobStoreObjectModule;
|
||||
import org.jclouds.encryption.EncryptionService;
|
||||
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Provides;
|
||||
|
@ -52,25 +51,22 @@ public class AtmosObjectModule extends AbstractModule {
|
|||
}
|
||||
|
||||
private static class AtmosObjectFactory implements AtmosObject.Factory {
|
||||
@Inject
|
||||
EncryptionService encryptionService;
|
||||
|
||||
@Inject
|
||||
Provider<MutableContentMetadata> metadataProvider;
|
||||
|
||||
public AtmosObject create(MutableContentMetadata contentMetadata) {
|
||||
return new AtmosObjectImpl(encryptionService, contentMetadata != null ? contentMetadata
|
||||
: metadataProvider.get());
|
||||
return new AtmosObjectImpl(contentMetadata != null ? contentMetadata : metadataProvider
|
||||
.get());
|
||||
}
|
||||
|
||||
public AtmosObject create(SystemMetadata systemMetadata, UserMetadata userMetadata) {
|
||||
return new AtmosObjectImpl(encryptionService, metadataProvider.get(), systemMetadata,
|
||||
userMetadata);
|
||||
return new AtmosObjectImpl(metadataProvider.get(), systemMetadata, userMetadata);
|
||||
}
|
||||
|
||||
public AtmosObject create(MutableContentMetadata contentMetadata,
|
||||
SystemMetadata systemMetadata, UserMetadata userMetadata) {
|
||||
return new AtmosObjectImpl(encryptionService, contentMetadata, systemMetadata,
|
||||
userMetadata);
|
||||
return new AtmosObjectImpl(contentMetadata, systemMetadata, userMetadata);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -26,7 +26,6 @@ import org.jclouds.atmosonline.saas.domain.AtmosObject;
|
|||
import org.jclouds.atmosonline.saas.domain.MutableContentMetadata;
|
||||
import org.jclouds.atmosonline.saas.domain.SystemMetadata;
|
||||
import org.jclouds.atmosonline.saas.domain.UserMetadata;
|
||||
import org.jclouds.encryption.EncryptionService;
|
||||
import org.jclouds.http.Payload;
|
||||
import org.jclouds.http.PayloadEnclosing;
|
||||
import org.jclouds.http.internal.PayloadEnclosingImpl;
|
||||
|
@ -57,10 +56,9 @@ public class AtmosObjectImpl extends PayloadEnclosingImpl implements AtmosObject
|
|||
private final SetPayloadPropertiesMutableContentMetadata contentMetadata;
|
||||
private Multimap<String, String> allHeaders = LinkedHashMultimap.create();
|
||||
|
||||
public AtmosObjectImpl(EncryptionService encryptionService,
|
||||
MutableContentMetadata contentMetadata, SystemMetadata systemMetadata,
|
||||
public AtmosObjectImpl(MutableContentMetadata contentMetadata, SystemMetadata systemMetadata,
|
||||
UserMetadata userMetadata) {
|
||||
super(encryptionService);
|
||||
super();
|
||||
this.contentMetadata = linkMetadataToThis(contentMetadata);
|
||||
this._contentMetadata = this.contentMetadata.getDelegate();
|
||||
this.systemMetadata = systemMetadata;
|
||||
|
@ -68,9 +66,8 @@ public class AtmosObjectImpl extends PayloadEnclosingImpl implements AtmosObject
|
|||
}
|
||||
|
||||
@Inject
|
||||
public AtmosObjectImpl(EncryptionService encryptionService,
|
||||
MutableContentMetadata contentMetadata) {
|
||||
this(encryptionService, contentMetadata, null, new UserMetadata());
|
||||
public AtmosObjectImpl(MutableContentMetadata contentMetadata) {
|
||||
this(contentMetadata, null, new UserMetadata());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -112,6 +112,7 @@ public class AtmosStorageClientLiveTest {
|
|||
|
||||
URI container1;
|
||||
URI container2;
|
||||
private BlobStoreContext context;
|
||||
|
||||
@BeforeGroups(groups = { "live" })
|
||||
public void setupClient() throws InterruptedException, ExecutionException, TimeoutException,
|
||||
|
@ -120,15 +121,14 @@ public class AtmosStorageClientLiveTest {
|
|||
"jclouds.test.identity");
|
||||
String credential = checkNotNull(System.getProperty("jclouds.test.credential"),
|
||||
"jclouds.test.credential");
|
||||
BlobStoreContext blobStoreContext = new BlobStoreContextFactory().createContext(
|
||||
"atmosonline", identity, credential, ImmutableSet
|
||||
.<Module> of(new Log4JLoggingModule()));
|
||||
RestContext<AtmosStorageClient, AtmosStorageAsyncClient> context = blobStoreContext
|
||||
context = new BlobStoreContextFactory().createContext("atmosonline", identity, credential,
|
||||
ImmutableSet.<Module> of(new Log4JLoggingModule()));
|
||||
RestContext<AtmosStorageClient, AtmosStorageAsyncClient> restContext = context
|
||||
.getProviderSpecificContext();
|
||||
connection = context.getApi();
|
||||
connection = restContext.getApi();
|
||||
for (DirectoryEntry entry : connection.listDirectories()) {
|
||||
if (entry.getObjectName().startsWith(containerPrefix)) {
|
||||
blobStoreContext.getBlobStore().deleteContainer(entry.getObjectName());
|
||||
context.getBlobStore().deleteContainer(entry.getObjectName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -226,7 +226,7 @@ public class AtmosStorageClientLiveTest {
|
|||
object.getContentMetadata().setName(name);
|
||||
object.setPayload(Payloads.newPayload(data));
|
||||
object.getContentMetadata().setContentLength(16l);
|
||||
object.generateMD5();
|
||||
context.utils().encryption().generateMD5BufferingIfNotRepeatable(object);
|
||||
object.getContentMetadata().setContentType("text/plain");
|
||||
object.getUserMetadata().getMetadata().put("Metadata", metadataValue);
|
||||
replaceObject(object);
|
||||
|
|
|
@ -25,7 +25,6 @@ import org.jclouds.aws.s3.domain.MutableObjectMetadata;
|
|||
import org.jclouds.aws.s3.domain.S3Object;
|
||||
import org.jclouds.aws.s3.domain.internal.S3ObjectImpl;
|
||||
import org.jclouds.blobstore.config.BlobStoreObjectModule;
|
||||
import org.jclouds.encryption.EncryptionService;
|
||||
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Provides;
|
||||
|
@ -49,14 +48,11 @@ public class S3ObjectModule extends AbstractModule {
|
|||
}
|
||||
|
||||
private static class S3ObjectFactory implements S3Object.Factory {
|
||||
@Inject
|
||||
EncryptionService encryptionService;
|
||||
@Inject
|
||||
Provider<MutableObjectMetadata> metadataProvider;
|
||||
|
||||
public S3Object create(MutableObjectMetadata metadata) {
|
||||
return new S3ObjectImpl(encryptionService, metadata != null ? metadata : metadataProvider
|
||||
.get());
|
||||
return new S3ObjectImpl(metadata != null ? metadata : metadataProvider.get());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -25,7 +25,6 @@ import javax.inject.Inject;
|
|||
import org.jclouds.aws.s3.domain.AccessControlList;
|
||||
import org.jclouds.aws.s3.domain.MutableObjectMetadata;
|
||||
import org.jclouds.aws.s3.domain.S3Object;
|
||||
import org.jclouds.encryption.EncryptionService;
|
||||
import org.jclouds.http.Payload;
|
||||
import org.jclouds.http.PayloadEnclosing;
|
||||
import org.jclouds.http.internal.PayloadEnclosingImpl;
|
||||
|
@ -64,8 +63,8 @@ public class S3ObjectImpl extends PayloadEnclosingImpl implements S3Object, Comp
|
|||
private Multimap<String, String> allHeaders = LinkedHashMultimap.create();
|
||||
|
||||
@Inject
|
||||
public S3ObjectImpl(EncryptionService encryptionService, MutableObjectMetadata metadata) {
|
||||
super(encryptionService);
|
||||
public S3ObjectImpl(MutableObjectMetadata metadata) {
|
||||
super();
|
||||
this.metadata = linkMetadataToThis(metadata);
|
||||
this._metadata = this.metadata.getDelegate();
|
||||
}
|
||||
|
|
|
@ -25,7 +25,6 @@ import org.jclouds.azure.storage.blob.domain.AzureBlob;
|
|||
import org.jclouds.azure.storage.blob.domain.MutableBlobProperties;
|
||||
import org.jclouds.azure.storage.blob.domain.internal.AzureBlobImpl;
|
||||
import org.jclouds.blobstore.config.BlobStoreObjectModule;
|
||||
import org.jclouds.encryption.EncryptionService;
|
||||
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Provides;
|
||||
|
@ -50,14 +49,11 @@ public class AzureBlobModule extends AbstractModule {
|
|||
}
|
||||
|
||||
private static class AzureBlobFactory implements AzureBlob.Factory {
|
||||
@Inject
|
||||
EncryptionService encryptionService;
|
||||
@Inject
|
||||
Provider<MutableBlobProperties> metadataProvider;
|
||||
|
||||
public AzureBlob create(MutableBlobProperties metadata) {
|
||||
return new AzureBlobImpl(encryptionService, metadata != null ? metadata : metadataProvider
|
||||
.get());
|
||||
return new AzureBlobImpl(metadata != null ? metadata : metadataProvider.get());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -24,7 +24,6 @@ import javax.inject.Inject;
|
|||
|
||||
import org.jclouds.azure.storage.blob.domain.AzureBlob;
|
||||
import org.jclouds.azure.storage.blob.domain.MutableBlobProperties;
|
||||
import org.jclouds.encryption.EncryptionService;
|
||||
import org.jclouds.http.Payload;
|
||||
import org.jclouds.http.PayloadEnclosing;
|
||||
import org.jclouds.http.internal.PayloadEnclosingImpl;
|
||||
|
@ -45,8 +44,8 @@ public class AzureBlobImpl extends PayloadEnclosingImpl implements AzureBlob, Co
|
|||
private Multimap<String, String> allHeaders = LinkedHashMultimap.create();
|
||||
|
||||
@Inject
|
||||
public AzureBlobImpl(EncryptionService encryptionService, MutableBlobProperties properties) {
|
||||
super(encryptionService);
|
||||
public AzureBlobImpl(MutableBlobProperties properties) {
|
||||
super();
|
||||
this.properties = linkMetadataToThis(properties);
|
||||
this._properties = this.properties.getDelegate();
|
||||
}
|
||||
|
|
|
@ -39,10 +39,9 @@ import org.jclouds.azure.storage.blob.domain.ListBlobsResponse;
|
|||
import org.jclouds.azure.storage.blob.options.ListBlobsOptions;
|
||||
import org.jclouds.azure.storage.domain.BoundedSet;
|
||||
import org.jclouds.azure.storage.options.ListOptions;
|
||||
import org.jclouds.blobstore.BlobStoreContext;
|
||||
import org.jclouds.blobstore.BlobStoreContextFactory;
|
||||
import org.jclouds.blobstore.ContainerNotFoundException;
|
||||
import org.jclouds.encryption.EncryptionService;
|
||||
import org.jclouds.encryption.internal.JCEEncryptionService;
|
||||
import org.jclouds.http.HttpResponseException;
|
||||
import org.jclouds.http.options.GetOptions;
|
||||
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
|
||||
|
@ -67,15 +66,16 @@ public class AzureBlobClientLiveTest {
|
|||
protected AzureBlobClient client;
|
||||
|
||||
private String containerPrefix = System.getProperty("user.name") + "-azureblob";
|
||||
private EncryptionService encryptionService = new JCEEncryptionService();
|
||||
|
||||
private BlobStoreContext context;
|
||||
|
||||
@BeforeTest
|
||||
public void setupClient() throws IOException {
|
||||
identity = System.getProperty("jclouds.test.identity");
|
||||
String credential = System.getProperty("jclouds.test.credential");
|
||||
client = (AzureBlobClient) new BlobStoreContextFactory().createContext("azureblob", identity,
|
||||
credential, ImmutableSet.<Module> of(new Log4JLoggingModule()))
|
||||
.getProviderSpecificContext().getApi();
|
||||
context = new BlobStoreContextFactory().createContext("azureblob", identity, credential,
|
||||
ImmutableSet.<Module> of(new Log4JLoggingModule()));
|
||||
client = (AzureBlobClient) context.getProviderSpecificContext().getApi();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -113,7 +113,7 @@ public class AzureBlobClientLiveTest {
|
|||
ListBlobsResponse list = client.listBlobs(privateContainer);
|
||||
assertEquals(list.getUrl(), URI.create(String.format("https://%s.blob.core.windows.net/%s",
|
||||
identity, privateContainer)));
|
||||
// TODO ... check to see the container actually exists
|
||||
// TODO .. check to see the container actually exists
|
||||
}
|
||||
|
||||
@Test(timeOut = 5 * 60 * 1000)
|
||||
|
@ -231,12 +231,12 @@ public class AzureBlobClientLiveTest {
|
|||
AzureBlob object = client.newBlob();
|
||||
object.getProperties().setName("object");
|
||||
object.setPayload(data);
|
||||
object.generateMD5();
|
||||
context.utils().encryption().generateMD5BufferingIfNotRepeatable(object);
|
||||
object.getProperties().setContentType("text/plain");
|
||||
object.getProperties().getMetadata().put("mykey", "metadata-value");
|
||||
byte[] md5 = object.getProperties().getContentMD5();
|
||||
String newEtag = client.putBlob(privateContainer, object);
|
||||
assertEquals(encryptionService.hex(md5), encryptionService.hex(object.getProperties()
|
||||
assertEquals(context.utils().encryption().hex(md5), context.utils().encryption().hex(object.getProperties()
|
||||
.getContentMD5()));
|
||||
|
||||
// Test HEAD of missing object
|
||||
|
@ -253,8 +253,8 @@ public class AzureBlobClientLiveTest {
|
|||
// http://code.google.com/p/jclouds/issues/detail?id=92
|
||||
// assertEquals(metadata.getSize(), data.length());
|
||||
assertEquals(metadata.getContentType(), "text/plain");
|
||||
// Azure doesn't return the Content-MD5 on head request...
|
||||
assertEquals(encryptionService.hex(md5), encryptionService.hex(object.getProperties()
|
||||
// Azure doesn't return the Content-MD5 on head request..
|
||||
assertEquals(context.utils().encryption().hex(md5), context.utils().encryption().hex(object.getProperties()
|
||||
.getContentMD5()));
|
||||
assertEquals(metadata.getETag(), newEtag);
|
||||
assertEquals(metadata.getMetadata().entrySet().size(), 1);
|
||||
|
@ -276,7 +276,7 @@ public class AzureBlobClientLiveTest {
|
|||
// TODO assertEquals(getBlob.getName(), object.getProperties().getName());
|
||||
assertEquals(getBlob.getPayload().getContentLength(), new Long(data.length()));
|
||||
assertEquals(getBlob.getProperties().getContentType(), "text/plain");
|
||||
assertEquals(encryptionService.hex(md5), encryptionService.hex(getBlob.getProperties()
|
||||
assertEquals(context.utils().encryption().hex(md5), context.utils().encryption().hex(getBlob.getProperties()
|
||||
.getContentMD5()));
|
||||
assertEquals(newEtag, getBlob.getProperties().getETag());
|
||||
// wait until we can update metadata
|
||||
|
@ -318,7 +318,7 @@ public class AzureBlobClientLiveTest {
|
|||
object.setPayload(bais);
|
||||
object.getPayload().setContentLength(new Long(data.getBytes().length));
|
||||
newEtag = client.putBlob(privateContainer, object);
|
||||
assertEquals(encryptionService.hex(md5), encryptionService.hex(getBlob.getProperties()
|
||||
assertEquals(context.utils().encryption().hex(md5), context.utils().encryption().hex(getBlob.getProperties()
|
||||
.getContentMD5()));
|
||||
|
||||
// Test GET with options
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
Current supported services are:
|
||||
[s3, azureblob, atmos, cloudfiles, walrus, googlestorage]
|
||||
|
||||
Here's a quick example of how to view blob resources in rackspace
|
||||
Here's a quick example of how to viewresources in rackspace
|
||||
|
||||
(use 'org.jclouds.blobstore)
|
||||
(use 'clojure.contrib.pprint)
|
||||
|
@ -92,8 +92,6 @@ Options can also be specified for extension modules
|
|||
|
||||
(def *blobstore*)
|
||||
|
||||
(def *encryption-service* (JCEEncryptionService.)) ;; TODO: use guice
|
||||
|
||||
(def *max-retries* 3)
|
||||
|
||||
(defmacro with-blobstore [[& blobstore-or-args] & body]
|
||||
|
@ -222,7 +220,7 @@ Options can also be specified for extension modules
|
|||
(.putBlob blobstore container-name blob)))
|
||||
|
||||
(defn blob-metadata
|
||||
"Get blob metadata from given path"
|
||||
"Get metadata from given path"
|
||||
([container-name path]
|
||||
(blob-metadata container-name path *blobstore*))
|
||||
([container-name path blobstore]
|
||||
|
@ -268,17 +266,29 @@ example:
|
|||
(.list (as-blobstore blobstore) container-name
|
||||
(.inDirectory (new ListContainerOptions) dir))))
|
||||
|
||||
(defn md5-blob
|
||||
"add a content md5 to a blob. note that this implies rebuffering, if theisn't repeatable"
|
||||
([blob]
|
||||
(md5-blob *blobstore*))
|
||||
([blob blobstore]
|
||||
(.generateMD5BufferingIfNotRepeatable (.encryption (.utils (blobstore-context blobstore)))
|
||||
blob)))
|
||||
(defn blob
|
||||
"create a new blob with the specified payload"
|
||||
([name payload]
|
||||
(blob name payload *blobstore*))
|
||||
([name payload blobstore]
|
||||
(doto (.newBlob blobstore name)
|
||||
(.setPayload payload))))
|
||||
|
||||
(defn upload-blob
|
||||
"Create an blob representing text data:
|
||||
"Create anrepresenting text data:
|
||||
container, name, string -> etag"
|
||||
([container-name name data] ;; TODO: allow payload to be a stream
|
||||
([container-name name data]
|
||||
(upload-blob container-name name data *blobstore*))
|
||||
([container-name name data blobstore]
|
||||
(put-blob container-name
|
||||
(doto (.newBlob blobstore name)
|
||||
(.setPayload data)
|
||||
(.generateMD5))
|
||||
blobstore)))
|
||||
(md5-blob (blob name data) blobstore) blobstore)))
|
||||
|
||||
(defmulti #^{:arglists '[[container-name name target]
|
||||
[container-name name target blobstore]]}
|
||||
|
|
|
@ -31,6 +31,7 @@ import org.jclouds.blobstore.strategy.ContainsValueInListStrategy;
|
|||
import org.jclouds.blobstore.strategy.GetBlobsInListStrategy;
|
||||
import org.jclouds.blobstore.strategy.PutBlobsStrategy;
|
||||
import org.jclouds.blobstore.strategy.internal.ListContainerAndRecurseThroughFolders;
|
||||
import org.jclouds.encryption.EncryptionService;
|
||||
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Scopes;
|
||||
|
@ -83,11 +84,14 @@ public class BlobStoreMapModule extends AbstractModule {
|
|||
@Inject
|
||||
PutBlobsStrategy putBlobsStrategy;
|
||||
@Inject
|
||||
EncryptionService encryptionService;
|
||||
@Inject
|
||||
ListContainerAndRecurseThroughFolders listStrategy;
|
||||
|
||||
public InputStreamMap create(String containerName, ListContainerOptions options) {
|
||||
return new InputStreamMapImpl(connection, blobFactory, getAllBlobs, listStrategy,
|
||||
containsValueStrategy, putBlobsStrategy, containerName, options);
|
||||
containsValueStrategy, putBlobsStrategy, containerName, options,
|
||||
encryptionService);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -24,7 +24,6 @@ import javax.inject.Provider;
|
|||
import org.jclouds.blobstore.domain.Blob;
|
||||
import org.jclouds.blobstore.domain.MutableBlobMetadata;
|
||||
import org.jclouds.blobstore.domain.internal.BlobImpl;
|
||||
import org.jclouds.encryption.EncryptionService;
|
||||
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Provides;
|
||||
|
@ -47,14 +46,12 @@ public class BlobStoreObjectModule extends AbstractModule {
|
|||
}
|
||||
|
||||
private static class BlobFactory implements Blob.Factory {
|
||||
@Inject
|
||||
EncryptionService encryptionService;
|
||||
|
||||
@Inject
|
||||
Provider<MutableBlobMetadata> metadataProvider;
|
||||
|
||||
public Blob create(MutableBlobMetadata metadata) {
|
||||
return new BlobImpl(encryptionService, metadata != null ? metadata : metadataProvider
|
||||
.get());
|
||||
return new BlobImpl(metadata != null ? metadata : metadataProvider.get());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -25,7 +25,6 @@ import javax.inject.Inject;
|
|||
import org.jclouds.blobstore.domain.Blob;
|
||||
import org.jclouds.blobstore.domain.MutableBlobMetadata;
|
||||
import org.jclouds.blobstore.domain.StorageMetadata;
|
||||
import org.jclouds.encryption.EncryptionService;
|
||||
import org.jclouds.http.Payload;
|
||||
import org.jclouds.http.PayloadEnclosing;
|
||||
import org.jclouds.http.internal.PayloadEnclosingImpl;
|
||||
|
@ -49,8 +48,8 @@ public class BlobImpl extends PayloadEnclosingImpl implements Blob, Comparable<B
|
|||
private Multimap<String, String> allHeaders = LinkedHashMultimap.create();
|
||||
|
||||
@Inject
|
||||
public BlobImpl(EncryptionService encryptionService, MutableBlobMetadata metadata) {
|
||||
super(encryptionService);
|
||||
public BlobImpl(MutableBlobMetadata metadata) {
|
||||
super();
|
||||
this.metadata = linkMetadataToThis(metadata);
|
||||
this._metadata = this.metadata.getDelegate();
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@ package org.jclouds.blobstore.functions;
|
|||
import javax.inject.Inject;
|
||||
|
||||
import org.jclouds.blobstore.domain.Blob;
|
||||
import org.jclouds.encryption.EncryptionService;
|
||||
import org.jclouds.http.Payloads;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
|
@ -28,10 +29,12 @@ import com.google.common.base.Function;
|
|||
public class ObjectMD5 implements Function<Object, byte[]> {
|
||||
|
||||
protected final Blob.Factory blobFactory;
|
||||
protected final EncryptionService encryptionService;
|
||||
|
||||
@Inject
|
||||
ObjectMD5(Blob.Factory blobFactory) {
|
||||
ObjectMD5(EncryptionService encryptionService, Blob.Factory blobFactory) {
|
||||
this.blobFactory = blobFactory;
|
||||
this.encryptionService = encryptionService;
|
||||
}
|
||||
|
||||
public byte[] apply(Object from) {
|
||||
|
@ -43,7 +46,7 @@ public class ObjectMD5 implements Function<Object, byte[]> {
|
|||
object.setPayload(Payloads.newPayload(from));
|
||||
}
|
||||
if (object.getMetadata().getContentMD5() == null)
|
||||
object.generateMD5();
|
||||
encryptionService.generateMD5BufferingIfNotRepeatable(object);
|
||||
return object.getPayload().getContentMD5();
|
||||
}
|
||||
|
||||
|
|
|
@ -38,6 +38,7 @@ import org.jclouds.blobstore.strategy.ContainsValueInListStrategy;
|
|||
import org.jclouds.blobstore.strategy.GetBlobsInListStrategy;
|
||||
import org.jclouds.blobstore.strategy.PutBlobsStrategy;
|
||||
import org.jclouds.blobstore.strategy.internal.ListContainerAndRecurseThroughFolders;
|
||||
import org.jclouds.encryption.EncryptionService;
|
||||
import org.jclouds.http.Payload;
|
||||
import org.jclouds.http.payloads.ByteArrayPayload;
|
||||
import org.jclouds.http.payloads.FilePayload;
|
||||
|
@ -58,14 +59,16 @@ import com.google.common.base.Function;
|
|||
* @see BaseBlobMap
|
||||
*/
|
||||
public class InputStreamMapImpl extends BaseBlobMap<InputStream> implements InputStreamMap {
|
||||
protected final EncryptionService encryptionService;
|
||||
|
||||
@Inject
|
||||
public InputStreamMapImpl(BlobStore connection, Blob.Factory blobFactory,
|
||||
GetBlobsInListStrategy getAllBlobs, ListContainerAndRecurseThroughFolders listStrategy,
|
||||
ContainsValueInListStrategy containsValueStrategy, PutBlobsStrategy putBlobsStrategy,
|
||||
String containerName, ListContainerOptions options) {
|
||||
String containerName, ListContainerOptions options, EncryptionService encryptionService) {
|
||||
super(connection, getAllBlobs, containsValueStrategy, putBlobsStrategy, listStrategy,
|
||||
containerName, options);
|
||||
this.encryptionService = encryptionService;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -129,14 +132,22 @@ public class InputStreamMapImpl extends BaseBlobMap<InputStream> implements Inpu
|
|||
new Function<Map.Entry<? extends String, ? extends Object>, Blob>() {
|
||||
@Override
|
||||
public Blob apply(Map.Entry<? extends String, ? extends Object> from) {
|
||||
Blob blob = blobstore.newBlob(prefixer.apply(from.getKey()));
|
||||
blob.setPayload(newPayload(from.getValue()));
|
||||
blob.generateMD5();
|
||||
return blob;
|
||||
String name = from.getKey();
|
||||
Object value = from.getValue();
|
||||
return newBlobWithMD5(name, value);
|
||||
}
|
||||
|
||||
}));
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
Blob newBlobWithMD5(String name, Object value) {
|
||||
Blob blob = blobstore.newBlob(prefixer.apply(name));
|
||||
blob.setPayload(newPayload(value));
|
||||
encryptionService.generateMD5BufferingIfNotRepeatable(blob);
|
||||
return blob;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream putString(String key, String value) {
|
||||
return putInternal(key, new StringPayload(value));
|
||||
|
@ -166,9 +177,7 @@ public class InputStreamMapImpl extends BaseBlobMap<InputStream> implements Inpu
|
|||
@VisibleForTesting
|
||||
InputStream putInternal(String name, Payload payload) {
|
||||
InputStream returnVal = containsKey(name) ? get(name) : null;
|
||||
Blob blob = blobstore.newBlob(prefixer.apply(name));
|
||||
blob.setPayload(payload);
|
||||
blob.generateMD5();
|
||||
Blob blob = newBlobWithMD5(name, payload);
|
||||
blobstore.putBlob(containerName, blob);
|
||||
return returnVal;
|
||||
}
|
||||
|
|
|
@ -47,7 +47,6 @@ import org.jclouds.blobstore.domain.BlobMetadata;
|
|||
import org.jclouds.blobstore.domain.PageSet;
|
||||
import org.jclouds.blobstore.domain.StorageMetadata;
|
||||
import org.jclouds.blobstore.domain.StorageType;
|
||||
import org.jclouds.encryption.EncryptionService;
|
||||
import org.jclouds.encryption.internal.JCEEncryptionService;
|
||||
import org.jclouds.http.BaseJettyTest;
|
||||
import org.jclouds.http.HttpResponseException;
|
||||
|
@ -68,25 +67,22 @@ import com.google.common.io.ByteStreams;
|
|||
import com.google.common.io.InputSupplier;
|
||||
import com.google.common.util.concurrent.Futures;
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
import com.google.inject.Guice;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class BaseBlobIntegrationTest extends BaseBlobStoreIntegrationTest {
|
||||
private byte[] oneHundredOneConstitutions;
|
||||
private EncryptionService encryptionService;
|
||||
private byte[] oneHundredOneConstitutionsMD5;
|
||||
|
||||
@BeforeClass(groups = { "integration", "live" })
|
||||
@Override
|
||||
public void setUpResourcesOnThisThread(ITestContext testContext) throws Exception {
|
||||
encryptionService = Guice.createInjector().getInstance(EncryptionService.class);
|
||||
Payload result = encryptionService
|
||||
.generatePayloadWithMD5For(getTestDataSupplier().getInput());
|
||||
super.setUpResourcesOnThisThread(testContext);
|
||||
Payload result = context.utils().encryption().generatePayloadWithMD5For(
|
||||
getTestDataSupplier().getInput());
|
||||
oneHundredOneConstitutions = (byte[]) result.getRawContent();
|
||||
oneHundredOneConstitutionsMD5 = result.getContentMD5();
|
||||
super.setUpResourcesOnThisThread(testContext);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
|
@ -119,7 +115,7 @@ public class BaseBlobIntegrationTest extends BaseBlobStoreIntegrationTest {
|
|||
|
||||
@Override
|
||||
public Void apply(Blob from) {
|
||||
assertEquals(encryptionService.md5(from.getPayload().getInput()),
|
||||
assertEquals(context.utils().encryption().md5(from.getPayload().getInput()),
|
||||
oneHundredOneConstitutionsMD5);
|
||||
return null;
|
||||
}
|
||||
|
@ -151,7 +147,7 @@ public class BaseBlobIntegrationTest extends BaseBlobStoreIntegrationTest {
|
|||
String key = "apples";
|
||||
|
||||
Date before = new Date(System.currentTimeMillis() - 1000);
|
||||
// first create the object
|
||||
// first create the blob
|
||||
addObjectAndValidateContent(containerName, key);
|
||||
// now, modify it
|
||||
addObjectAndValidateContent(containerName, key);
|
||||
|
@ -251,13 +247,13 @@ public class BaseBlobIntegrationTest extends BaseBlobStoreIntegrationTest {
|
|||
String key = "apples";
|
||||
|
||||
addObjectAndValidateContent(containerName, key);
|
||||
Blob object1 = context.getBlobStore().getBlob(containerName, key, range(0, 5));
|
||||
assertEquals(getContentAsStringOrNullAndClose(object1), TEST_STRING.substring(0, 6));
|
||||
Blob blob1 = context.getBlobStore().getBlob(containerName, key, range(0, 5));
|
||||
assertEquals(getContentAsStringOrNullAndClose(blob1), TEST_STRING.substring(0, 6));
|
||||
|
||||
Blob object2 = context.getBlobStore().getBlob(containerName, key,
|
||||
Blob blob2 = context.getBlobStore().getBlob(containerName, key,
|
||||
range(6, TEST_STRING.length()));
|
||||
assertEquals(getContentAsStringOrNullAndClose(object2), TEST_STRING.substring(6,
|
||||
TEST_STRING.length()));
|
||||
assertEquals(getContentAsStringOrNullAndClose(blob2), TEST_STRING.substring(6, TEST_STRING
|
||||
.length()));
|
||||
} finally {
|
||||
returnContainer(containerName);
|
||||
}
|
||||
|
@ -271,10 +267,10 @@ public class BaseBlobIntegrationTest extends BaseBlobStoreIntegrationTest {
|
|||
String key = "apples";
|
||||
|
||||
addObjectAndValidateContent(containerName, key);
|
||||
Blob object = context.getBlobStore().getBlob(containerName, key,
|
||||
Blob blob = context.getBlobStore().getBlob(containerName, key,
|
||||
range(0, 5).range(6, TEST_STRING.length()));
|
||||
|
||||
assertEquals(getContentAsStringOrNullAndClose(object), TEST_STRING);
|
||||
assertEquals(getContentAsStringOrNullAndClose(blob), TEST_STRING);
|
||||
} finally {
|
||||
returnContainer(containerName);
|
||||
}
|
||||
|
@ -289,12 +285,12 @@ public class BaseBlobIntegrationTest extends BaseBlobStoreIntegrationTest {
|
|||
// String key = "apples";
|
||||
//
|
||||
// addObjectAndValidateContent(containerName, key);
|
||||
// Blob object = context.getBlobStore().getBlob(containerName, key, tail(5)).get(30,
|
||||
// Blob blob = context.getBlobStore().getBlob(containerName, key, tail(5)).get(30,
|
||||
// TimeUnit.SECONDS);
|
||||
// assertEquals(BlobStoreUtils.getContentAsStringAndClose(object), TEST_STRING
|
||||
// assertEquals(BlobStoreUtils.getContentAsStringAndClose(blob), TEST_STRING
|
||||
// .substring(TEST_STRING.length() - 5));
|
||||
// assertEquals(object.getContentLength(), 5);
|
||||
// assertEquals(object.getMetadata().getSize(), TEST_STRING.length());
|
||||
// assertEquals(blob.getContentLength(), 5);
|
||||
// assertEquals(blob.getMetadata().getSize(), TEST_STRING.length());
|
||||
// } finally {
|
||||
// returnContainer(containerName);
|
||||
// }
|
||||
|
@ -309,12 +305,12 @@ public class BaseBlobIntegrationTest extends BaseBlobStoreIntegrationTest {
|
|||
// String key = "apples";
|
||||
//
|
||||
// addObjectAndValidateContent(containerName, key);
|
||||
// Blob object = context.getBlobStore().getBlob(containerName, key, startAt(5)).get(30,
|
||||
// Blob blob = context.getBlobStore().getBlob(containerName, key, startAt(5)).get(30,
|
||||
// TimeUnit.SECONDS);
|
||||
// assertEquals(BlobStoreUtils.getContentAsStringAndClose(object), TEST_STRING.substring(5,
|
||||
// assertEquals(BlobStoreUtils.getContentAsStringAndClose(blob), TEST_STRING.substring(5,
|
||||
// TEST_STRING.length()));
|
||||
// assertEquals(object.getContentLength(), TEST_STRING.length() - 5);
|
||||
// assertEquals(object.getMetadata().getSize(), TEST_STRING.length());
|
||||
// assertEquals(blob.getContentLength(), TEST_STRING.length() - 5);
|
||||
// assertEquals(blob.getMetadata().getSize(), TEST_STRING.length());
|
||||
// } finally {
|
||||
// returnContainer(containerName);
|
||||
// }
|
||||
|
@ -339,7 +335,7 @@ public class BaseBlobIntegrationTest extends BaseBlobStoreIntegrationTest {
|
|||
}
|
||||
|
||||
@Test(groups = { "integration", "live" })
|
||||
public void objectNotFound() throws InterruptedException {
|
||||
public void blobNotFound() throws InterruptedException {
|
||||
String containerName = getContainerName();
|
||||
String key = "test";
|
||||
try {
|
||||
|
@ -407,17 +403,17 @@ public class BaseBlobIntegrationTest extends BaseBlobStoreIntegrationTest {
|
|||
@Test(groups = { "integration", "live" }, dataProvider = "putTests")
|
||||
public void testPutObject(String key, String type, Object content, Object realObject)
|
||||
throws InterruptedException, IOException {
|
||||
Blob object = context.getBlobStore().newBlob(key);
|
||||
object.getMetadata().setContentType(type);
|
||||
object.setPayload(Payloads.newPayload(content));
|
||||
Blob blob = context.getBlobStore().newBlob(key);
|
||||
blob.getMetadata().setContentType(type);
|
||||
blob.setPayload(Payloads.newPayload(content));
|
||||
if (content instanceof InputStream) {
|
||||
object.generateMD5();
|
||||
context.utils().encryption().generateMD5BufferingIfNotRepeatable(blob);
|
||||
}
|
||||
String containerName = getContainerName();
|
||||
try {
|
||||
assertNotNull(context.getBlobStore().putBlob(containerName, object));
|
||||
object = context.getBlobStore().getBlob(containerName, object.getMetadata().getName());
|
||||
String returnedString = getContentAsStringOrNullAndClose(object);
|
||||
assertNotNull(context.getBlobStore().putBlob(containerName, blob));
|
||||
blob = context.getBlobStore().getBlob(containerName, blob.getMetadata().getName());
|
||||
String returnedString = getContentAsStringOrNullAndClose(blob);
|
||||
assertEquals(returnedString, realObject);
|
||||
PageSet<? extends StorageMetadata> set = context.getBlobStore().list(containerName);
|
||||
assert set.size() == 1 : set;
|
||||
|
@ -430,20 +426,20 @@ public class BaseBlobIntegrationTest extends BaseBlobStoreIntegrationTest {
|
|||
public void testMetadata() throws InterruptedException {
|
||||
String key = "hello";
|
||||
|
||||
Blob object = context.getBlobStore().newBlob(key);
|
||||
object.setPayload(TEST_STRING);
|
||||
object.getMetadata().setContentType(MediaType.TEXT_PLAIN);
|
||||
object.getMetadata().setSize(new Long(TEST_STRING.length()));
|
||||
Blob blob = context.getBlobStore().newBlob(key);
|
||||
blob.setPayload(TEST_STRING);
|
||||
blob.getMetadata().setContentType(MediaType.TEXT_PLAIN);
|
||||
blob.getMetadata().setSize(new Long(TEST_STRING.length()));
|
||||
// NOTE all metadata in jclouds comes out as lowercase, in an effort to normalize the
|
||||
// providers.
|
||||
object.getMetadata().getUserMetadata().put("Adrian", "powderpuff");
|
||||
object.getMetadata().setContentMD5(
|
||||
blob.getMetadata().getUserMetadata().put("Adrian", "powderpuff");
|
||||
blob.getMetadata().setContentMD5(
|
||||
new JCEEncryptionService().md5(Utils.toInputStream(TEST_STRING)));
|
||||
String containerName = getContainerName();
|
||||
try {
|
||||
assertNull(context.getBlobStore().blobMetadata(containerName, "powderpuff"));
|
||||
|
||||
addBlobToContainer(containerName, object);
|
||||
addBlobToContainer(containerName, blob);
|
||||
Blob newObject = validateContent(containerName, key);
|
||||
|
||||
BlobMetadata metadata = newObject.getMetadata();
|
||||
|
@ -452,10 +448,10 @@ public class BaseBlobIntegrationTest extends BaseBlobStoreIntegrationTest {
|
|||
validateMetadata(context.getBlobStore().blobMetadata(containerName, key));
|
||||
|
||||
// write 2 items with the same key to ensure that provider doesn't accept dupes
|
||||
object.getMetadata().getUserMetadata().put("Adrian", "wonderpuff");
|
||||
object.getMetadata().getUserMetadata().put("Adrian", "powderpuff");
|
||||
blob.getMetadata().getUserMetadata().put("Adrian", "wonderpuff");
|
||||
blob.getMetadata().getUserMetadata().put("Adrian", "powderpuff");
|
||||
|
||||
addBlobToContainer(containerName, object);
|
||||
addBlobToContainer(containerName, blob);
|
||||
validateMetadata(context.getBlobStore().blobMetadata(containerName, key));
|
||||
|
||||
} finally {
|
||||
|
|
|
@ -59,15 +59,15 @@ public abstract class BaseBlobMapIntegrationTest extends BaseMapIntegrationTest<
|
|||
putFiveStrings(map);
|
||||
putFiveStringsUnderPath(map);
|
||||
|
||||
Collection<Blob> values = map.values();
|
||||
Collection<Blob> blobs = map.values();
|
||||
assertConsistencyAwareMapSize(map, 5);
|
||||
Set<String> valuesAsString = new HashSet<String>();
|
||||
for (Blob object : values) {
|
||||
valuesAsString.add(getContentAsStringOrNullAndClose(object));
|
||||
Set<String> blobsAsString = new HashSet<String>();
|
||||
for (Blob blob : blobs) {
|
||||
blobsAsString.add(getContentAsStringOrNullAndClose(blob));
|
||||
}
|
||||
valuesAsString.removeAll(fiveStrings.values());
|
||||
assert valuesAsString.size() == 0 : valuesAsString.size() + ": " + values + ": "
|
||||
+ valuesAsString;
|
||||
blobsAsString.removeAll(fiveStrings.values());
|
||||
assert blobsAsString.size() == 0 : blobsAsString.size() + ": " + blobs + ": "
|
||||
+ blobsAsString;
|
||||
} finally {
|
||||
returnContainer(bucketName);
|
||||
}
|
||||
|
@ -90,12 +90,12 @@ public abstract class BaseBlobMapIntegrationTest extends BaseMapIntegrationTest<
|
|||
}
|
||||
|
||||
private void assertConsistencyAwareContentEquals(final Map<String, Blob> map, final String key,
|
||||
final String value) throws InterruptedException {
|
||||
final String blob) throws InterruptedException {
|
||||
assertConsistencyAware(new Runnable() {
|
||||
public void run() {
|
||||
Blob old = map.remove(key);
|
||||
try {
|
||||
assertEquals(getContentAsStringOrNullAndClose(old), value);
|
||||
assertEquals(getContentAsStringOrNullAndClose(old), blob);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
@ -116,16 +116,16 @@ public abstract class BaseBlobMapIntegrationTest extends BaseMapIntegrationTest<
|
|||
for (Entry<String, Blob> entry : entries) {
|
||||
assertEquals(fiveStrings.get(entry.getKey()), getContentAsStringOrNullAndClose(entry
|
||||
.getValue()));
|
||||
Blob value = entry.getValue();
|
||||
value.setPayload("");
|
||||
value.generateMD5();
|
||||
entry.setValue(value);
|
||||
Blob blob = entry.getValue();
|
||||
blob.setPayload("");
|
||||
context.utils().encryption().generateMD5BufferingIfNotRepeatable(blob);
|
||||
entry.setValue(blob);
|
||||
}
|
||||
assertConsistencyAware(new Runnable() {
|
||||
public void run() {
|
||||
for (Blob value : map.values()) {
|
||||
for (Blob blob : map.values()) {
|
||||
try {
|
||||
assertEquals(getContentAsStringOrNullAndClose(value), "");
|
||||
assertEquals(getContentAsStringOrNullAndClose(blob), "");
|
||||
} catch (IOException e) {
|
||||
Throwables.propagate(e);
|
||||
}
|
||||
|
@ -144,10 +144,10 @@ public abstract class BaseBlobMapIntegrationTest extends BaseMapIntegrationTest<
|
|||
try {
|
||||
Map<String, Blob> map = createMap(context, bucketName);
|
||||
putStringWithMD5(map, "one", "apple");
|
||||
Blob object = context.getBlobStore().newBlob("one");
|
||||
object.setPayload("apple");
|
||||
object.generateMD5();
|
||||
assertConsistencyAwareContainsValue(map, object);
|
||||
Blob blob = context.getBlobStore().newBlob("one");
|
||||
blob.setPayload("apple");
|
||||
context.utils().encryption().generateMD5BufferingIfNotRepeatable(blob);
|
||||
assertConsistencyAwareContainsValue(map, blob);
|
||||
} finally {
|
||||
returnContainer(bucketName);
|
||||
}
|
||||
|
@ -172,14 +172,14 @@ public abstract class BaseBlobMapIntegrationTest extends BaseMapIntegrationTest<
|
|||
String bucketName = getContainerName();
|
||||
try {
|
||||
Map<String, Blob> map = createMap(context, bucketName);
|
||||
Blob object = context.getBlobStore().newBlob("one");
|
||||
object.setPayload(Utils.toInputStream("apple"));
|
||||
object.generateMD5();
|
||||
Blob old = map.put(object.getMetadata().getName(), object);
|
||||
Blob blob = context.getBlobStore().newBlob("one");
|
||||
blob.setPayload(Utils.toInputStream("apple"));
|
||||
context.utils().encryption().generateMD5BufferingIfNotRepeatable(blob);
|
||||
Blob old = map.put(blob.getMetadata().getName(), blob);
|
||||
getOneReturnsAppleAndOldValueIsNull(map, old);
|
||||
object.setPayload(Utils.toInputStream("bear"));
|
||||
object.generateMD5();
|
||||
Blob apple = map.put(object.getMetadata().getName(), object);
|
||||
blob.setPayload(Utils.toInputStream("bear"));
|
||||
context.utils().encryption().generateMD5BufferingIfNotRepeatable(blob);
|
||||
Blob apple = map.put(blob.getMetadata().getName(), blob);
|
||||
getOneReturnsBearAndOldValueIsApple(map, apple);
|
||||
} finally {
|
||||
returnContainer(bucketName);
|
||||
|
@ -193,10 +193,10 @@ public abstract class BaseBlobMapIntegrationTest extends BaseMapIntegrationTest<
|
|||
Map<String, Blob> map = createMap(context, bucketName);
|
||||
Map<String, Blob> newMap = new HashMap<String, Blob>();
|
||||
for (String key : fiveInputs.keySet()) {
|
||||
Blob object = context.getBlobStore().newBlob(key);
|
||||
object.setPayload(fiveInputs.get(key));
|
||||
object.getPayload().setContentLength((long) fiveBytes.get(key).length);
|
||||
newMap.put(key, object);
|
||||
Blob blob = context.getBlobStore().newBlob(key);
|
||||
blob.setPayload(fiveInputs.get(key));
|
||||
blob.getPayload().setContentLength((long) fiveBytes.get(key).length);
|
||||
newMap.put(key, blob);
|
||||
}
|
||||
map.putAll(newMap);
|
||||
assertConsistencyAwareMapSize(map, 5);
|
||||
|
@ -222,9 +222,9 @@ public abstract class BaseBlobMapIntegrationTest extends BaseMapIntegrationTest<
|
|||
|
||||
Map<String, Blob> newMap = new HashMap<String, Blob>();
|
||||
for (String key : keySet) {
|
||||
Blob object = context.getBlobStore().newBlob(key);
|
||||
object.setPayload(key);
|
||||
newMap.put(key, object);
|
||||
Blob blob = context.getBlobStore().newBlob(key);
|
||||
blob.setPayload(key);
|
||||
newMap.put(key, blob);
|
||||
}
|
||||
map.putAll(newMap);
|
||||
newMap.clear();
|
||||
|
@ -239,19 +239,19 @@ public abstract class BaseBlobMapIntegrationTest extends BaseMapIntegrationTest<
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void putStringWithMD5(Map<String, Blob> map, String key, String value) {
|
||||
Blob object = context.getBlobStore().newBlob(key);
|
||||
object.setPayload(value);
|
||||
object.generateMD5();
|
||||
map.put(key, object);
|
||||
protected void putStringWithMD5(Map<String, Blob> map, String key, String text) {
|
||||
Blob blob = context.getBlobStore().newBlob(key);
|
||||
blob.setPayload(text);
|
||||
context.utils().encryption().generateMD5BufferingIfNotRepeatable(blob);
|
||||
map.put(key, blob);
|
||||
}
|
||||
|
||||
protected void putFiveStrings(Map<String, Blob> map) {
|
||||
Map<String, Blob> newMap = new HashMap<String, Blob>();
|
||||
for (Map.Entry<String, String> entry : fiveStrings.entrySet()) {
|
||||
Blob object = context.getBlobStore().newBlob(entry.getKey());
|
||||
object.setPayload(entry.getValue());
|
||||
newMap.put(entry.getKey(), object);
|
||||
Blob blob = context.getBlobStore().newBlob(entry.getKey());
|
||||
blob.setPayload(entry.getValue());
|
||||
newMap.put(entry.getKey(), blob);
|
||||
}
|
||||
map.putAll(newMap);
|
||||
}
|
||||
|
@ -259,9 +259,9 @@ public abstract class BaseBlobMapIntegrationTest extends BaseMapIntegrationTest<
|
|||
protected void putFiveStringsUnderPath(Map<String, Blob> map) {
|
||||
Map<String, Blob> newMap = new HashMap<String, Blob>();
|
||||
for (Map.Entry<String, String> entry : fiveStringsUnderPath.entrySet()) {
|
||||
Blob object = context.getBlobStore().newBlob(entry.getKey());
|
||||
object.setPayload(entry.getValue());
|
||||
newMap.put(entry.getKey(), object);
|
||||
Blob blob = context.getBlobStore().newBlob(entry.getKey());
|
||||
blob.setPayload(entry.getValue());
|
||||
newMap.put(entry.getKey(), blob);
|
||||
}
|
||||
map.putAll(newMap);
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ import java.security.Key;
|
|||
|
||||
import org.jclouds.encryption.internal.JCEEncryptionService;
|
||||
import org.jclouds.http.Payload;
|
||||
import org.jclouds.http.PayloadEnclosing;
|
||||
import org.jclouds.http.payloads.ByteArrayPayload;
|
||||
|
||||
import com.google.inject.ImplementedBy;
|
||||
|
@ -55,6 +56,15 @@ public interface EncryptionService {
|
|||
|
||||
byte[] md5(InputStream toEncode);
|
||||
|
||||
/**
|
||||
* generate an MD5 Hash for the current data.
|
||||
* <p/>
|
||||
* <h2>Note</h2>
|
||||
* <p/>
|
||||
* If this is an InputStream, it will be converted to a byte array first.
|
||||
*/
|
||||
<T extends PayloadEnclosing> T generateMD5BufferingIfNotRepeatable(T payloadEnclosing);
|
||||
|
||||
Payload generateMD5BufferingIfNotRepeatable(Payload in);
|
||||
|
||||
ByteArrayPayload generatePayloadWithMD5For(InputStream toEncode);
|
||||
|
|
|
@ -19,11 +19,13 @@
|
|||
package org.jclouds.encryption.internal;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.base.Preconditions.checkState;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
|
||||
import org.jclouds.encryption.EncryptionService;
|
||||
import org.jclouds.http.Payload;
|
||||
import org.jclouds.http.PayloadEnclosing;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -76,4 +78,16 @@ public abstract class BaseEncryptionService implements EncryptionService {
|
|||
return payload;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public <T extends PayloadEnclosing> T generateMD5BufferingIfNotRepeatable(T payloadEnclosing) {
|
||||
checkState(payloadEnclosing != null, "payloadEnclosing");
|
||||
Payload newPayload = generateMD5BufferingIfNotRepeatable(payloadEnclosing.getPayload());
|
||||
if (newPayload != payloadEnclosing.getPayload())
|
||||
payloadEnclosing.setPayload(newPayload);
|
||||
return payloadEnclosing;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,16 +20,18 @@ package org.jclouds.http;
|
|||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.io.Closeables.closeQuietly;
|
||||
import static com.google.inject.internal.Lists.newArrayList;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import java.net.URI;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import org.jclouds.http.internal.PayloadEnclosingImpl;
|
||||
|
||||
import com.google.common.collect.LinkedHashMultimap;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.common.collect.Multimaps;
|
||||
import com.google.inject.internal.Nullable;
|
||||
|
||||
/**
|
||||
|
@ -37,7 +39,7 @@ import com.google.inject.internal.Nullable;
|
|||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class HttpRequest extends HttpMessage {
|
||||
public class HttpRequest extends PayloadEnclosingImpl implements PayloadEnclosing {
|
||||
|
||||
private List<HttpRequestFilter> requestFilters = newArrayList();
|
||||
private String method;
|
||||
|
@ -45,6 +47,26 @@ public class HttpRequest extends HttpMessage {
|
|||
private Payload payload;
|
||||
private char[] skips;
|
||||
|
||||
/**
|
||||
* synchronized as there is no concurrent version. Headers may change in flight due to redirects.
|
||||
*/
|
||||
private Multimap<String, String> headers = Multimaps.synchronizedMultimap(LinkedHashMultimap
|
||||
.<String, String> create());
|
||||
|
||||
public Multimap<String, String> getHeaders() {
|
||||
return headers;
|
||||
}
|
||||
|
||||
/**
|
||||
* try to get the value, then try as lowercase.
|
||||
*/
|
||||
public String getFirstHeaderOrNull(String string) {
|
||||
Collection<String> values = headers.get(string);
|
||||
if (values.size() == 0)
|
||||
values = headers.get(string.toLowerCase());
|
||||
return (values.size() >= 1) ? values.iterator().next() : null;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param endpoint
|
||||
|
@ -104,31 +126,6 @@ public class HttpRequest extends HttpMessage {
|
|||
return method;
|
||||
}
|
||||
|
||||
public Payload getPayload() {
|
||||
return payload;
|
||||
}
|
||||
|
||||
public void setPayload(Payload data) {
|
||||
closeContentIfPresent();
|
||||
this.payload = checkNotNull(data, "data");
|
||||
}
|
||||
|
||||
public void setPayload(InputStream data) {
|
||||
setPayload(Payloads.newPayload(checkNotNull(data, "data")));
|
||||
}
|
||||
|
||||
public void setPayload(byte[] data) {
|
||||
setPayload(Payloads.newPayload(checkNotNull(data, "data")));
|
||||
}
|
||||
|
||||
public void setPayload(String data) {
|
||||
setPayload(Payloads.newPayload(checkNotNull(data, "data")));
|
||||
}
|
||||
|
||||
public void setPayload(File data) {
|
||||
setPayload(Payloads.newPayload(checkNotNull(data, "data")));
|
||||
}
|
||||
|
||||
/**
|
||||
* characters to skip encoding on.
|
||||
*/
|
||||
|
@ -160,18 +157,6 @@ public class HttpRequest extends HttpMessage {
|
|||
this.endpoint = endpoint;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void finalize() throws Throwable {
|
||||
closeContentIfPresent();
|
||||
super.finalize();
|
||||
}
|
||||
|
||||
private void closeContentIfPresent() {
|
||||
if (getPayload() != null && getPayload().getInput() != null) {
|
||||
closeQuietly(getPayload().getInput());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
|
|
|
@ -47,13 +47,4 @@ public interface PayloadEnclosing {
|
|||
|
||||
Payload getPayload();
|
||||
|
||||
/**
|
||||
* generate an MD5 Hash for the current data.
|
||||
* <p/>
|
||||
* <h2>Note</h2>
|
||||
* <p/>
|
||||
* If this is an InputStream, it will be converted to a byte array first.
|
||||
*/
|
||||
void generateMD5();
|
||||
|
||||
}
|
|
@ -19,7 +19,6 @@
|
|||
package org.jclouds.http.internal;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.base.Preconditions.checkState;
|
||||
import static com.google.common.io.Closeables.closeQuietly;
|
||||
import static org.jclouds.http.Payloads.newPayload;
|
||||
|
||||
|
@ -28,7 +27,6 @@ import java.io.InputStream;
|
|||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import org.jclouds.encryption.EncryptionService;
|
||||
import org.jclouds.http.Payload;
|
||||
import org.jclouds.http.PayloadEnclosing;
|
||||
|
||||
|
@ -37,29 +35,16 @@ import org.jclouds.http.PayloadEnclosing;
|
|||
* @author Adrian Cole
|
||||
*/
|
||||
public class PayloadEnclosingImpl implements PayloadEnclosing {
|
||||
private final EncryptionService encryptionService;
|
||||
protected Payload payload;
|
||||
|
||||
public PayloadEnclosingImpl(EncryptionService encryptionService, @Nullable Payload payload) {
|
||||
this.encryptionService = encryptionService;
|
||||
public PayloadEnclosingImpl() {
|
||||
this(null);
|
||||
}
|
||||
|
||||
public PayloadEnclosingImpl(@Nullable Payload payload) {
|
||||
this.payload = payload;
|
||||
}
|
||||
|
||||
public PayloadEnclosingImpl(EncryptionService encryptionService) {
|
||||
this(encryptionService, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void generateMD5() {
|
||||
checkState(payload != null, "payload");
|
||||
Payload newPayload = encryptionService.generateMD5BufferingIfNotRepeatable(payload);
|
||||
if (newPayload != payload)
|
||||
setPayload(newPayload);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
|
@ -98,6 +83,7 @@ public class PayloadEnclosingImpl implements PayloadEnclosing {
|
|||
*/
|
||||
@Override
|
||||
public void setPayload(String data) {
|
||||
closeContentIfPresent();
|
||||
setPayload(newPayload(checkNotNull(data, "data")));
|
||||
}
|
||||
|
||||
|
@ -140,4 +126,9 @@ public class PayloadEnclosingImpl implements PayloadEnclosing {
|
|||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void finalize() throws Throwable {
|
||||
closeContentIfPresent();
|
||||
super.finalize();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -614,10 +614,11 @@ public class RestAnnotationProcessorTest {
|
|||
assertEquals(request.getPayload().getRawContent(), "\"data\"");
|
||||
}
|
||||
|
||||
public void testCreatePostWithPathRequest() throws SecurityException, NoSuchMethodException, IOException {
|
||||
public void testCreatePostWithPathRequest() throws SecurityException, NoSuchMethodException,
|
||||
IOException {
|
||||
Method method = TestPost.class.getMethod("postWithPath", String.class, MapBinder.class);
|
||||
HttpRequest request = factory(TestPost.class).createRequest(method,
|
||||
"data", new org.jclouds.rest.MapBinder() {
|
||||
HttpRequest request = factory(TestPost.class).createRequest(method, "data",
|
||||
new org.jclouds.rest.MapBinder() {
|
||||
public void bindToRequest(HttpRequest request, Map<String, String> postParams) {
|
||||
request.setPayload(postParams.get("fooble"));
|
||||
}
|
||||
|
@ -625,7 +626,7 @@ public class RestAnnotationProcessorTest {
|
|||
public void bindToRequest(HttpRequest request, Object toBind) {
|
||||
throw new RuntimeException("this shouldn't be used in POST");
|
||||
}
|
||||
} );
|
||||
});
|
||||
assertRequestLineEquals(request, "POST http://localhost:9999/data HTTP/1.1");
|
||||
assertHeadersEqual(request, "Content-Length: 4\nContent-Type: application/unknown\n");
|
||||
assertPayloadEquals(request, "data");
|
||||
|
@ -1405,10 +1406,8 @@ public class RestAnnotationProcessorTest {
|
|||
public void testPutPayloadEnclosing() throws SecurityException, NoSuchMethodException,
|
||||
IOException {
|
||||
Method method = TestTransformers.class.getMethod("put", PayloadEnclosing.class);
|
||||
HttpRequest request = factory(TestQuery.class).createRequest(
|
||||
method,
|
||||
new PayloadEnclosingImpl(injector.getInstance(EncryptionService.class),
|
||||
newStringPayload("whoops")));
|
||||
HttpRequest request = factory(TestQuery.class).createRequest(method,
|
||||
new PayloadEnclosingImpl(newStringPayload("whoops")));
|
||||
assertRequestLineEquals(request, "PUT http://localhost:9999?x-ms-version=2009-07-17 HTTP/1.1");
|
||||
assertHeadersEqual(request, "Content-Length: 6\nContent-Type: application/unknown\n");
|
||||
assertPayloadEquals(request, "whoops");
|
||||
|
@ -1417,10 +1416,10 @@ public class RestAnnotationProcessorTest {
|
|||
public void testPutPayloadEnclosingGenerateMD5() throws SecurityException,
|
||||
NoSuchMethodException, IOException {
|
||||
Method method = TestTransformers.class.getMethod("put", PayloadEnclosing.class);
|
||||
PayloadEnclosing payloadEnclosing = new PayloadEnclosingImpl(injector
|
||||
.getInstance(EncryptionService.class), newStringPayload("whoops"));
|
||||
PayloadEnclosing payloadEnclosing = new PayloadEnclosingImpl(newStringPayload("whoops"));
|
||||
|
||||
payloadEnclosing.generateMD5();
|
||||
injector.getInstance(EncryptionService.class).generateMD5BufferingIfNotRepeatable(
|
||||
payloadEnclosing);
|
||||
HttpRequest request = factory(TestQuery.class).createRequest(method, payloadEnclosing);
|
||||
assertRequestLineEquals(request, "PUT http://localhost:9999?x-ms-version=2009-07-17 HTTP/1.1");
|
||||
assertHeadersEqual(request,
|
||||
|
@ -1432,11 +1431,11 @@ public class RestAnnotationProcessorTest {
|
|||
public void testPutInputStreamPayloadEnclosingGenerateMD5() throws SecurityException,
|
||||
NoSuchMethodException, IOException {
|
||||
Method method = TestTransformers.class.getMethod("put", PayloadEnclosing.class);
|
||||
PayloadEnclosing payloadEnclosing = new PayloadEnclosingImpl(injector
|
||||
.getInstance(EncryptionService.class),
|
||||
PayloadEnclosing payloadEnclosing = new PayloadEnclosingImpl(
|
||||
newInputStreamPayload(toInputStream("whoops")));
|
||||
|
||||
payloadEnclosing.generateMD5();
|
||||
injector.getInstance(EncryptionService.class).generateMD5BufferingIfNotRepeatable(
|
||||
payloadEnclosing);
|
||||
HttpRequest request = factory(TestQuery.class).createRequest(method, payloadEnclosing);
|
||||
assertRequestLineEquals(request, "PUT http://localhost:9999?x-ms-version=2009-07-17 HTTP/1.1");
|
||||
assertHeadersEqual(request,
|
||||
|
|
|
@ -41,7 +41,7 @@ public class PCSFileImpl extends PayloadEnclosingImpl implements PCSFile, Compar
|
|||
|
||||
@Inject
|
||||
public PCSFileImpl(MutableFileInfo metadata) {
|
||||
super(null);// no MD5 support
|
||||
super();// no MD5 support
|
||||
this.metadata = metadata;
|
||||
}
|
||||
|
||||
|
|
|
@ -78,7 +78,7 @@ public class SDNClientLiveTest {
|
|||
Blob blob = connection.newBlob();
|
||||
blob.getMetadata().setName("test.txt");
|
||||
blob.setPayload("value");
|
||||
blob.generateMD5();
|
||||
context.utils().encryption().generateMD5BufferingIfNotRepeatable(blob);
|
||||
|
||||
byte[] md5 = blob.getMetadata().getContentMD5();
|
||||
connection.upload(uploadInfo.getHost(), uploadInfo.getToken(), containerName, blob);
|
||||
|
|
|
@ -22,7 +22,6 @@ import javax.inject.Inject;
|
|||
import javax.inject.Provider;
|
||||
|
||||
import org.jclouds.blobstore.config.BlobStoreObjectModule;
|
||||
import org.jclouds.encryption.EncryptionService;
|
||||
import org.jclouds.rackspace.cloudfiles.domain.CFObject;
|
||||
import org.jclouds.rackspace.cloudfiles.domain.MutableObjectInfoWithMetadata;
|
||||
import org.jclouds.rackspace.cloudfiles.domain.internal.CFObjectImpl;
|
||||
|
@ -50,14 +49,11 @@ public class CFObjectModule extends AbstractModule {
|
|||
}
|
||||
|
||||
private static class CFObjectFactory implements CFObject.Factory {
|
||||
@Inject
|
||||
EncryptionService encryptionService;
|
||||
@Inject
|
||||
Provider<MutableObjectInfoWithMetadata> metadataProvider;
|
||||
|
||||
public CFObject create(MutableObjectInfoWithMetadata metadata) {
|
||||
return new CFObjectImpl(encryptionService, metadata != null ? metadata : metadataProvider
|
||||
.get());
|
||||
return new CFObjectImpl(metadata != null ? metadata : metadataProvider.get());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -22,7 +22,6 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
|||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.jclouds.encryption.EncryptionService;
|
||||
import org.jclouds.http.Payload;
|
||||
import org.jclouds.http.PayloadEnclosing;
|
||||
import org.jclouds.http.internal.PayloadEnclosingImpl;
|
||||
|
@ -45,8 +44,8 @@ public class CFObjectImpl extends PayloadEnclosingImpl implements CFObject, Comp
|
|||
private Multimap<String, String> allHeaders = LinkedHashMultimap.create();
|
||||
|
||||
@Inject
|
||||
public CFObjectImpl(EncryptionService encryptionService, MutableObjectInfoWithMetadata info) {
|
||||
super(encryptionService);
|
||||
public CFObjectImpl(MutableObjectInfoWithMetadata info) {
|
||||
super();
|
||||
this.info = linkMetadataToThis(info);
|
||||
this._info = this.info.getDelegate();
|
||||
|
||||
|
|
|
@ -386,7 +386,7 @@ public class CloudFilesClientLiveTest extends BaseBlobStoreIntegrationTest {
|
|||
CFObject object = getApi().newCFObject();
|
||||
object.getInfo().setName(key);
|
||||
object.setPayload(data);
|
||||
object.generateMD5();
|
||||
context.utils().encryption().generateMD5BufferingIfNotRepeatable(object);
|
||||
object.getInfo().setContentType("text/plain");
|
||||
object.getInfo().getMetadata().put("Metadata", "metadata-value");
|
||||
return object;
|
||||
|
|
|
@ -102,7 +102,7 @@ public class BlobStoreFileObject extends AbstractFileObject {
|
|||
protected void onClose() throws IOException {
|
||||
try {
|
||||
blob.setPayload(file);
|
||||
blob.generateMD5();
|
||||
context.getContext().utils().encryption().generateMD5BufferingIfNotRepeatable(blob);
|
||||
logger.info(String.format(">> put: %s/%s %d bytes", getContainer(),
|
||||
getNameTrimLeadingSlashes(), blob.getPayload().getContentLength()));
|
||||
String tag = context.putBlob(getContainer(), blob);
|
||||
|
|
Loading…
Reference in New Issue