diff --git a/atmos/src/main/java/org/jclouds/atmosonline/saas/config/AtmosObjectModule.java b/atmos/src/main/java/org/jclouds/atmosonline/saas/config/AtmosObjectModule.java index 5a32e60cda..c0a3da1a48 100644 --- a/atmos/src/main/java/org/jclouds/atmosonline/saas/config/AtmosObjectModule.java +++ b/atmos/src/main/java/org/jclouds/atmosonline/saas/config/AtmosObjectModule.java @@ -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 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); } } diff --git a/atmos/src/main/java/org/jclouds/atmosonline/saas/domain/internal/AtmosObjectImpl.java b/atmos/src/main/java/org/jclouds/atmosonline/saas/domain/internal/AtmosObjectImpl.java index b342eb7d74..eafe12b2b0 100644 --- a/atmos/src/main/java/org/jclouds/atmosonline/saas/domain/internal/AtmosObjectImpl.java +++ b/atmos/src/main/java/org/jclouds/atmosonline/saas/domain/internal/AtmosObjectImpl.java @@ -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 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()); } /** diff --git a/atmos/src/test/java/org/jclouds/atmosonline/saas/AtmosStorageClientLiveTest.java b/atmos/src/test/java/org/jclouds/atmosonline/saas/AtmosStorageClientLiveTest.java index c9e618bd53..720c9f6880 100644 --- a/atmos/src/test/java/org/jclouds/atmosonline/saas/AtmosStorageClientLiveTest.java +++ b/atmos/src/test/java/org/jclouds/atmosonline/saas/AtmosStorageClientLiveTest.java @@ -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 - . of(new Log4JLoggingModule())); - RestContext context = blobStoreContext + context = new BlobStoreContextFactory().createContext("atmosonline", identity, credential, + ImmutableSet. of(new Log4JLoggingModule())); + RestContext 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); diff --git a/aws/core/src/main/java/org/jclouds/aws/s3/config/S3ObjectModule.java b/aws/core/src/main/java/org/jclouds/aws/s3/config/S3ObjectModule.java index e2a60aa98c..a8fa2be17a 100644 --- a/aws/core/src/main/java/org/jclouds/aws/s3/config/S3ObjectModule.java +++ b/aws/core/src/main/java/org/jclouds/aws/s3/config/S3ObjectModule.java @@ -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 metadataProvider; public S3Object create(MutableObjectMetadata metadata) { - return new S3ObjectImpl(encryptionService, metadata != null ? metadata : metadataProvider - .get()); + return new S3ObjectImpl(metadata != null ? metadata : metadataProvider.get()); } } diff --git a/aws/core/src/main/java/org/jclouds/aws/s3/domain/internal/S3ObjectImpl.java b/aws/core/src/main/java/org/jclouds/aws/s3/domain/internal/S3ObjectImpl.java index 121d76d9df..63181bb697 100644 --- a/aws/core/src/main/java/org/jclouds/aws/s3/domain/internal/S3ObjectImpl.java +++ b/aws/core/src/main/java/org/jclouds/aws/s3/domain/internal/S3ObjectImpl.java @@ -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 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(); } diff --git a/azure/src/main/java/org/jclouds/azure/storage/blob/config/AzureBlobModule.java b/azure/src/main/java/org/jclouds/azure/storage/blob/config/AzureBlobModule.java index 5aaac92ebc..9b155836a0 100644 --- a/azure/src/main/java/org/jclouds/azure/storage/blob/config/AzureBlobModule.java +++ b/azure/src/main/java/org/jclouds/azure/storage/blob/config/AzureBlobModule.java @@ -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 metadataProvider; public AzureBlob create(MutableBlobProperties metadata) { - return new AzureBlobImpl(encryptionService, metadata != null ? metadata : metadataProvider - .get()); + return new AzureBlobImpl(metadata != null ? metadata : metadataProvider.get()); } } diff --git a/azure/src/main/java/org/jclouds/azure/storage/blob/domain/internal/AzureBlobImpl.java b/azure/src/main/java/org/jclouds/azure/storage/blob/domain/internal/AzureBlobImpl.java index c970e888f4..3ffec753f8 100644 --- a/azure/src/main/java/org/jclouds/azure/storage/blob/domain/internal/AzureBlobImpl.java +++ b/azure/src/main/java/org/jclouds/azure/storage/blob/domain/internal/AzureBlobImpl.java @@ -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 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(); } diff --git a/azure/src/test/java/org/jclouds/azure/storage/blob/AzureBlobClientLiveTest.java b/azure/src/test/java/org/jclouds/azure/storage/blob/AzureBlobClientLiveTest.java index 067008d181..0d45f1ea67 100644 --- a/azure/src/test/java/org/jclouds/azure/storage/blob/AzureBlobClientLiveTest.java +++ b/azure/src/test/java/org/jclouds/azure/storage/blob/AzureBlobClientLiveTest.java @@ -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. of(new Log4JLoggingModule())) - .getProviderSpecificContext().getApi(); + context = new BlobStoreContextFactory().createContext("azureblob", identity, credential, + ImmutableSet. 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 diff --git a/blobstore/src/main/clojure/org/jclouds/blobstore.clj b/blobstore/src/main/clojure/org/jclouds/blobstore.clj index 9c1977090f..f4c38e86b7 100644 --- a/blobstore/src/main/clojure/org/jclouds/blobstore.clj +++ b/blobstore/src/main/clojure/org/jclouds/blobstore.clj @@ -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]]} diff --git a/blobstore/src/main/java/org/jclouds/blobstore/config/BlobStoreMapModule.java b/blobstore/src/main/java/org/jclouds/blobstore/config/BlobStoreMapModule.java index 016ed12c25..77ce77b62c 100644 --- a/blobstore/src/main/java/org/jclouds/blobstore/config/BlobStoreMapModule.java +++ b/blobstore/src/main/java/org/jclouds/blobstore/config/BlobStoreMapModule.java @@ -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); } } diff --git a/blobstore/src/main/java/org/jclouds/blobstore/config/BlobStoreObjectModule.java b/blobstore/src/main/java/org/jclouds/blobstore/config/BlobStoreObjectModule.java index 76624bdeb4..8d691b7718 100644 --- a/blobstore/src/main/java/org/jclouds/blobstore/config/BlobStoreObjectModule.java +++ b/blobstore/src/main/java/org/jclouds/blobstore/config/BlobStoreObjectModule.java @@ -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 metadataProvider; public Blob create(MutableBlobMetadata metadata) { - return new BlobImpl(encryptionService, metadata != null ? metadata : metadataProvider - .get()); + return new BlobImpl(metadata != null ? metadata : metadataProvider.get()); } } diff --git a/blobstore/src/main/java/org/jclouds/blobstore/domain/internal/BlobImpl.java b/blobstore/src/main/java/org/jclouds/blobstore/domain/internal/BlobImpl.java index 9a464c40c3..1996b26c13 100644 --- a/blobstore/src/main/java/org/jclouds/blobstore/domain/internal/BlobImpl.java +++ b/blobstore/src/main/java/org/jclouds/blobstore/domain/internal/BlobImpl.java @@ -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 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(); } diff --git a/blobstore/src/main/java/org/jclouds/blobstore/functions/ObjectMD5.java b/blobstore/src/main/java/org/jclouds/blobstore/functions/ObjectMD5.java index cf7f65768d..dbded887ac 100644 --- a/blobstore/src/main/java/org/jclouds/blobstore/functions/ObjectMD5.java +++ b/blobstore/src/main/java/org/jclouds/blobstore/functions/ObjectMD5.java @@ -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 { 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.setPayload(Payloads.newPayload(from)); } if (object.getMetadata().getContentMD5() == null) - object.generateMD5(); + encryptionService.generateMD5BufferingIfNotRepeatable(object); return object.getPayload().getContentMD5(); } diff --git a/blobstore/src/main/java/org/jclouds/blobstore/internal/InputStreamMapImpl.java b/blobstore/src/main/java/org/jclouds/blobstore/internal/InputStreamMapImpl.java index b43ee58e13..bdd332a8f6 100755 --- a/blobstore/src/main/java/org/jclouds/blobstore/internal/InputStreamMapImpl.java +++ b/blobstore/src/main/java/org/jclouds/blobstore/internal/InputStreamMapImpl.java @@ -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 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 implements Inpu new Function, Blob>() { @Override public Blob apply(Map.Entry 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 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; } diff --git a/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseBlobIntegrationTest.java b/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseBlobIntegrationTest.java index a81fd7657f..001259cb0c 100755 --- a/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseBlobIntegrationTest.java +++ b/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseBlobIntegrationTest.java @@ -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 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 { diff --git a/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseBlobMapIntegrationTest.java b/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseBlobMapIntegrationTest.java index 426ad78dc8..4d14b3d54d 100755 --- a/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseBlobMapIntegrationTest.java +++ b/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseBlobMapIntegrationTest.java @@ -59,15 +59,15 @@ public abstract class BaseBlobMapIntegrationTest extends BaseMapIntegrationTest< putFiveStrings(map); putFiveStringsUnderPath(map); - Collection values = map.values(); + Collection blobs = map.values(); assertConsistencyAwareMapSize(map, 5); - Set valuesAsString = new HashSet(); - for (Blob object : values) { - valuesAsString.add(getContentAsStringOrNullAndClose(object)); + Set blobsAsString = new HashSet(); + 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 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 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 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 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 map = createMap(context, bucketName); Map newMap = new HashMap(); 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 newMap = new HashMap(); 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 map, String key, String value) { - Blob object = context.getBlobStore().newBlob(key); - object.setPayload(value); - object.generateMD5(); - map.put(key, object); + protected void putStringWithMD5(Map 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 map) { Map newMap = new HashMap(); for (Map.Entry 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 map) { Map newMap = new HashMap(); for (Map.Entry 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); } diff --git a/core/src/main/java/org/jclouds/encryption/EncryptionService.java b/core/src/main/java/org/jclouds/encryption/EncryptionService.java index e5609bc1a3..064fe3e47b 100644 --- a/core/src/main/java/org/jclouds/encryption/EncryptionService.java +++ b/core/src/main/java/org/jclouds/encryption/EncryptionService.java @@ -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. + *

+ *

Note

+ *

+ * If this is an InputStream, it will be converted to a byte array first. + */ + T generateMD5BufferingIfNotRepeatable(T payloadEnclosing); + Payload generateMD5BufferingIfNotRepeatable(Payload in); ByteArrayPayload generatePayloadWithMD5For(InputStream toEncode); diff --git a/core/src/main/java/org/jclouds/encryption/internal/BaseEncryptionService.java b/core/src/main/java/org/jclouds/encryption/internal/BaseEncryptionService.java index dd3be41da8..4cf7f0052f 100755 --- a/core/src/main/java/org/jclouds/encryption/internal/BaseEncryptionService.java +++ b/core/src/main/java/org/jclouds/encryption/internal/BaseEncryptionService.java @@ -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 generateMD5BufferingIfNotRepeatable(T payloadEnclosing) { + checkState(payloadEnclosing != null, "payloadEnclosing"); + Payload newPayload = generateMD5BufferingIfNotRepeatable(payloadEnclosing.getPayload()); + if (newPayload != payloadEnclosing.getPayload()) + payloadEnclosing.setPayload(newPayload); + return payloadEnclosing; + } } diff --git a/core/src/main/java/org/jclouds/http/HttpRequest.java b/core/src/main/java/org/jclouds/http/HttpRequest.java index f161b1dd4e..5a4bccda4f 100644 --- a/core/src/main/java/org/jclouds/http/HttpRequest.java +++ b/core/src/main/java/org/jclouds/http/HttpRequest.java @@ -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 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 headers = Multimaps.synchronizedMultimap(LinkedHashMultimap + . create()); + + public Multimap getHeaders() { + return headers; + } + + /** + * try to get the value, then try as lowercase. + */ + public String getFirstHeaderOrNull(String string) { + Collection 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; diff --git a/core/src/main/java/org/jclouds/http/PayloadEnclosing.java b/core/src/main/java/org/jclouds/http/PayloadEnclosing.java index 09886749c1..2faf579a84 100644 --- a/core/src/main/java/org/jclouds/http/PayloadEnclosing.java +++ b/core/src/main/java/org/jclouds/http/PayloadEnclosing.java @@ -47,13 +47,4 @@ public interface PayloadEnclosing { Payload getPayload(); - /** - * generate an MD5 Hash for the current data. - *

- *

Note

- *

- * If this is an InputStream, it will be converted to a byte array first. - */ - void generateMD5(); - } \ No newline at end of file diff --git a/core/src/main/java/org/jclouds/http/internal/PayloadEnclosingImpl.java b/core/src/main/java/org/jclouds/http/internal/PayloadEnclosingImpl.java index dfff0797cd..9b579de3d2 100644 --- a/core/src/main/java/org/jclouds/http/internal/PayloadEnclosingImpl.java +++ b/core/src/main/java/org/jclouds/http/internal/PayloadEnclosingImpl.java @@ -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(); + } } diff --git a/core/src/test/java/org/jclouds/rest/internal/RestAnnotationProcessorTest.java b/core/src/test/java/org/jclouds/rest/internal/RestAnnotationProcessorTest.java index 8eddd95d44..bc9c24a483 100755 --- a/core/src/test/java/org/jclouds/rest/internal/RestAnnotationProcessorTest.java +++ b/core/src/test/java/org/jclouds/rest/internal/RestAnnotationProcessorTest.java @@ -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 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, diff --git a/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/domain/internal/PCSFileImpl.java b/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/domain/internal/PCSFileImpl.java index 28271884ff..deabf3bc1f 100644 --- a/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/domain/internal/PCSFileImpl.java +++ b/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/domain/internal/PCSFileImpl.java @@ -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; } diff --git a/nirvanix/sdn/core/src/test/java/org/jclouds/nirvanix/sdn/SDNClientLiveTest.java b/nirvanix/sdn/core/src/test/java/org/jclouds/nirvanix/sdn/SDNClientLiveTest.java index d611c5de86..68b9c0c3ae 100644 --- a/nirvanix/sdn/core/src/test/java/org/jclouds/nirvanix/sdn/SDNClientLiveTest.java +++ b/nirvanix/sdn/core/src/test/java/org/jclouds/nirvanix/sdn/SDNClientLiveTest.java @@ -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); diff --git a/rackspace/src/main/java/org/jclouds/rackspace/cloudfiles/config/CFObjectModule.java b/rackspace/src/main/java/org/jclouds/rackspace/cloudfiles/config/CFObjectModule.java index 66d376b622..f033d73405 100644 --- a/rackspace/src/main/java/org/jclouds/rackspace/cloudfiles/config/CFObjectModule.java +++ b/rackspace/src/main/java/org/jclouds/rackspace/cloudfiles/config/CFObjectModule.java @@ -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 metadataProvider; public CFObject create(MutableObjectInfoWithMetadata metadata) { - return new CFObjectImpl(encryptionService, metadata != null ? metadata : metadataProvider - .get()); + return new CFObjectImpl(metadata != null ? metadata : metadataProvider.get()); } } diff --git a/rackspace/src/main/java/org/jclouds/rackspace/cloudfiles/domain/internal/CFObjectImpl.java b/rackspace/src/main/java/org/jclouds/rackspace/cloudfiles/domain/internal/CFObjectImpl.java index 87c60aaafd..c8a3ff031a 100644 --- a/rackspace/src/main/java/org/jclouds/rackspace/cloudfiles/domain/internal/CFObjectImpl.java +++ b/rackspace/src/main/java/org/jclouds/rackspace/cloudfiles/domain/internal/CFObjectImpl.java @@ -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 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(); diff --git a/rackspace/src/test/java/org/jclouds/rackspace/cloudfiles/CloudFilesClientLiveTest.java b/rackspace/src/test/java/org/jclouds/rackspace/cloudfiles/CloudFilesClientLiveTest.java index 84d2ffc370..ec66facf2a 100644 --- a/rackspace/src/test/java/org/jclouds/rackspace/cloudfiles/CloudFilesClientLiveTest.java +++ b/rackspace/src/test/java/org/jclouds/rackspace/cloudfiles/CloudFilesClientLiveTest.java @@ -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; diff --git a/tools/vfs/src/main/java/org/jclouds/vfs/provider/blobstore/BlobStoreFileObject.java b/tools/vfs/src/main/java/org/jclouds/vfs/provider/blobstore/BlobStoreFileObject.java index b66d673996..de4b405996 100644 --- a/tools/vfs/src/main/java/org/jclouds/vfs/provider/blobstore/BlobStoreFileObject.java +++ b/tools/vfs/src/main/java/org/jclouds/vfs/provider/blobstore/BlobStoreFileObject.java @@ -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);