From 6f180ddb4e1449f969469598d6640d3d67aaf7ee Mon Sep 17 00:00:00 2001 From: Adrian Cole Date: Sun, 1 Aug 2010 02:07:53 -0700 Subject: [PATCH] Issu 301: refactored utilities that depend on guava. introduced Crypto, CryptoStreams, and more Payloads to help deal with encrypted payloads and headers --- .../__providerName__RestClientModule.java | 6 +- .../saas/binders/BindMetadataToHeaders.java | 4 +- .../saas/blobstore/AtmosAsyncBlobStore.java | 30 +- .../saas/blobstore/AtmosBlobStore.java | 10 +- .../strategy/FindMD5InUserMetadata.java | 6 +- .../atmosonline/saas/domain/AtmosObject.java | 2 +- .../saas/domain/internal/AtmosObjectImpl.java | 2 +- .../atmosonline/saas/filters/SignRequest.java | 38 +- .../ParseSystemMetadataFromHeaders.java | 33 +- .../saas/util/AtmosStorageUtils.java | 24 +- .../saas/AtmosStorageClientLiveTest.java | 96 ++- .../ParseSystemMetadataFromHeadersTest.java | 28 +- .../internal/StubAtmosStorageAsyncClient.java | 18 +- .../BindS3UploadPolicyAndSignature.java | 11 +- .../EC2ComputeServiceContextModule.java | 3 +- .../strategy/DescribeImagesParallel.java | 2 +- ...rtUnencodedBytesToBase64EncodedString.java | 11 +- .../ec2/xml/UnencodeStringValueHandler.java | 10 +- .../org/jclouds/aws/filters/FormSigner.java | 39 +- .../aws/s3/blobstore/S3AsyncBlobStore.java | 17 +- .../org/jclouds/aws/s3/domain/S3Object.java | 2 +- .../aws/s3/domain/internal/S3ObjectImpl.java | 2 +- .../s3/filters/RequestAuthorizeSignature.java | 44 +- .../ParseObjectMetadataFromHeaders.java | 12 +- .../jclouds/aws/s3/xml/ListBucketHandler.java | 16 +- .../org/jclouds/aws/sqs/xml/MD5Handler.java | 13 +- .../jclouds/aws/sqs/xml/RegexMD5Handler.java | 8 +- .../aws/ec2/services/AMIClientLiveTest.java | 4 +- .../ParseObjectMetadataFromHeadersTest.java | 29 +- .../aws/s3/internal/StubS3AsyncClient.java | 8 +- .../aws/s3/xml/ListBucketHandlerTest.java | 102 ++-- .../jclouds/aws/sqs/SQSClientLiveTest.java | 19 +- .../java/org/jclouds/aws/sqs/SpeedTest.java | 47 +- .../blob/blobstore/AzureAsyncBlobStore.java | 29 +- .../azure/storage/blob/domain/AzureBlob.java | 2 +- .../blob/domain/internal/AzureBlobImpl.java | 2 +- ...ontainerNameEnumerationResultsHandler.java | 26 +- .../filters/SharedKeyLiteAuthentication.java | 36 +- .../storage/blob/AzureBlobClientLiveTest.java | 64 +- .../main/clojure/org/jclouds/blobstore.clj | 47 +- .../blobstore/TransientAsyncBlobStore.java | 44 +- .../blobstore/config/BlobStoreMapModule.java | 6 +- .../org/jclouds/blobstore/domain/Blob.java | 2 +- .../blobstore/domain/internal/BlobImpl.java | 2 +- .../blobstore/functions/ObjectMD5.java | 17 +- .../internal/BaseAsyncBlobStore.java | 13 +- .../internal/InputStreamMapImpl.java | 17 +- .../internal/DeleteAllKeysInList.java | 2 +- .../strategy/internal/FetchBlobMetadata.java | 2 +- .../GetAllBlobsInListAndRetryOnFailure.java | 2 +- .../MarkersDeleteDirectoryStrategy.java | 2 +- .../internal/PutBlobsStrategyImpl.java | 2 +- .../internal/BaseBlobIntegrationTest.java | 43 +- .../internal/BaseBlobLiveTest.java | 19 +- .../internal/BaseBlobMapIntegrationTest.java | 17 +- .../BaseContainerIntegrationTest.java | 11 +- .../internal/BaseMapIntegrationTest.java | 10 +- .../binders/BindChecksumsToJsonPayload.java | 14 +- .../chef/config/BaseChefRestClientModule.java | 15 +- .../jclouds/chef/config/ChefParserModule.java | 49 +- .../chef/filters/SignedHeaderAuth.java | 21 +- .../DeleteAllClientsAndNodesInListImpl.java | 2 +- .../chef/strategy/internal/GetNodesImpl.java | 2 +- .../ohai/functions/ByteArrayToMacAddress.java | 12 +- .../org/jclouds/chef/ChefAsyncClientTest.java | 9 +- .../org/jclouds/chef/ChefClientLiveTest.java | 13 +- .../BindHexEncodedMD5sToJsonPayloadTest.java | 5 +- .../chef/filters/SignedHeaderAuthTest.java | 8 +- .../functions/ParseClientFromJsonTest.java | 28 +- .../ParseCookbookVersionFromJsonTest.java | 83 +-- .../ParseUploadSandboxFromJsonTest.java | 33 +- .../functions/ByteArrayToMacAddressTest.java | 6 +- .../servlet/ChefRegistrationListener.java | 11 +- .../compute/internal/BaseComputeService.java | 4 +- .../jclouds/compute/internal/UtilsImpl.java | 4 +- .../jclouds/compute/util/ComputeUtils.java | 2 +- core/src/main/clojure/org/jclouds/core.clj | 2 +- .../jclouds/concurrent/ConcurrentUtils.java | 561 ------------------ .../jclouds/concurrent/FutureIterables.java | 185 ++++++ .../java/org/jclouds/concurrent/Futures.java | 248 ++++++++ .../org/jclouds/concurrent/MoreExecutors.java | 199 +++++++ .../config/ExecutorServiceModule.java | 6 +- .../main/java/org/jclouds/crypto/Crypto.java | 60 ++ .../org/jclouds/crypto/CryptoStreams.java | 318 ++++++++++ .../main/java/org/jclouds/crypto/Pems.java | 252 ++++++++ .../jclouds/encryption/EncryptionService.java | 102 ---- .../internal/BaseEncryptionService.java | 299 ---------- .../encryption/internal/JCECrypto.java | 135 +++++ .../internal/JCEEncryptionService.java | 202 ------- .../main/java/org/jclouds/http/HttpUtils.java | 91 ++- ...formingHttpCommandExecutorServiceImpl.java | 4 +- .../http/filters/BasicAuthentication.java | 8 +- .../BaseHttpCommandExecutorService.java | 18 +- .../JavaUrlHttpCommandExecutorService.java | 36 +- .../http/internal/PayloadEnclosingImpl.java | 2 +- .../java/org/jclouds/io/InputSuppliers.java | 74 +++ .../{http => io}/PayloadEnclosing.java | 3 +- .../main/java/org/jclouds/io/Payloads.java | 87 ++- .../io/payloads/BaseCipherPayload.java | 57 ++ .../io/payloads/RSADecryptingPayload.java | 58 ++ .../io/payloads/RSAEncryptingPayload.java | 58 ++ .../org/jclouds/json/config/GsonModule.java | 38 +- .../org/jclouds/logging/internal/Wire.java | 2 +- .../org/jclouds/rest/RestContextBuilder.java | 4 +- .../src/main/java/org/jclouds/rest/Utils.java | 8 +- .../internal/RestAnnotationProcessor.java | 2 +- .../org/jclouds/rest/internal/UtilsImpl.java | 10 +- .../concurrent/FutureExceptionParserTest.java | 6 +- ...tilsTest.java => FutureIterablesTest.java} | 18 +- .../FuturesComposePerformanceTest.java | 17 +- .../concurrent/FuturesTestingUtils.java | 6 +- .../RetryOnTimeOutExceptionSupplierTest.java | 3 +- .../concurrent/internal/SyncProxyTest.java | 12 +- .../org/jclouds/crypto/CryptoStreamsTest.java | 65 ++ .../java/org/jclouds/crypto/PemsTest.java | 91 +++ ...CommandExecutorServiceIntegrationTest.java | 78 ++- .../java/org/jclouds/http/BaseJettyTest.java | 52 +- .../http/filters/BasicAuthenticationTest.java | 4 +- .../BackoffLimitedRetryHandlerTest.java | 14 +- .../jclouds/http/internal/WireLiveTest.java | 43 +- .../CryptoTest.java} | 80 +-- .../org/jclouds/rest/BaseRestClientTest.java | 68 ++- .../internal/RestAnnotationProcessorTest.java | 56 +- .../jclouds/azure/azurequeue/SpeedTest.java | 8 +- .../ApacheHCHttpCommandExecutorService.java | 27 +- .../bouncycastle/BouncyCastleCrypto.java | 40 ++ .../BouncyCastleEncryptionService.java | 192 ------ ...ule.java => BouncyCastleCryptoModule.java} | 10 +- ...eTest.java => BouncyCastleCryptoTest.java} | 18 +- .../config/EnterpriseConfigurationModule.java | 4 +- .../AsyncGaeHttpCommandExecutorService.java | 6 +- .../org/jclouds/gae/ConvertToGaeRequest.java | 22 +- .../gae/GaeHttpCommandExecutorService.java | 7 +- .../GoogleAppEngineConfigurationModule.java | 5 +- ...CommandExecutorServiceIntegrationTest.java | 11 +- .../jclouds/gae/ConvertToGaeRequestTest.java | 10 +- .../gae/ConvertToJcloudsResponseTest.java | 10 +- .../ning/NingHttpCommandExecutorService.java | 35 +- .../filters/SharedKeyLiteAuthentication.java | 14 +- .../jclouds/mezeo/pcs2/domain/PCSFile.java | 2 +- .../sdn/SDNAuthenticationLiveTest.java | 10 +- .../nirvanix/sdn/SDNClientLiveTest.java | 6 +- .../filters/AddSessionTokenToRequestTest.java | 19 +- .../InsertUserContextIntoPathTest.java | 23 +- .../OpscodePlatformAsyncClientTest.java | 4 +- .../OpscodePlatformClientLiveTest.java | 9 +- .../blobstore/CloudFilesAsyncBlobStore.java | 28 +- .../functions/ObjectToBlobMetadata.java | 9 +- .../functions/ResourceToObjectInfo.java | 14 +- .../rackspace/cloudfiles/domain/CFObject.java | 2 +- .../domain/internal/CFObjectImpl.java | 2 +- .../functions/ParseObjectInfoFromHeaders.java | 13 +- .../RackspaceAuthenticationLiveTest.java | 9 +- .../cloudfiles/CloudFilesClientLiveTest.java | 23 +- ...rseObjectInfoListFromJsonResponseTest.java | 8 +- .../internal/StubCloudFilesAsyncClient.java | 8 +- .../slicehost/filters/SlicehostBasic.java | 8 +- .../blobstore/BlobStoreFileObject.java | 55 +- .../functions/AllCatalogItemsInCatalog.java | 2 +- .../functions/AllCatalogsInOrganization.java | 2 +- .../functions/AllVDCsInOrganization.java | 2 +- .../functions/OrganizatonsForLocations.java | 2 +- .../VAppTemplatesForCatalogItems.java | 2 +- .../VAppTemplatesForResourceEntities.java | 2 +- .../jclouds/vcloud/VCloudLoginLiveTest.java | 14 +- .../vcloud/VCloudVersionsLiveTest.java | 17 +- 166 files changed, 3101 insertions(+), 2789 deletions(-) delete mode 100644 core/src/main/java/org/jclouds/concurrent/ConcurrentUtils.java create mode 100644 core/src/main/java/org/jclouds/concurrent/FutureIterables.java create mode 100644 core/src/main/java/org/jclouds/concurrent/Futures.java create mode 100644 core/src/main/java/org/jclouds/concurrent/MoreExecutors.java create mode 100644 core/src/main/java/org/jclouds/crypto/Crypto.java create mode 100644 core/src/main/java/org/jclouds/crypto/CryptoStreams.java create mode 100644 core/src/main/java/org/jclouds/crypto/Pems.java delete mode 100644 core/src/main/java/org/jclouds/encryption/EncryptionService.java delete mode 100755 core/src/main/java/org/jclouds/encryption/internal/BaseEncryptionService.java create mode 100755 core/src/main/java/org/jclouds/encryption/internal/JCECrypto.java delete mode 100644 core/src/main/java/org/jclouds/encryption/internal/JCEEncryptionService.java create mode 100644 core/src/main/java/org/jclouds/io/InputSuppliers.java rename core/src/main/java/org/jclouds/{http => io}/PayloadEnclosing.java (96%) create mode 100644 core/src/main/java/org/jclouds/io/payloads/BaseCipherPayload.java create mode 100644 core/src/main/java/org/jclouds/io/payloads/RSADecryptingPayload.java create mode 100644 core/src/main/java/org/jclouds/io/payloads/RSAEncryptingPayload.java rename core/src/test/java/org/jclouds/concurrent/{ConcurrentUtilsTest.java => FutureIterablesTest.java} (87%) create mode 100644 core/src/test/java/org/jclouds/crypto/CryptoStreamsTest.java create mode 100644 core/src/test/java/org/jclouds/crypto/PemsTest.java rename core/src/test/java/org/jclouds/{encryption/EncryptionServiceTest.java => io/CryptoTest.java} (61%) create mode 100644 extensions/bouncycastle/src/main/java/org/jclouds/encryption/bouncycastle/BouncyCastleCrypto.java delete mode 100644 extensions/bouncycastle/src/main/java/org/jclouds/encryption/bouncycastle/BouncyCastleEncryptionService.java rename extensions/bouncycastle/src/main/java/org/jclouds/encryption/bouncycastle/config/{BouncyCastleEncryptionServiceModule.java => BouncyCastleCryptoModule.java} (73%) rename extensions/bouncycastle/src/test/java/org/jclouds/encryption/bouncycastle/{BouncyCastleEncryptionServiceTest.java => BouncyCastleCryptoTest.java} (66%) diff --git a/archetypes/json-client-archetype/src/main/resources/archetype-resources/src/main/java/config/__providerName__RestClientModule.java b/archetypes/json-client-archetype/src/main/resources/archetype-resources/src/main/java/config/__providerName__RestClientModule.java index c2999d1c3b..9cd82e3cce 100644 --- a/archetypes/json-client-archetype/src/main/resources/archetype-resources/src/main/java/config/__providerName__RestClientModule.java +++ b/archetypes/json-client-archetype/src/main/resources/archetype-resources/src/main/java/config/__providerName__RestClientModule.java @@ -56,7 +56,7 @@ import org.jclouds.http.annotation.ServerError; import org.jclouds.http.filters.BasicAuthentication; import org.jclouds.rest.ConfiguresRestClient; import org.jclouds.rest.config.RestClientModule; -import org.jclouds.encryption.EncryptionService; +import org.jclouds.crypto.Crypto; import ${package}.${providerName}; import ${package}.${providerName}Client; @@ -85,9 +85,9 @@ public class ${providerName}RestClientModule extends public BasicAuthentication provideBasicAuthentication( @Named(${providerName}Constants.PROPERTY_${ucaseProviderName}_USER) String user, @Named(${providerName}Constants.PROPERTY_${ucaseProviderName}_PASSWORD) String password, - EncryptionService encryptionService) + Crypto crypto) throws UnsupportedEncodingException { - return new BasicAuthentication(user, password, encryptionService); + return new BasicAuthentication(user, password, crypto); } @Provides diff --git a/atmos/src/main/java/org/jclouds/atmosonline/saas/binders/BindMetadataToHeaders.java b/atmos/src/main/java/org/jclouds/atmosonline/saas/binders/BindMetadataToHeaders.java index 4423aa7c5f..001dcf8453 100644 --- a/atmos/src/main/java/org/jclouds/atmosonline/saas/binders/BindMetadataToHeaders.java +++ b/atmos/src/main/java/org/jclouds/atmosonline/saas/binders/BindMetadataToHeaders.java @@ -22,7 +22,7 @@ import javax.inject.Inject; import javax.inject.Singleton; import org.jclouds.atmosonline.saas.domain.AtmosObject; -import org.jclouds.encryption.EncryptionService; +import org.jclouds.crypto.Crypto; import org.jclouds.http.HttpRequest; import org.jclouds.rest.Binder; @@ -32,7 +32,7 @@ public class BindMetadataToHeaders implements Binder { @Inject protected BindMetadataToHeaders(BindUserMetadataToHeaders metaBinder, - EncryptionService encryptionService) { + Crypto crypto) { this.metaBinder = metaBinder; } diff --git a/atmos/src/main/java/org/jclouds/atmosonline/saas/blobstore/AtmosAsyncBlobStore.java b/atmos/src/main/java/org/jclouds/atmosonline/saas/blobstore/AtmosAsyncBlobStore.java index 85096fbc03..caea28ed43 100644 --- a/atmos/src/main/java/org/jclouds/atmosonline/saas/blobstore/AtmosAsyncBlobStore.java +++ b/atmos/src/main/java/org/jclouds/atmosonline/saas/blobstore/AtmosAsyncBlobStore.java @@ -19,8 +19,6 @@ package org.jclouds.atmosonline.saas.blobstore; import static com.google.common.base.Preconditions.checkNotNull; -import static org.jclouds.concurrent.ConcurrentUtils.compose; -import static org.jclouds.concurrent.ConcurrentUtils.makeListenable; import java.net.URI; import java.util.Set; @@ -54,8 +52,9 @@ import org.jclouds.blobstore.functions.BlobToHttpGetOptions; import org.jclouds.blobstore.internal.BaseAsyncBlobStore; import org.jclouds.blobstore.strategy.internal.FetchBlobMetadata; import org.jclouds.blobstore.util.BlobUtils; +import org.jclouds.concurrent.Futures; +import org.jclouds.crypto.Crypto; import org.jclouds.domain.Location; -import org.jclouds.encryption.EncryptionService; import org.jclouds.http.options.GetOptions; import com.google.common.base.Function; @@ -73,7 +72,7 @@ public class AtmosAsyncBlobStore extends BaseAsyncBlobStore { private final BlobToObject blob2Object; private final BlobStoreListOptionsToListOptions container2ContainerListOptions; private final DirectoryEntryListToResourceMetadataList container2ResourceList; - private final EncryptionService encryptionService; + private final Crypto crypto; private final BlobToHttpGetOptions blob2ObjectGetOptions; private final Provider fetchBlobMetadataProvider; @@ -83,7 +82,7 @@ public class AtmosAsyncBlobStore extends BaseAsyncBlobStore { Set locations, AtmosStorageAsyncClient async, AtmosStorageClient sync, ObjectToBlob object2Blob, ObjectToBlobMetadata object2BlobMd, BlobToObject blob2Object, BlobStoreListOptionsToListOptions container2ContainerListOptions, - DirectoryEntryListToResourceMetadataList container2ResourceList, EncryptionService encryptionService, + DirectoryEntryListToResourceMetadataList container2ResourceList, Crypto crypto, BlobToHttpGetOptions blob2ObjectGetOptions, Provider fetchBlobMetadataProvider) { super(context, blobUtils, service, defaultLocation, locations); this.blob2ObjectGetOptions = checkNotNull(blob2ObjectGetOptions, "blob2ObjectGetOptions"); @@ -95,7 +94,7 @@ public class AtmosAsyncBlobStore extends BaseAsyncBlobStore { this.object2Blob = checkNotNull(object2Blob, "object2Blob"); this.blob2Object = checkNotNull(blob2Object, "blob2Object"); this.object2BlobMd = checkNotNull(object2BlobMd, "object2BlobMd"); - this.encryptionService = checkNotNull(encryptionService, "encryptionService"); + this.crypto = checkNotNull(crypto, "crypto"); this.fetchBlobMetadataProvider = checkNotNull(fetchBlobMetadataProvider, "fetchBlobMetadataProvider"); } @@ -104,7 +103,7 @@ public class AtmosAsyncBlobStore extends BaseAsyncBlobStore { */ @Override public ListenableFuture blobMetadata(String container, String key) { - return compose(async.headFile(container + "/" + key), new Function() { + return Futures.compose(async.headFile(container + "/" + key), new Function() { @Override public BlobMetadata apply(AtmosObject from) { return object2BlobMd.apply(from); @@ -119,7 +118,7 @@ public class AtmosAsyncBlobStore extends BaseAsyncBlobStore { */ @Override public ListenableFuture createContainerInLocation(Location location, String container) { - return compose(async.createDirectory(container), new Function() { + return Futures.compose(async.createDirectory(container), new Function() { public Boolean apply(URI from) { return true; @@ -133,7 +132,7 @@ public class AtmosAsyncBlobStore extends BaseAsyncBlobStore { */ @Override public ListenableFuture createDirectory(String container, String directory) { - return compose(async.createDirectory(container + "/" + directory), new Function() { + return Futures.compose(async.createDirectory(container + "/" + directory), new Function() { public Void apply(URI from) { return null;// no etag @@ -195,7 +194,7 @@ public class AtmosAsyncBlobStore extends BaseAsyncBlobStore { public ListenableFuture getBlob(String container, String key, org.jclouds.blobstore.options.GetOptions options) { GetOptions httpOptions = blob2ObjectGetOptions.apply(options); ListenableFuture returnVal = async.readFile(container + "/" + key, httpOptions); - return compose(returnVal, object2Blob, service); + return Futures.compose(returnVal, object2Blob, service); } /** @@ -203,7 +202,7 @@ public class AtmosAsyncBlobStore extends BaseAsyncBlobStore { */ @Override public ListenableFuture> list() { - return compose(async.listDirectories(), container2ResourceList, service); + return Futures.compose(async.listDirectories(), container2ResourceList, service); } /** @@ -215,8 +214,9 @@ public class AtmosAsyncBlobStore extends BaseAsyncBlobStore { container = AtmosStorageUtils.adjustContainerIfDirOptionPresent(container, options); ListOptions nativeOptions = container2ContainerListOptions.apply(options); ListenableFuture> returnVal = async.listDirectory(container, nativeOptions); - ListenableFuture> list = compose(returnVal, container2ResourceList, service); - return (ListenableFuture>) (options.isDetailed() ? compose(list, + ListenableFuture> list = Futures.compose(returnVal, container2ResourceList, + service); + return (ListenableFuture>) (options.isDetailed() ? Futures.compose(list, fetchBlobMetadataProvider.get().setContainerName(container), service) : list); } @@ -227,11 +227,11 @@ public class AtmosAsyncBlobStore extends BaseAsyncBlobStore { */ @Override public ListenableFuture putBlob(final String container, final Blob blob) { - return makeListenable(service.submit(new Callable() { + return Futures.makeListenable(service.submit(new Callable() { @Override public String call() throws Exception { - return AtmosStorageUtils.putBlob(sync, encryptionService, blob2Object, container, blob); + return AtmosStorageUtils.putBlob(sync, crypto, blob2Object, container, blob); } diff --git a/atmos/src/main/java/org/jclouds/atmosonline/saas/blobstore/AtmosBlobStore.java b/atmos/src/main/java/org/jclouds/atmosonline/saas/blobstore/AtmosBlobStore.java index aaef78704f..a83d8682a9 100644 --- a/atmos/src/main/java/org/jclouds/atmosonline/saas/blobstore/AtmosBlobStore.java +++ b/atmos/src/main/java/org/jclouds/atmosonline/saas/blobstore/AtmosBlobStore.java @@ -44,8 +44,8 @@ import org.jclouds.blobstore.functions.BlobToHttpGetOptions; import org.jclouds.blobstore.internal.BaseBlobStore; import org.jclouds.blobstore.strategy.internal.FetchBlobMetadata; import org.jclouds.blobstore.util.BlobUtils; +import org.jclouds.crypto.Crypto; import org.jclouds.domain.Location; -import org.jclouds.encryption.EncryptionService; import org.jclouds.http.options.GetOptions; /** @@ -59,7 +59,7 @@ public class AtmosBlobStore extends BaseBlobStore { private final BlobToObject blob2Object; private final BlobStoreListOptionsToListOptions container2ContainerListOptions; private final DirectoryEntryListToResourceMetadataList container2ResourceList; - private final EncryptionService encryptionService; + private final Crypto crypto; private final BlobToHttpGetOptions blob2ObjectGetOptions; private final Provider fetchBlobMetadataProvider; @@ -69,7 +69,7 @@ public class AtmosBlobStore extends BaseBlobStore { ObjectToBlobMetadata object2BlobMd, BlobToObject blob2Object, BlobStoreListOptionsToListOptions container2ContainerListOptions, DirectoryEntryListToResourceMetadataList container2ResourceList, - EncryptionService encryptionService, BlobToHttpGetOptions blob2ObjectGetOptions, + Crypto crypto, BlobToHttpGetOptions blob2ObjectGetOptions, Provider fetchBlobMetadataProvider) { super(context, blobUtils, defaultLocation, locations); this.blob2ObjectGetOptions = checkNotNull(blob2ObjectGetOptions, "blob2ObjectGetOptions"); @@ -80,7 +80,7 @@ public class AtmosBlobStore extends BaseBlobStore { this.object2Blob = checkNotNull(object2Blob, "object2Blob"); this.blob2Object = checkNotNull(blob2Object, "blob2Object"); this.object2BlobMd = checkNotNull(object2BlobMd, "object2BlobMd"); - this.encryptionService = checkNotNull(encryptionService, "encryptionService"); + this.crypto = checkNotNull(crypto, "crypto"); this.fetchBlobMetadataProvider = checkNotNull(fetchBlobMetadataProvider, "fetchBlobMetadataProvider"); } @@ -204,7 +204,7 @@ public class AtmosBlobStore extends BaseBlobStore { */ @Override public String putBlob(final String container, final Blob blob) { - return AtmosStorageUtils.putBlob(sync, encryptionService, blob2Object, container, blob); + return AtmosStorageUtils.putBlob(sync, crypto, blob2Object, container, blob); } /** diff --git a/atmos/src/main/java/org/jclouds/atmosonline/saas/blobstore/strategy/FindMD5InUserMetadata.java b/atmos/src/main/java/org/jclouds/atmosonline/saas/blobstore/strategy/FindMD5InUserMetadata.java index d9e764ce5e..c67f6a993e 100644 --- a/atmos/src/main/java/org/jclouds/atmosonline/saas/blobstore/strategy/FindMD5InUserMetadata.java +++ b/atmos/src/main/java/org/jclouds/atmosonline/saas/blobstore/strategy/FindMD5InUserMetadata.java @@ -19,7 +19,7 @@ package org.jclouds.atmosonline.saas.blobstore.strategy; import static com.google.common.base.Preconditions.checkNotNull; -import static org.jclouds.concurrent.ConcurrentUtils.awaitCompletion; +import static org.jclouds.concurrent.FutureIterables.awaitCompletion; import java.util.Arrays; import java.util.Map; @@ -43,7 +43,7 @@ import org.jclouds.blobstore.internal.BlobRuntimeException; import org.jclouds.blobstore.options.ListContainerOptions; import org.jclouds.blobstore.strategy.ContainsValueInListStrategy; import org.jclouds.blobstore.strategy.ListBlobsInContainer; -import static org.jclouds.concurrent.ConcurrentUtils.*; +import org.jclouds.concurrent.Futures; import org.jclouds.logging.Logger; import com.google.common.base.Throwables; @@ -85,7 +85,7 @@ public class FindMD5InUserMetadata implements ContainsValueInListStrategy { final BlockingQueue queue = new SynchronousQueue(); Map> responses = Maps.newHashMap(); for (BlobMetadata md : getAllBlobMetadata.execute(containerName, options)) { - final ListenableFuture future = makeListenable(client.headFile(containerName + final ListenableFuture future = Futures.makeListenable(client.headFile(containerName + "/" + md.getName()), userExecutor); future.addListener(new Runnable() { public void run() { diff --git a/atmos/src/main/java/org/jclouds/atmosonline/saas/domain/AtmosObject.java b/atmos/src/main/java/org/jclouds/atmosonline/saas/domain/AtmosObject.java index 9928c6a18b..5d014a628d 100644 --- a/atmos/src/main/java/org/jclouds/atmosonline/saas/domain/AtmosObject.java +++ b/atmos/src/main/java/org/jclouds/atmosonline/saas/domain/AtmosObject.java @@ -18,7 +18,7 @@ */ package org.jclouds.atmosonline.saas.domain; -import org.jclouds.http.PayloadEnclosing; +import org.jclouds.io.PayloadEnclosing; import com.google.common.collect.Multimap; import com.google.inject.internal.Nullable; 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 6ac3226f43..6dec83ef57 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,9 +26,9 @@ 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.http.PayloadEnclosing; import org.jclouds.http.internal.PayloadEnclosingImpl; import org.jclouds.io.Payload; +import org.jclouds.io.PayloadEnclosing; import org.jclouds.io.payloads.DelegatingPayload; import com.google.common.collect.LinkedHashMultimap; diff --git a/atmos/src/main/java/org/jclouds/atmosonline/saas/filters/SignRequest.java b/atmos/src/main/java/org/jclouds/atmosonline/saas/filters/SignRequest.java index 06b728554f..96a86cab04 100644 --- a/atmos/src/main/java/org/jclouds/atmosonline/saas/filters/SignRequest.java +++ b/atmos/src/main/java/org/jclouds/atmosonline/saas/filters/SignRequest.java @@ -36,13 +36,15 @@ import javax.inject.Singleton; import javax.ws.rs.core.HttpHeaders; import org.jclouds.atmosonline.saas.reference.AtmosStorageHeaders; +import org.jclouds.crypto.Crypto; +import org.jclouds.crypto.CryptoStreams; import org.jclouds.date.TimeStamp; -import org.jclouds.encryption.EncryptionService; import org.jclouds.http.HttpException; import org.jclouds.http.HttpRequest; import org.jclouds.http.HttpRequestFilter; import org.jclouds.http.HttpUtils; import org.jclouds.http.internal.SignatureWire; +import org.jclouds.io.InputSuppliers; import org.jclouds.logging.Logger; import org.jclouds.util.Utils; @@ -62,7 +64,7 @@ public class SignRequest implements HttpRequestFilter { private final String uid; private final byte[] key; private final Provider timeStampProvider; - private final EncryptionService encryptionService; + private final Crypto crypto; private final HttpUtils utils; @Resource @@ -74,20 +76,19 @@ public class SignRequest implements HttpRequestFilter { @Inject public SignRequest(SignatureWire signatureWire, @Named(PROPERTY_IDENTITY) String uid, - @Named(PROPERTY_CREDENTIAL) String encodedKey, - @TimeStamp Provider timeStampProvider, EncryptionService encryptionService, - HttpUtils utils) { + @Named(PROPERTY_CREDENTIAL) String encodedKey, @TimeStamp Provider timeStampProvider, + Crypto crypto, HttpUtils utils) { this.signatureWire = signatureWire; this.uid = uid; - this.key = encryptionService.fromBase64(encodedKey); + this.key = CryptoStreams.base64(encodedKey); this.timeStampProvider = timeStampProvider; - this.encryptionService = encryptionService; + this.crypto = crypto; this.utils = utils; } public void filter(HttpRequest request) throws HttpException { - String toSign = replaceUIDHeader(request).removeOldSignature(request).replaceDateHeader( - request).createStringToSign(request); + String toSign = replaceUIDHeader(request).removeOldSignature(request).replaceDateHeader(request) + .createStringToSign(request); calculateAndReplaceAuthHeader(request, toSign); utils.logRequest(signatureLog, request, "<<"); } @@ -111,19 +112,17 @@ public class SignRequest implements HttpRequestFilter { return buffer.toString(); } - private void calculateAndReplaceAuthHeader(HttpRequest request, String toSign) - throws HttpException { + private void calculateAndReplaceAuthHeader(HttpRequest request, String toSign) throws HttpException { String signature = signString(toSign); if (signatureWire.enabled()) signatureWire.input(Utils.toInputStream(signature)); - request.getHeaders().replaceValues(AtmosStorageHeaders.SIGNATURE, - Collections.singletonList(signature)); + request.getHeaders().replaceValues(AtmosStorageHeaders.SIGNATURE, Collections.singletonList(signature)); } public String signString(String toSign) { String signature; try { - signature = encryptionService.base64(encryptionService.hmacSha1(toSign, key)); + signature = CryptoStreams.base64(CryptoStreams.mac(InputSuppliers.of(toSign), crypto.hmacSHA1(key))); } catch (Exception e) { throw new HttpException("error signing request", e); } @@ -140,8 +139,7 @@ public class SignRequest implements HttpRequestFilter { } SignRequest replaceDateHeader(HttpRequest request) { - request.getHeaders().replaceValues(HttpHeaders.DATE, - Collections.singletonList(timeStampProvider.get())); + request.getHeaders().replaceValues(HttpHeaders.DATE, Collections.singletonList(timeStampProvider.get())); return this; } @@ -172,9 +170,8 @@ public class SignRequest implements HttpRequestFilter { } private void appendPayloadMetadata(HttpRequest request, StringBuilder buffer) { - buffer.append( - utils.valueOrEmpty(request.getPayload() == null ? null : request.getPayload() - .getContentType())).append("\n"); + buffer.append(utils.valueOrEmpty(request.getPayload() == null ? null : request.getPayload().getContentType())) + .append("\n"); } @VisibleForTesting @@ -182,8 +179,7 @@ public class SignRequest implements HttpRequestFilter { // Only the value is used, not the header // name. If a request does not include the header, this is an empty string. for (String header : new String[] { "Range" }) - toSign.append(utils.valueOrEmpty(request.getHeaders().get(header)).toLowerCase()).append( - "\n"); + toSign.append(utils.valueOrEmpty(request.getHeaders().get(header)).toLowerCase()).append("\n"); // Standard HTTP header, in UTC format. Only the date value is used, not the header name. toSign.append(request.getHeaders().get(HttpHeaders.DATE).iterator().next()).append("\n"); } diff --git a/atmos/src/main/java/org/jclouds/atmosonline/saas/functions/ParseSystemMetadataFromHeaders.java b/atmos/src/main/java/org/jclouds/atmosonline/saas/functions/ParseSystemMetadataFromHeaders.java index 0f06944c8a..3ddffe3732 100644 --- a/atmos/src/main/java/org/jclouds/atmosonline/saas/functions/ParseSystemMetadataFromHeaders.java +++ b/atmos/src/main/java/org/jclouds/atmosonline/saas/functions/ParseSystemMetadataFromHeaders.java @@ -1,6 +1,6 @@ /** * - * Copyright (C) 2009 Cloud Conscious, LLC. +f * Copyright (C) 2009 Cloud Conscious, LLC. * * ==================================================================== * Licensed under the Apache License, Version 2.0 (the "License"); @@ -28,8 +28,8 @@ import javax.inject.Singleton; import org.jclouds.atmosonline.saas.domain.FileType; import org.jclouds.atmosonline.saas.domain.SystemMetadata; import org.jclouds.atmosonline.saas.reference.AtmosStorageHeaders; +import org.jclouds.crypto.CryptoStreams; import org.jclouds.date.DateService; -import org.jclouds.encryption.EncryptionService; import org.jclouds.http.HttpResponse; import com.google.common.base.Function; @@ -41,18 +41,14 @@ import com.google.common.collect.Maps; @Singleton public class ParseSystemMetadataFromHeaders implements Function { private final DateService dateService; - private final EncryptionService encryptionService; @Inject - public ParseSystemMetadataFromHeaders(DateService dateService, - EncryptionService encryptionService) { + public ParseSystemMetadataFromHeaders(DateService dateService) { this.dateService = dateService; - this.encryptionService = encryptionService; } public SystemMetadata apply(HttpResponse from) { - String meta = checkNotNull(from.getFirstHeaderOrNull(AtmosStorageHeaders.META), - AtmosStorageHeaders.META); + String meta = checkNotNull(from.getFirstHeaderOrNull(AtmosStorageHeaders.META), AtmosStorageHeaders.META); Map metaMap = Maps.newHashMap(); String[] metas = meta.split(", "); for (String entry : metas) { @@ -60,17 +56,14 @@ public class ParseSystemMetadataFromHeaders implements Function= 12 : String.format("Should be 12 entries in %s", metaMap); - byte[] md5 = metaMap.containsKey("content-md5") ? encryptionService.fromHex(metaMap - .get("content-md5")) : null; - return new SystemMetadata(md5, dateService.iso8601SecondsDateParse(checkNotNull(metaMap - .get("atime"), "atime")), dateService.iso8601SecondsDateParse(checkNotNull(metaMap - .get("ctime"), "ctime")), checkNotNull(metaMap.get("gid"), "gid"), dateService - .iso8601SecondsDateParse(checkNotNull(metaMap.get("itime"), "itime")), dateService - .iso8601SecondsDateParse(checkNotNull(metaMap.get("mtime"), "mtime")), Integer - .parseInt(checkNotNull(metaMap.get("nlink"), "nlink")), checkNotNull(metaMap - .get("objectid"), "objectid"), checkNotNull(metaMap.get("objname"), "objname"), - checkNotNull(metaMap.get("policyname"), "policyname"), Long.parseLong(checkNotNull( - metaMap.get("size"), "size")), FileType.fromValue(checkNotNull(metaMap - .get("type"), "type")), checkNotNull(metaMap.get("uid"), "uid")); + byte[] md5 = metaMap.containsKey("content-md5") ? CryptoStreams.hex(metaMap.get("content-md5")) : null; + return new SystemMetadata(md5, dateService.iso8601SecondsDateParse(checkNotNull(metaMap.get("atime"), "atime")), + dateService.iso8601SecondsDateParse(checkNotNull(metaMap.get("ctime"), "ctime")), checkNotNull(metaMap + .get("gid"), "gid"), dateService.iso8601SecondsDateParse(checkNotNull(metaMap.get("itime"), + "itime")), dateService.iso8601SecondsDateParse(checkNotNull(metaMap.get("mtime"), "mtime")), + Integer.parseInt(checkNotNull(metaMap.get("nlink"), "nlink")), checkNotNull(metaMap.get("objectid"), + "objectid"), checkNotNull(metaMap.get("objname"), "objname"), checkNotNull(metaMap + .get("policyname"), "policyname"), Long.parseLong(checkNotNull(metaMap.get("size"), "size")), + FileType.fromValue(checkNotNull(metaMap.get("type"), "type")), checkNotNull(metaMap.get("uid"), "uid")); } } \ No newline at end of file diff --git a/atmos/src/main/java/org/jclouds/atmosonline/saas/util/AtmosStorageUtils.java b/atmos/src/main/java/org/jclouds/atmosonline/saas/util/AtmosStorageUtils.java index 0def314b61..b2dfaa345c 100644 --- a/atmos/src/main/java/org/jclouds/atmosonline/saas/util/AtmosStorageUtils.java +++ b/atmos/src/main/java/org/jclouds/atmosonline/saas/util/AtmosStorageUtils.java @@ -30,7 +30,8 @@ import org.jclouds.atmosonline.saas.domain.AtmosStorageError; import org.jclouds.atmosonline.saas.filters.SignRequest; import org.jclouds.atmosonline.saas.xml.ErrorHandler; import org.jclouds.blobstore.domain.Blob; -import org.jclouds.encryption.EncryptionService; +import org.jclouds.crypto.Crypto; +import org.jclouds.crypto.CryptoStreams; import org.jclouds.http.HttpCommand; import org.jclouds.http.HttpException; import org.jclouds.http.HttpResponse; @@ -56,10 +57,9 @@ public class AtmosStorageUtils { @Inject Provider errorHandlerProvider; - public AtmosStorageError parseAtmosStorageErrorFromContent(HttpCommand command, - HttpResponse response, InputStream content) throws HttpException { - AtmosStorageError error = (AtmosStorageError) factory.create(errorHandlerProvider.get()) - .parse(content); + public AtmosStorageError parseAtmosStorageErrorFromContent(HttpCommand command, HttpResponse response, + InputStream content) throws HttpException { + AtmosStorageError error = (AtmosStorageError) factory.create(errorHandlerProvider.get()).parse(content); if (error.getCode() == 1032) { error.setStringSigned(signer.createStringToSign(command.getRequest())); } @@ -67,13 +67,12 @@ public class AtmosStorageUtils { } - public static String putBlob(final AtmosStorageClient sync, EncryptionService encryptionService, - BlobToObject blob2Object, String container, Blob blob) { + public static String putBlob(final AtmosStorageClient sync, Crypto crypto, BlobToObject blob2Object, + String container, Blob blob) { final String path = container + "/" + blob.getMetadata().getName(); deleteAndEnsureGone(sync, path); if (blob.getMetadata().getContentMD5() != null) - blob.getMetadata().getUserMetadata().put("content-md5", - encryptionService.hex(blob.getMetadata().getContentMD5())); + blob.getMetadata().getUserMetadata().put("content-md5", CryptoStreams.hex(blob.getMetadata().getContentMD5())); sync.createFile(container, blob2Object.apply(blob)); return path; } @@ -93,10 +92,9 @@ public class AtmosStorageUtils { } } - public AtmosStorageError parseAtmosStorageErrorFromContent(HttpCommand command, - HttpResponse response, String content) throws HttpException { - return parseAtmosStorageErrorFromContent(command, response, new ByteArrayInputStream(content - .getBytes())); + public AtmosStorageError parseAtmosStorageErrorFromContent(HttpCommand command, HttpResponse response, String content) + throws HttpException { + return parseAtmosStorageErrorFromContent(command, response, new ByteArrayInputStream(content.getBytes())); } public static String adjustContainerIfDirOptionPresent(String container, 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 d598ac4b4b..1f749e6e2c 100644 --- a/atmos/src/test/java/org/jclouds/atmosonline/saas/AtmosStorageClientLiveTest.java +++ b/atmos/src/test/java/org/jclouds/atmosonline/saas/AtmosStorageClientLiveTest.java @@ -89,8 +89,7 @@ public class AtmosStorageClientLiveTest { private final String metadataValue; private final String compare; - private ObjectMatches(AtmosStorageClient connection, String name, String metadataValue, - String compare) { + private ObjectMatches(AtmosStorageClient connection, String name, String metadataValue, String compare) { this.connection = connection; this.name = name; this.metadataValue = metadataValue; @@ -115,16 +114,12 @@ public class AtmosStorageClientLiveTest { private BlobStoreContext context; @BeforeGroups(groups = { "live" }) - public void setupClient() throws InterruptedException, ExecutionException, TimeoutException, - IOException { - String identity = checkNotNull(System.getProperty("jclouds.test.identity"), - "jclouds.test.identity"); - String credential = checkNotNull(System.getProperty("jclouds.test.credential"), - "jclouds.test.credential"); - context = new BlobStoreContextFactory().createContext("atmosonline", identity, credential, - ImmutableSet. of(new Log4JLoggingModule())); - RestContext restContext = context - .getProviderSpecificContext(); + public void setupClient() throws InterruptedException, ExecutionException, TimeoutException, IOException { + String identity = checkNotNull(System.getProperty("jclouds.test.identity"), "jclouds.test.identity"); + String credential = checkNotNull(System.getProperty("jclouds.test.credential"), "jclouds.test.credential"); + context = new BlobStoreContextFactory().createContext("atmosonline", identity, credential, ImmutableSet + . of(new Log4JLoggingModule())); + RestContext restContext = context.getProviderSpecificContext(); connection = restContext.getApi(); for (DirectoryEntry entry : connection.listDirectories()) { if (entry.getObjectName().startsWith(containerPrefix)) { @@ -169,8 +164,8 @@ public class AtmosStorageClientLiveTest { createOrReplaceObject("object2", "here is my data!", "meta-value1"); createOrReplaceObject("object3", "here is my data!", "meta-value1"); createOrReplaceObject("object4", "here is my data!", "meta-value1"); - BoundedSet r2 = connection.listDirectory(privateDirectory, - ListOptions.Builder.limit(1)); + BoundedSet r2 = connection + .listDirectory(privateDirectory, ListOptions.Builder.limit(1)); assertEquals(r2.size(), 1); assert r2.getToken() != null; assertEquals(Iterables.getLast(Sets.newTreeSet(r2)).getObjectName(), "object2"); @@ -196,8 +191,7 @@ public class AtmosStorageClientLiveTest { // loop to gather metrics for (boolean stream : new Boolean[] { true, false }) { for (int i = 0; i < 10; i++) { - System.err.printf("upload/delete/create attempt %d type %s%n", i + 1, stream ? "stream" - : "string"); + System.err.printf("upload/delete/create attempt %d type %s%n", i + 1, stream ? "stream" : "string"); // try updating createOrUpdateWithErrorLoop(stream, "there is my data", "2"); @@ -209,8 +203,7 @@ public class AtmosStorageClientLiveTest { } } - private void createOrUpdateWithErrorLoop(boolean stream, String data, String metadataValue) - throws Exception { + private void createOrUpdateWithErrorLoop(boolean stream, String data, String metadataValue) throws Exception { createOrReplaceObject("object", makeData(data, stream), metadataValue); assertEventuallyObjectMatches("object", data, metadataValue); } @@ -219,14 +212,13 @@ public class AtmosStorageClientLiveTest { return stream ? Utils.toInputStream(in) : in; } - private void createOrReplaceObject(String name, Object data, String metadataValue) - throws Exception { + private void createOrReplaceObject(String name, Object data, String metadataValue) throws Exception { // Test PUT with string data, ETag hash, and a piece of metadata AtmosObject object = connection.newObject(); object.getContentMetadata().setName(name); object.setPayload(Payloads.newPayload(data)); object.getContentMetadata().setContentLength(16l); - context.utils().encryption().generateMD5BufferingIfNotRepeatable(object); + Payloads.calculateMD5(object); object.getContentMetadata().setContentType("text/plain"); object.getUserMetadata().getMetadata().put("Metadata", metadataValue); replaceObject(object); @@ -243,9 +235,8 @@ public class AtmosStorageClientLiveTest { try { assertion.run(); if (i > 0) - System.err.printf("%d attempts and %dms asserting %s%n", i + 1, System - .currentTimeMillis() - - start, assertion.getClass().getSimpleName()); + System.err.printf("%d attempts and %dms asserting %s%n", i + 1, System.currentTimeMillis() - start, + assertion.getClass().getSimpleName()); return; } catch (AssertionError e) { error = e; @@ -257,10 +248,9 @@ public class AtmosStorageClientLiveTest { } - protected void assertEventuallyObjectMatches(final String name, final String compare, - final String metadataValue) throws InterruptedException { - assertEventually(new ObjectMatches(connection, privateDirectory + "/" + name, metadataValue, - compare)); + protected void assertEventuallyObjectMatches(final String name, final String compare, final String metadataValue) + throws InterruptedException { + assertEventually(new ObjectMatches(connection, privateDirectory + "/" + name, metadataValue, compare)); } protected void assertEventuallyHeadMatches(final String name, final String metadataValue) @@ -268,17 +258,15 @@ public class AtmosStorageClientLiveTest { assertEventually(new HeadMatches(connection, privateDirectory + "/" + name, metadataValue)); } - private static void verifyHeadObject(AtmosStorageClient connection, String path, - String metadataValue) throws InterruptedException, ExecutionException, - TimeoutException, IOException { + private static void verifyHeadObject(AtmosStorageClient connection, String path, String metadataValue) + throws InterruptedException, ExecutionException, TimeoutException, IOException { AtmosObject getBlob = connection.headFile(path); assertEquals(Utils.toStringAndClose(getBlob.getPayload().getInput()), ""); verifyMetadata(metadataValue, getBlob); } - private static void verifyObject(AtmosStorageClient connection, String path, String compare, - String metadataValue) throws InterruptedException, ExecutionException, - TimeoutException, IOException { + private static void verifyObject(AtmosStorageClient connection, String path, String compare, String metadataValue) + throws InterruptedException, ExecutionException, TimeoutException, IOException { AtmosObject getBlob = connection.readFile(path); assertEquals(Utils.toStringAndClose(getBlob.getPayload().getInput()), compare); verifyMetadata(metadataValue, getBlob); @@ -304,8 +292,8 @@ public class AtmosStorageClientLiveTest { try { Utils.toStringAndClose(URI.create( - "http://accesspoint.emccis.com/rest/objects/" - + getBlob.getSystemMetadata().getObjectID()).toURL().openStream()); + "http://accesspoint.emccis.com/rest/objects/" + getBlob.getSystemMetadata().getObjectID()).toURL() + .openStream()); assert false : "shouldn't have worked, since it is private"; } catch (IOException e) { @@ -323,29 +311,25 @@ public class AtmosStorageClientLiveTest { long time = System.currentTimeMillis(); try { connection.createFile(privateDirectory, object); - System.err.printf("%s %s; %dms%n", "created", - object.getPayload() instanceof InputStreamPayload ? "stream" : "string", System - .currentTimeMillis() - - time); + System.err.printf("%s %s; %dms%n", "created", object.getPayload() instanceof InputStreamPayload ? "stream" + : "string", System.currentTimeMillis() - time); } catch (Exception e) { String message = Throwables.getRootCause(e).getMessage(); System.err.printf("failure %s %s; %dms: [%s]%n", "creating", - object.getPayload() instanceof InputStreamPayload ? "stream" : "string", System - .currentTimeMillis() + object.getPayload() instanceof InputStreamPayload ? "stream" : "string", System.currentTimeMillis() - time, message); throw e; } } - private void deleteConfirmed(final String path) throws InterruptedException, ExecutionException, - TimeoutException { + private void deleteConfirmed(final String path) throws InterruptedException, ExecutionException, TimeoutException { long time = System.currentTimeMillis(); deleteConsistencyAware(path); System.err.printf("confirmed deletion after %dms%n", System.currentTimeMillis() - time); } - protected void deleteImmediateAndVerifyWithHead(final String path) throws InterruptedException, - ExecutionException, TimeoutException { + protected void deleteImmediateAndVerifyWithHead(final String path) throws InterruptedException, ExecutionException, + TimeoutException { try { connection.deletePath(path); } catch (KeyNotFoundException ex) { @@ -357,8 +341,8 @@ public class AtmosStorageClientLiveTest { } - protected void deleteConsistencyAware(final String path) throws InterruptedException, - ExecutionException, TimeoutException { + protected void deleteConsistencyAware(final String path) throws InterruptedException, ExecutionException, + TimeoutException { try { connection.deletePath(path); } catch (KeyNotFoundException ex) { @@ -370,8 +354,7 @@ public class AtmosStorageClientLiveTest { }, INCONSISTENCY_WINDOW); } - protected void retryAndCheckSystemMetadataAndPutIfPresentReplaceStrategy(AtmosObject object) - throws Exception { + protected void retryAndCheckSystemMetadataAndPutIfPresentReplaceStrategy(AtmosObject object) throws Exception { int failures = 0; while (true) { @@ -390,8 +373,7 @@ public class AtmosStorageClientLiveTest { object.getPayload() instanceof InputStreamPayload ? "stream" : "string"); } - private void checkSystemMetadataAndPutIfPresentReplaceStrategy(AtmosObject object) - throws Exception { + private void checkSystemMetadataAndPutIfPresentReplaceStrategy(AtmosObject object) throws Exception { long time = System.currentTimeMillis(); boolean update = true; try { @@ -405,15 +387,13 @@ public class AtmosStorageClientLiveTest { else connection.createFile(privateDirectory, object); System.err.printf("%s %s; %dms%n", update ? "updated" : "created", - object.getPayload() instanceof InputStreamPayload ? "stream" : "string", System - .currentTimeMillis() + object.getPayload() instanceof InputStreamPayload ? "stream" : "string", System.currentTimeMillis() - time); } catch (Exception e) { String message = Throwables.getRootCause(e).getMessage(); - System.err.printf("failure %s %s; %dms: [%s]%n", update ? "updating" : "creating", object - .getPayload() instanceof InputStreamPayload ? "stream" : "string", System - .currentTimeMillis() - - time, message); + System.err.printf("failure %s %s; %dms: [%s]%n", update ? "updating" : "creating", + object.getPayload() instanceof InputStreamPayload ? "stream" : "string", System.currentTimeMillis() + - time, message); throw e; } } diff --git a/atmos/src/test/java/org/jclouds/atmosonline/saas/functions/ParseSystemMetadataFromHeadersTest.java b/atmos/src/test/java/org/jclouds/atmosonline/saas/functions/ParseSystemMetadataFromHeadersTest.java index adb00e38dd..a6af540064 100644 --- a/atmos/src/test/java/org/jclouds/atmosonline/saas/functions/ParseSystemMetadataFromHeadersTest.java +++ b/atmos/src/test/java/org/jclouds/atmosonline/saas/functions/ParseSystemMetadataFromHeadersTest.java @@ -22,8 +22,8 @@ import static org.testng.Assert.assertEquals; import org.jclouds.atmosonline.saas.domain.FileType; import org.jclouds.atmosonline.saas.domain.SystemMetadata; +import org.jclouds.crypto.CryptoStreams; import org.jclouds.date.DateService; -import org.jclouds.encryption.EncryptionService; import org.jclouds.http.HttpResponse; import org.jclouds.io.Payloads; import org.testng.annotations.Test; @@ -41,29 +41,23 @@ public class ParseSystemMetadataFromHeadersTest { public void test() { Injector injector = Guice.createInjector(); - ParseSystemMetadataFromHeaders parser = injector - .getInstance(ParseSystemMetadataFromHeaders.class); + ParseSystemMetadataFromHeaders parser = injector.getInstance(ParseSystemMetadataFromHeaders.class); DateService dateService = injector.getInstance(DateService.class); - EncryptionService encryptionService = injector.getInstance(EncryptionService.class); HttpResponse response = new HttpResponse(200, "ok", Payloads.newStringPayload("")); - response - .getHeaders() - .put( - "x-emc-meta", - "content-md5=1f3870be274f6c49b3e31a0c6728957f, atime=2009-10-12T16:09:42Z, mtime=2009-10-19T04:37:00Z," - + " ctime=2009-10-19T04:37:00Z, itime=2009-10-12T16:09:42Z, type=directory, uid=root, " - + "gid=rootr, objectid=4980cdb2b010109b04a44f7bb83f5f04ad354c638ae5, " - + "objname=e913e09366364e9ba384b8fead643d43, size=4096, nlink=1, policyname=default"); - SystemMetadata expected = new SystemMetadata(encryptionService - .fromHex("1f3870be274f6c49b3e31a0c6728957f"), + response.getHeaders().put( + "x-emc-meta", + "content-md5=1f3870be274f6c49b3e31a0c6728957f, atime=2009-10-12T16:09:42Z, mtime=2009-10-19T04:37:00Z," + + " ctime=2009-10-19T04:37:00Z, itime=2009-10-12T16:09:42Z, type=directory, uid=root, " + + "gid=rootr, objectid=4980cdb2b010109b04a44f7bb83f5f04ad354c638ae5, " + + "objname=e913e09366364e9ba384b8fead643d43, size=4096, nlink=1, policyname=default"); + SystemMetadata expected = new SystemMetadata(CryptoStreams.hex("1f3870be274f6c49b3e31a0c6728957f"), dateService.iso8601SecondsDateParse("2009-10-12T16:09:42Z"), dateService .iso8601SecondsDateParse("2009-10-19T04:37:00Z"), "rootr", dateService .iso8601SecondsDateParse("2009-10-12T16:09:42Z"), dateService - .iso8601SecondsDateParse("2009-10-19T04:37:00Z"), 1, - "4980cdb2b010109b04a44f7bb83f5f04ad354c638ae5", "e913e09366364e9ba384b8fead643d43", - "default", 4096l, FileType.DIRECTORY, "root" + .iso8601SecondsDateParse("2009-10-19T04:37:00Z"), 1, "4980cdb2b010109b04a44f7bb83f5f04ad354c638ae5", + "e913e09366364e9ba384b8fead643d43", "default", 4096l, FileType.DIRECTORY, "root" ); SystemMetadata data = parser.apply(response); diff --git a/atmos/src/test/java/org/jclouds/atmosonline/saas/internal/StubAtmosStorageAsyncClient.java b/atmos/src/test/java/org/jclouds/atmosonline/saas/internal/StubAtmosStorageAsyncClient.java index 14dbe07d89..14f6eeaaf1 100644 --- a/atmos/src/test/java/org/jclouds/atmosonline/saas/internal/StubAtmosStorageAsyncClient.java +++ b/atmos/src/test/java/org/jclouds/atmosonline/saas/internal/StubAtmosStorageAsyncClient.java @@ -21,7 +21,6 @@ package org.jclouds.atmosonline.saas.internal; import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.util.concurrent.Futures.immediateFailedFuture; import static com.google.common.util.concurrent.Futures.immediateFuture; -import static org.jclouds.concurrent.ConcurrentUtils.compose; import java.net.URI; import java.util.concurrent.ExecutionException; @@ -47,6 +46,7 @@ import org.jclouds.blobstore.TransientAsyncBlobStore; import org.jclouds.blobstore.domain.Blob; import org.jclouds.blobstore.domain.BlobMetadata; import org.jclouds.blobstore.functions.HttpGetOptionsListToGetOptions; +import org.jclouds.concurrent.Futures; import org.jclouds.http.options.GetOptions; import com.google.common.base.Function; @@ -97,7 +97,7 @@ public class StubAtmosStorageAsyncClient implements AtmosStorageAsyncClient { container = directoryName; path = null; } - return compose(blobStore.createContainerInLocation(null, container), new Function() { + return Futures.compose(blobStore.createContainerInLocation(null, container), new Function() { public URI apply(Boolean from) { if (path != null) { @@ -123,7 +123,7 @@ public class StubAtmosStorageAsyncClient implements AtmosStorageAsyncClient { object.getContentMetadata().setName(path + "/" + file); } Blob blob = object2Blob.apply(object); - return compose(blobStore.putBlob(container, blob), new Function() { + return Futures.compose(blobStore.putBlob(container, blob), new Function() { public URI apply(String from) { return URI.create(uri); @@ -135,7 +135,7 @@ public class StubAtmosStorageAsyncClient implements AtmosStorageAsyncClient { public ListenableFuture deletePath(String path) { if (path.indexOf('/') == path.length() - 1) { // chop off the trailing slash - return compose(blobStore.deleteContainerImpl(path.substring(0, path.length() - 1)), + return Futures.compose(blobStore.deleteContainerImpl(path.substring(0, path.length() - 1)), new Function() { public Void apply(Boolean from) { @@ -160,7 +160,7 @@ public class StubAtmosStorageAsyncClient implements AtmosStorageAsyncClient { else { String container = path.substring(0, path.indexOf('/')); path = path.substring(path.indexOf('/') + 1); - return compose(blobStore.blobMetadata(container, path), new Function() { + return Futures.compose(blobStore.blobMetadata(container, path), new Function() { public UserMetadata apply(BlobMetadata from) { return blob2ObjectInfo.apply(from).getUserMetadata(); } @@ -172,7 +172,7 @@ public class StubAtmosStorageAsyncClient implements AtmosStorageAsyncClient { String container = path.substring(0, path.indexOf('/')); path = path.substring(path.indexOf('/') + 1); try { - return compose(blobStore.getBlob(container, path), blob2Object, service); + return Futures.compose(blobStore.getBlob(container, path), blob2Object, service); } catch (Exception e) { return immediateFailedFuture(Throwables.getRootCause(e)); } @@ -181,7 +181,7 @@ public class StubAtmosStorageAsyncClient implements AtmosStorageAsyncClient { public ListenableFuture> listDirectories(ListOptions... optionsList) { // org.jclouds.blobstore.options.ListOptions options = container2ContainerListOptions // .apply(optionsList); - return compose(blobStore.list(), resource2ObjectList, service); + return Futures.compose(blobStore.list(), resource2ObjectList, service); } public ListenableFuture> listDirectory(String directoryName, @@ -194,7 +194,7 @@ public class StubAtmosStorageAsyncClient implements AtmosStorageAsyncClient { if (!path.equals("")) options.inDirectory(path); } - return compose(blobStore.list(container, options), resource2ObjectList, service); + return Futures.compose(blobStore.list(container, options), resource2ObjectList, service); } public AtmosObject newObject() { @@ -222,7 +222,7 @@ public class StubAtmosStorageAsyncClient implements AtmosStorageAsyncClient { String container = path.substring(0, path.indexOf('/')); String blobName = path.substring(path.indexOf('/') + 1); org.jclouds.blobstore.options.GetOptions getOptions = httpGetOptionsConverter.apply(options); - return compose(blobStore.getBlob(container, blobName, getOptions), blob2Object, service); + return Futures.compose(blobStore.getBlob(container, blobName, getOptions), blob2Object, service); } public ListenableFuture updateFile(String parent, AtmosObject object) { diff --git a/aws/core/src/main/java/org/jclouds/aws/ec2/binders/BindS3UploadPolicyAndSignature.java b/aws/core/src/main/java/org/jclouds/aws/ec2/binders/BindS3UploadPolicyAndSignature.java index 3a5c35c05e..a254d175d3 100644 --- a/aws/core/src/main/java/org/jclouds/aws/ec2/binders/BindS3UploadPolicyAndSignature.java +++ b/aws/core/src/main/java/org/jclouds/aws/ec2/binders/BindS3UploadPolicyAndSignature.java @@ -25,10 +25,13 @@ import javax.inject.Inject; import javax.inject.Singleton; import org.jclouds.aws.filters.FormSigner; -import org.jclouds.encryption.EncryptionService; +import org.jclouds.crypto.Crypto; +import org.jclouds.crypto.CryptoStreams; import org.jclouds.http.HttpRequest; import org.jclouds.rest.Binder; +import com.google.common.base.Charsets; + /** * * @author Adrian Cole @@ -36,16 +39,14 @@ import org.jclouds.rest.Binder; @Singleton public class BindS3UploadPolicyAndSignature implements Binder { private final FormSigner signer; - private final EncryptionService encryptionService; @Inject - BindS3UploadPolicyAndSignature(FormSigner signer, EncryptionService encryptionService) { + BindS3UploadPolicyAndSignature(FormSigner signer, Crypto crypto) { this.signer = signer; - this.encryptionService = encryptionService; } public void bindToRequest(HttpRequest request, Object input) { - String encodedJson = encryptionService.base64(checkNotNull(input, "json").toString().getBytes()); + String encodedJson = CryptoStreams.base64(checkNotNull(input, "json").toString().getBytes(Charsets.UTF_8)); addFormParamTo(request, "Storage.S3.UploadPolicy", encodedJson); String signature = signer.sign(encodedJson); addFormParamTo(request, "Storage.S3.UploadPolicySignature", signature); diff --git a/aws/core/src/main/java/org/jclouds/aws/ec2/compute/config/EC2ComputeServiceContextModule.java b/aws/core/src/main/java/org/jclouds/aws/ec2/compute/config/EC2ComputeServiceContextModule.java index 4a6c4e209b..ba6d0297a5 100755 --- a/aws/core/src/main/java/org/jclouds/aws/ec2/compute/config/EC2ComputeServiceContextModule.java +++ b/aws/core/src/main/java/org/jclouds/aws/ec2/compute/config/EC2ComputeServiceContextModule.java @@ -36,7 +36,7 @@ import static org.jclouds.aws.ec2.util.EC2Utils.getAllRunningInstancesInRegion; import static org.jclouds.aws.ec2.util.EC2Utils.parseHandle; import static org.jclouds.compute.domain.OsFamily.CENTOS; import static org.jclouds.compute.domain.OsFamily.UBUNTU; -import static org.jclouds.concurrent.ConcurrentUtils.transformParallel; +import static org.jclouds.concurrent.FutureIterables.transformParallel; import java.net.URI; import java.security.SecureRandom; @@ -124,7 +124,6 @@ import com.google.common.base.Splitter; import com.google.common.base.Supplier; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Iterables; import com.google.common.collect.MapMaker; import com.google.common.collect.Maps; import com.google.inject.AbstractModule; diff --git a/aws/core/src/main/java/org/jclouds/aws/ec2/compute/strategy/DescribeImagesParallel.java b/aws/core/src/main/java/org/jclouds/aws/ec2/compute/strategy/DescribeImagesParallel.java index f963d9cd32..773830d1e9 100644 --- a/aws/core/src/main/java/org/jclouds/aws/ec2/compute/strategy/DescribeImagesParallel.java +++ b/aws/core/src/main/java/org/jclouds/aws/ec2/compute/strategy/DescribeImagesParallel.java @@ -19,7 +19,7 @@ package org.jclouds.aws.ec2.compute.strategy; import static com.google.common.collect.Iterables.concat; -import static org.jclouds.concurrent.ConcurrentUtils.transformParallel; +import static org.jclouds.concurrent.FutureIterables.transformParallel; import java.util.Set; import java.util.Map.Entry; diff --git a/aws/core/src/main/java/org/jclouds/aws/ec2/functions/ConvertUnencodedBytesToBase64EncodedString.java b/aws/core/src/main/java/org/jclouds/aws/ec2/functions/ConvertUnencodedBytesToBase64EncodedString.java index eb07acabe1..e255e93a89 100644 --- a/aws/core/src/main/java/org/jclouds/aws/ec2/functions/ConvertUnencodedBytesToBase64EncodedString.java +++ b/aws/core/src/main/java/org/jclouds/aws/ec2/functions/ConvertUnencodedBytesToBase64EncodedString.java @@ -21,10 +21,9 @@ package org.jclouds.aws.ec2.functions; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; -import javax.inject.Inject; import javax.inject.Singleton; -import org.jclouds.encryption.EncryptionService; +import org.jclouds.crypto.CryptoStreams; import com.google.common.base.Function; @@ -36,17 +35,13 @@ import com.google.common.base.Function; @Singleton public class ConvertUnencodedBytesToBase64EncodedString implements Function { - @Inject - EncryptionService encryptionService; - @Override public String apply(Object from) { - checkArgument(checkNotNull(from, "input") instanceof byte[], - "this binder is only valid for byte []!"); + checkArgument(checkNotNull(from, "input") instanceof byte[], "this binder is only valid for byte []!"); byte[] unencodedData = (byte[]) from; checkArgument(checkNotNull(unencodedData, "unencodedData").length <= 16 * 1024, "userData cannot be larger than 16kb"); - return encryptionService.base64(unencodedData); + return CryptoStreams.base64(unencodedData); } } \ No newline at end of file diff --git a/aws/core/src/main/java/org/jclouds/aws/ec2/xml/UnencodeStringValueHandler.java b/aws/core/src/main/java/org/jclouds/aws/ec2/xml/UnencodeStringValueHandler.java index 78e67d8e9a..3401160c92 100644 --- a/aws/core/src/main/java/org/jclouds/aws/ec2/xml/UnencodeStringValueHandler.java +++ b/aws/core/src/main/java/org/jclouds/aws/ec2/xml/UnencodeStringValueHandler.java @@ -18,9 +18,7 @@ */ package org.jclouds.aws.ec2.xml; -import javax.inject.Inject; - -import org.jclouds.encryption.EncryptionService; +import org.jclouds.crypto.CryptoStreams; import com.google.common.base.Charsets; @@ -32,12 +30,8 @@ import com.google.common.base.Charsets; */ public class UnencodeStringValueHandler extends StringValueHandler { - @Inject - private EncryptionService encryptionService; - @Override public String getResult() { - return super.getResult() == null ? null : new String(encryptionService.fromBase64(super - .getResult()), Charsets.UTF_8); + return super.getResult() == null ? null : new String(CryptoStreams.base64(super.getResult()), Charsets.UTF_8); } } diff --git a/aws/core/src/main/java/org/jclouds/aws/filters/FormSigner.java b/aws/core/src/main/java/org/jclouds/aws/filters/FormSigner.java index 24685b0345..0ad1bede1b 100755 --- a/aws/core/src/main/java/org/jclouds/aws/filters/FormSigner.java +++ b/aws/core/src/main/java/org/jclouds/aws/filters/FormSigner.java @@ -43,13 +43,15 @@ import javax.inject.Singleton; import javax.ws.rs.core.HttpHeaders; import org.jclouds.Constants; +import org.jclouds.crypto.Crypto; +import org.jclouds.crypto.CryptoStreams; import org.jclouds.date.TimeStamp; -import org.jclouds.encryption.EncryptionService; import org.jclouds.http.HttpException; import org.jclouds.http.HttpRequest; import org.jclouds.http.HttpRequestFilter; import org.jclouds.http.HttpUtils; import org.jclouds.http.internal.SignatureWire; +import org.jclouds.io.InputSuppliers; import org.jclouds.logging.Logger; import org.jclouds.rest.RequestSigner; import org.jclouds.util.Utils; @@ -69,13 +71,13 @@ import com.google.common.collect.Multimap; @Singleton public class FormSigner implements HttpRequestFilter, RequestSigner { - public static String[] mandatoryParametersForSignature = new String[] { ACTION, - SIGNATURE_METHOD, SIGNATURE_VERSION, VERSION }; + public static String[] mandatoryParametersForSignature = new String[] { ACTION, SIGNATURE_METHOD, SIGNATURE_VERSION, + VERSION }; private final SignatureWire signatureWire; private final String accessKey; private final String secretKey; private final Provider dateService; - private final EncryptionService encryptionService; + private final Crypto crypto; private final HttpUtils utils; @Resource @@ -83,24 +85,20 @@ public class FormSigner implements HttpRequestFilter, RequestSigner { private Logger signatureLog = Logger.NULL; @Inject - public FormSigner(SignatureWire signatureWire, - @Named(Constants.PROPERTY_IDENTITY) String accessKey, - @Named(Constants.PROPERTY_CREDENTIAL) String secretKey, - @TimeStamp Provider dateService, EncryptionService encryptionService, - HttpUtils utils) { + public FormSigner(SignatureWire signatureWire, @Named(Constants.PROPERTY_IDENTITY) String accessKey, + @Named(Constants.PROPERTY_CREDENTIAL) String secretKey, @TimeStamp Provider dateService, + Crypto crypto, HttpUtils utils) { this.signatureWire = signatureWire; this.accessKey = accessKey; this.secretKey = secretKey; this.dateService = dateService; - this.encryptionService = encryptionService; + this.crypto = crypto; this.utils = utils; } public void filter(HttpRequest request) throws HttpException { - checkNotNull(request.getFirstHeaderOrNull(HttpHeaders.HOST), - "request is not ready to sign; host not present"); - Multimap decodedParams = parseQueryToMap(request.getPayload().getRawContent() - .toString()); + checkNotNull(request.getFirstHeaderOrNull(HttpHeaders.HOST), "request is not ready to sign; host not present"); + Multimap decodedParams = parseQueryToMap(request.getPayload().getRawContent().toString()); addSigningParams(decodedParams); validateParams(decodedParams); String stringToSign = createStringToSign(request, decodedParams); @@ -141,8 +139,7 @@ public class FormSigner implements HttpRequestFilter, RequestSigner { @VisibleForTesting void validateParams(Multimap params) { for (String parameter : mandatoryParametersForSignature) { - checkState(params.containsKey(parameter), "parameter " + parameter - + " is required for signature"); + checkState(params.containsKey(parameter), "parameter " + parameter + " is required for signature"); } } @@ -155,8 +152,8 @@ public class FormSigner implements HttpRequestFilter, RequestSigner { public String sign(String stringToSign) { String signature; try { - signature = encryptionService.base64(encryptionService.hmacSha256(stringToSign, secretKey - .getBytes())); + signature = CryptoStreams.base64(CryptoStreams.mac(InputSuppliers.of(stringToSign), crypto + .hmacSHA256(secretKey.getBytes()))); if (signatureWire.enabled()) signatureWire.input(Utils.toInputStream(signature)); } catch (Exception e) { @@ -172,8 +169,7 @@ public class FormSigner implements HttpRequestFilter, RequestSigner { // StringToSign = HTTPVerb + "\n" + stringToSign.append(request.getMethod()).append("\n"); // ValueOfHostHeaderInLowercase + "\n" + - stringToSign.append(request.getFirstHeaderOrNull(HttpHeaders.HOST).toLowerCase()) - .append("\n"); + stringToSign.append(request.getFirstHeaderOrNull(HttpHeaders.HOST).toLowerCase()).append("\n"); // HTTPRequestURI + "\n" + stringToSign.append(request.getEndpoint().getPath()).append("\n"); // CanonicalizedFormString @@ -204,8 +200,7 @@ public class FormSigner implements HttpRequestFilter, RequestSigner { } public String createStringToSign(HttpRequest input) { - return createStringToSign(input, parseQueryToMap(input.getPayload().getRawContent() - .toString())); + return createStringToSign(input, parseQueryToMap(input.getPayload().getRawContent().toString())); } } diff --git a/aws/core/src/main/java/org/jclouds/aws/s3/blobstore/S3AsyncBlobStore.java b/aws/core/src/main/java/org/jclouds/aws/s3/blobstore/S3AsyncBlobStore.java index 3aaf48d8aa..0ef0c029f7 100644 --- a/aws/core/src/main/java/org/jclouds/aws/s3/blobstore/S3AsyncBlobStore.java +++ b/aws/core/src/main/java/org/jclouds/aws/s3/blobstore/S3AsyncBlobStore.java @@ -19,11 +19,9 @@ package org.jclouds.aws.s3.blobstore; import static com.google.common.base.Preconditions.checkNotNull; -import static org.jclouds.concurrent.ConcurrentUtils.compose; import java.util.Set; import java.util.concurrent.ExecutorService; -import com.google.common.util.concurrent.ListenableFuture; import javax.inject.Inject; import javax.inject.Named; @@ -56,11 +54,13 @@ import org.jclouds.blobstore.internal.BaseAsyncBlobStore; import org.jclouds.blobstore.options.ListContainerOptions; import org.jclouds.blobstore.strategy.internal.FetchBlobMetadata; import org.jclouds.blobstore.util.BlobUtils; +import org.jclouds.concurrent.Futures; import org.jclouds.domain.Location; import org.jclouds.http.options.GetOptions; import com.google.common.base.Function; import com.google.common.collect.Iterables; +import com.google.common.util.concurrent.ListenableFuture; /** * @@ -106,7 +106,7 @@ public class S3AsyncBlobStore extends BaseAsyncBlobStore { */ @Override public ListenableFuture> list() { - return compose(async.listOwnedBuckets(), + return Futures.compose(async.listOwnedBuckets(), new Function, org.jclouds.blobstore.domain.PageSet>() { public org.jclouds.blobstore.domain.PageSet apply(Set from) { return new PageSetImpl(Iterables.transform(from, bucket2ResourceMd), null); @@ -150,9 +150,10 @@ public class S3AsyncBlobStore extends BaseAsyncBlobStore { public ListenableFuture> list(String container, ListContainerOptions options) { ListBucketOptions httpOptions = container2BucketListOptions.apply(options); ListenableFuture returnVal = async.listBucket(container, httpOptions); - ListenableFuture> list = compose(returnVal, bucket2ResourceList, service); - return (options.isDetailed()) ? compose(list, fetchBlobMetadataProvider.get().setContainerName(container), - service) : list; + ListenableFuture> list = Futures.compose(returnVal, bucket2ResourceList, + service); + return (options.isDetailed()) ? Futures.compose(list, + fetchBlobMetadataProvider.get().setContainerName(container), service) : list; } /** @@ -185,7 +186,7 @@ public class S3AsyncBlobStore extends BaseAsyncBlobStore { */ @Override public ListenableFuture blobMetadata(String container, String key) { - return compose(async.headObject(container, key), new Function() { + return Futures.compose(async.headObject(container, key), new Function() { @Override public BlobMetadata apply(ObjectMetadata from) { @@ -206,7 +207,7 @@ public class S3AsyncBlobStore extends BaseAsyncBlobStore { @Override public ListenableFuture getBlob(String container, String key, org.jclouds.blobstore.options.GetOptions options) { GetOptions httpOptions = blob2ObjectGetOptions.apply(options); - return compose(async.getObject(container, key, httpOptions), object2Blob, service); + return Futures.compose(async.getObject(container, key, httpOptions), object2Blob, service); } /** diff --git a/aws/core/src/main/java/org/jclouds/aws/s3/domain/S3Object.java b/aws/core/src/main/java/org/jclouds/aws/s3/domain/S3Object.java index ae94c3c368..8f25481519 100644 --- a/aws/core/src/main/java/org/jclouds/aws/s3/domain/S3Object.java +++ b/aws/core/src/main/java/org/jclouds/aws/s3/domain/S3Object.java @@ -18,7 +18,7 @@ */ package org.jclouds.aws.s3.domain; -import org.jclouds.http.PayloadEnclosing; +import org.jclouds.io.PayloadEnclosing; import com.google.common.collect.Multimap; import com.google.inject.internal.Nullable; 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 3ce5d35b14..ce1ffb634c 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,9 +25,9 @@ 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.http.PayloadEnclosing; import org.jclouds.http.internal.PayloadEnclosingImpl; import org.jclouds.io.Payload; +import org.jclouds.io.PayloadEnclosing; import org.jclouds.io.payloads.DelegatingPayload; import com.google.common.collect.LinkedHashMultimap; diff --git a/aws/core/src/main/java/org/jclouds/aws/s3/filters/RequestAuthorizeSignature.java b/aws/core/src/main/java/org/jclouds/aws/s3/filters/RequestAuthorizeSignature.java index ffe0a2c4c9..c8ab68f784 100755 --- a/aws/core/src/main/java/org/jclouds/aws/s3/filters/RequestAuthorizeSignature.java +++ b/aws/core/src/main/java/org/jclouds/aws/s3/filters/RequestAuthorizeSignature.java @@ -43,13 +43,15 @@ import javax.ws.rs.core.HttpHeaders; import org.jclouds.Constants; import org.jclouds.aws.s3.Bucket; +import org.jclouds.crypto.Crypto; +import org.jclouds.crypto.CryptoStreams; import org.jclouds.date.TimeStamp; -import org.jclouds.encryption.EncryptionService; import org.jclouds.http.HttpException; import org.jclouds.http.HttpRequest; import org.jclouds.http.HttpRequestFilter; import org.jclouds.http.HttpUtils; import org.jclouds.http.internal.SignatureWire; +import org.jclouds.io.InputSuppliers; import org.jclouds.logging.Logger; import org.jclouds.rest.RequestSigner; import org.jclouds.rest.internal.GeneratedHttpRequest; @@ -71,13 +73,13 @@ import com.google.common.collect.Iterables; public class RequestAuthorizeSignature implements HttpRequestFilter, RequestSigner { private final String[] firstHeadersToSign = new String[] { HttpHeaders.DATE }; - public static Set SPECIAL_QUERIES = ImmutableSet.of("acl", "torrent", "logging", - "location", "requestPayment"); + public static Set SPECIAL_QUERIES = ImmutableSet.of("acl", "torrent", "logging", "location", + "requestPayment"); private final SignatureWire signatureWire; private final String accessKey; private final String secretKey; private final Provider timeStampProvider; - private final EncryptionService encryptionService; + private final Crypto crypto; private final HttpUtils utils; @Resource @@ -90,15 +92,11 @@ public class RequestAuthorizeSignature implements HttpRequestFilter, RequestSign private final boolean isVhostStyle; @Inject - public RequestAuthorizeSignature(SignatureWire signatureWire, - @Named(PROPERTY_AUTH_TAG) String authTag, + public RequestAuthorizeSignature(SignatureWire signatureWire, @Named(PROPERTY_AUTH_TAG) String authTag, @Named(PROPERTY_S3_VIRTUAL_HOST_BUCKETS) boolean isVhostStyle, - @Named(PROPERTY_S3_SERVICE_PATH) String servicePath, - @Named(PROPERTY_HEADER_TAG) String headerTag, - @Named(PROPERTY_IDENTITY) String accessKey, - @Named(PROPERTY_CREDENTIAL) String secretKey, - @TimeStamp Provider timeStampProvider, EncryptionService encryptionService, - HttpUtils utils) { + @Named(PROPERTY_S3_SERVICE_PATH) String servicePath, @Named(PROPERTY_HEADER_TAG) String headerTag, + @Named(PROPERTY_IDENTITY) String accessKey, @Named(PROPERTY_CREDENTIAL) String secretKey, + @TimeStamp Provider timeStampProvider, Crypto crypto, HttpUtils utils) { this.isVhostStyle = isVhostStyle; this.servicePath = servicePath; this.headerTag = headerTag; @@ -107,7 +105,7 @@ public class RequestAuthorizeSignature implements HttpRequestFilter, RequestSign this.accessKey = accessKey; this.secretKey = secretKey; this.timeStampProvider = timeStampProvider; - this.encryptionService = encryptionService; + this.crypto = crypto; this.utils = utils; } @@ -145,8 +143,8 @@ public class RequestAuthorizeSignature implements HttpRequestFilter, RequestSign public String sign(String toSign) { String signature; try { - signature = encryptionService.base64(encryptionService.hmacSha1(toSign, secretKey - .getBytes())); + signature = CryptoStreams.base64(CryptoStreams.mac(InputSuppliers.of(toSign), crypto.hmacSHA1(secretKey + .getBytes()))); } catch (Exception e) { throw new HttpException("error signing request", e); } @@ -158,8 +156,7 @@ public class RequestAuthorizeSignature implements HttpRequestFilter, RequestSign } void replaceDateHeader(HttpRequest request) { - request.getHeaders().replaceValues(HttpHeaders.DATE, - Collections.singletonList(timeStampProvider.get())); + request.getHeaders().replaceValues(HttpHeaders.DATE, Collections.singletonList(timeStampProvider.get())); } void appendAmzHeaders(HttpRequest request, StringBuilder toSign) { @@ -177,12 +174,10 @@ public class RequestAuthorizeSignature implements HttpRequestFilter, RequestSign } void appendPayloadMetadata(HttpRequest request, StringBuilder buffer) { - buffer.append( - utils.valueOrEmpty(request.getPayload() == null ? null : request.getPayload() - .getContentMD5())).append("\n"); - buffer.append( - utils.valueOrEmpty(request.getPayload() == null ? null : request.getPayload() - .getContentType())).append("\n"); + buffer.append(utils.valueOrEmpty(request.getPayload() == null ? null : request.getPayload().getContentMD5())) + .append("\n"); + buffer.append(utils.valueOrEmpty(request.getPayload() == null ? null : request.getPayload().getContentType())) + .append("\n"); } void appendHttpHeaders(HttpRequest request, StringBuilder toSign) { @@ -192,8 +187,7 @@ public class RequestAuthorizeSignature implements HttpRequestFilter, RequestSign @VisibleForTesting void appendBucketName(HttpRequest req, StringBuilder toSign) { - checkArgument(req instanceof GeneratedHttpRequest, - "this should be a generated http request"); + checkArgument(req instanceof GeneratedHttpRequest, "this should be a generated http request"); GeneratedHttpRequest request = GeneratedHttpRequest.class.cast(req); String bucketName = null; diff --git a/aws/core/src/main/java/org/jclouds/aws/s3/functions/ParseObjectMetadataFromHeaders.java b/aws/core/src/main/java/org/jclouds/aws/s3/functions/ParseObjectMetadataFromHeaders.java index 45d3bb0964..2d9f90dd10 100644 --- a/aws/core/src/main/java/org/jclouds/aws/s3/functions/ParseObjectMetadataFromHeaders.java +++ b/aws/core/src/main/java/org/jclouds/aws/s3/functions/ParseObjectMetadataFromHeaders.java @@ -29,7 +29,7 @@ import org.jclouds.aws.s3.blobstore.functions.BlobToObjectMetadata; import org.jclouds.aws.s3.domain.MutableObjectMetadata; import org.jclouds.blobstore.domain.BlobMetadata; import org.jclouds.blobstore.functions.ParseSystemAndUserMetadataFromHeaders; -import org.jclouds.encryption.EncryptionService; +import org.jclouds.crypto.CryptoStreams; import org.jclouds.http.HttpRequest; import org.jclouds.http.HttpResponse; import org.jclouds.rest.InvocationContext; @@ -45,20 +45,16 @@ import com.google.common.base.Function; * @see * @author Adrian Cole */ -public class ParseObjectMetadataFromHeaders implements - Function, InvocationContext { +public class ParseObjectMetadataFromHeaders implements Function, InvocationContext { private final ParseSystemAndUserMetadataFromHeaders blobMetadataParser; private final BlobToObjectMetadata blobToObjectMetadata; - private final EncryptionService encryptionService; private final String userMdPrefix; @Inject public ParseObjectMetadataFromHeaders(ParseSystemAndUserMetadataFromHeaders blobMetadataParser, - BlobToObjectMetadata blobToObjectMetadata, EncryptionService encryptionService, - @Named(PROPERTY_USER_METADATA_PREFIX) String userMdPrefix) { + BlobToObjectMetadata blobToObjectMetadata, @Named(PROPERTY_USER_METADATA_PREFIX) String userMdPrefix) { this.blobMetadataParser = blobMetadataParser; this.blobToObjectMetadata = blobToObjectMetadata; - this.encryptionService = encryptionService; this.userMdPrefix = userMdPrefix; } @@ -71,7 +67,7 @@ public class ParseObjectMetadataFromHeaders implements MutableObjectMetadata to = blobToObjectMetadata.apply(base); addETagTo(from, to); to.setSize(attemptToParseSizeAndRangeFromHeaders(from)); - to.setContentMD5(encryptionService.fromHex(Utils.replaceAll(to.getETag(), '"', ""))); + to.setContentMD5(CryptoStreams.hex(Utils.replaceAll(to.getETag(), '"', ""))); to.setCacheControl(from.getFirstHeaderOrNull(HttpHeaders.CACHE_CONTROL)); to.setContentDisposition(from.getFirstHeaderOrNull("Content-Disposition")); to.setContentEncoding(from.getFirstHeaderOrNull(HttpHeaders.CONTENT_ENCODING)); diff --git a/aws/core/src/main/java/org/jclouds/aws/s3/xml/ListBucketHandler.java b/aws/core/src/main/java/org/jclouds/aws/s3/xml/ListBucketHandler.java index 1fae1957dd..fcc8a71cdd 100755 --- a/aws/core/src/main/java/org/jclouds/aws/s3/xml/ListBucketHandler.java +++ b/aws/core/src/main/java/org/jclouds/aws/s3/xml/ListBucketHandler.java @@ -29,8 +29,8 @@ import org.jclouds.aws.s3.domain.ObjectMetadata; import org.jclouds.aws.s3.domain.ObjectMetadata.StorageClass; import org.jclouds.aws.s3.domain.internal.BucketListObjectMetadata; import org.jclouds.aws.s3.domain.internal.ListBucketResponseImpl; +import org.jclouds.crypto.CryptoStreams; import org.jclouds.date.DateService; -import org.jclouds.encryption.EncryptionService; import org.jclouds.http.functions.ParseSax; import org.jclouds.util.Utils; import org.xml.sax.Attributes; @@ -54,7 +54,6 @@ public class ListBucketHandler extends ParseSax.HandlerWithResult { private StringBuilder currentText = new StringBuilder(); byte[] md5; - private final EncryptionService encryptionService; - - @Inject - MD5Handler(EncryptionService encryptionService) { - this.encryptionService = encryptionService; - } - public byte[] getResult() { return md5; } @@ -48,7 +39,7 @@ public class MD5Handler extends ParseSax.HandlerWithResult { public void endElement(String uri, String name, String qName) { if (qName.equals("MD5OfMessageBody")) { String md5Hex = currentText.toString().trim(); - this.md5 = encryptionService.fromHex(md5Hex); + this.md5 = CryptoStreams.hex(md5Hex); } currentText = new StringBuilder(); } diff --git a/aws/core/src/main/java/org/jclouds/aws/sqs/xml/RegexMD5Handler.java b/aws/core/src/main/java/org/jclouds/aws/sqs/xml/RegexMD5Handler.java index c9ba1e315e..7891ed39e3 100644 --- a/aws/core/src/main/java/org/jclouds/aws/sqs/xml/RegexMD5Handler.java +++ b/aws/core/src/main/java/org/jclouds/aws/sqs/xml/RegexMD5Handler.java @@ -23,7 +23,7 @@ import java.util.regex.Pattern; import javax.inject.Inject; -import org.jclouds.encryption.EncryptionService; +import org.jclouds.crypto.CryptoStreams; import org.jclouds.http.HttpResponse; import org.jclouds.http.functions.ReturnStringIf2xx; @@ -40,11 +40,9 @@ import com.google.inject.Singleton; public class RegexMD5Handler implements Function { Pattern pattern = Pattern.compile("([\\S&&[^<]]+)"); private final ReturnStringIf2xx returnStringIf200; - private final EncryptionService encryptionService; @Inject - RegexMD5Handler(EncryptionService encryptionService, ReturnStringIf2xx returnStringIf200) { - this.encryptionService = encryptionService; + RegexMD5Handler(ReturnStringIf2xx returnStringIf200) { this.returnStringIf200 = returnStringIf200; } @@ -55,7 +53,7 @@ public class RegexMD5Handler implements Function { if (content != null) { Matcher matcher = pattern.matcher(content); if (matcher.find()) { - value = encryptionService.fromHex(matcher.group(1)); + value = CryptoStreams.hex(matcher.group(1)); } } return value; diff --git a/aws/core/src/test/java/org/jclouds/aws/ec2/services/AMIClientLiveTest.java b/aws/core/src/test/java/org/jclouds/aws/ec2/services/AMIClientLiveTest.java index 8414492868..756523f7c1 100644 --- a/aws/core/src/test/java/org/jclouds/aws/ec2/services/AMIClientLiveTest.java +++ b/aws/core/src/test/java/org/jclouds/aws/ec2/services/AMIClientLiveTest.java @@ -37,7 +37,6 @@ import org.jclouds.aws.ec2.domain.Image; import org.jclouds.aws.ec2.domain.RootDeviceType; import org.jclouds.aws.ec2.domain.Image.ImageType; import org.jclouds.logging.log4j.config.Log4JLoggingModule; -import org.jclouds.rest.ResourceNotFoundException; import org.jclouds.rest.RestContext; import org.jclouds.rest.RestContextFactory; import org.testng.annotations.AfterTest; @@ -78,9 +77,8 @@ public class AMIClientLiveTest { client = context.getApi().getAMIServices(); } - @Test(expectedExceptions = ResourceNotFoundException.class) public void testDescribeImageNotExists() { - client.describeImagesInRegion(null, imageIds("ami-cdf819a3")); + assertEquals(client.describeImagesInRegion(null, imageIds("ami-cdf819a3")).size(), 0); } @Test(expectedExceptions = AWSResponseException.class) diff --git a/aws/core/src/test/java/org/jclouds/aws/s3/functions/ParseObjectMetadataFromHeadersTest.java b/aws/core/src/test/java/org/jclouds/aws/s3/functions/ParseObjectMetadataFromHeadersTest.java index 2dbd6adefe..3db0d06886 100644 --- a/aws/core/src/test/java/org/jclouds/aws/s3/functions/ParseObjectMetadataFromHeadersTest.java +++ b/aws/core/src/test/java/org/jclouds/aws/s3/functions/ParseObjectMetadataFromHeadersTest.java @@ -23,8 +23,6 @@ import static org.easymock.classextension.EasyMock.createMock; import static org.easymock.classextension.EasyMock.replay; import static org.testng.Assert.assertEquals; -import java.security.NoSuchAlgorithmException; -import java.security.cert.CertificateException; import java.util.Date; import java.util.Map; @@ -37,14 +35,12 @@ import org.jclouds.aws.s3.domain.internal.MutableObjectMetadataImpl; import org.jclouds.blobstore.domain.MutableBlobMetadata; import org.jclouds.blobstore.domain.internal.MutableBlobMetadataImpl; import org.jclouds.blobstore.functions.ParseSystemAndUserMetadataFromHeaders; -import org.jclouds.encryption.EncryptionService; -import org.jclouds.encryption.internal.JCEEncryptionService; +import org.jclouds.crypto.CryptoStreams; import org.jclouds.http.HttpResponse; import org.jclouds.io.Payloads; import org.testng.annotations.BeforeTest; import org.testng.annotations.Test; -import com.google.common.base.Throwables; import com.google.common.collect.ImmutableMap; /** @@ -53,17 +49,6 @@ import com.google.common.collect.ImmutableMap; @Test(testName = "s3.ParseObjectMetadataFromHeadersTest") public class ParseObjectMetadataFromHeadersTest { - protected volatile static EncryptionService encryptionService; - static { - try { - encryptionService = new JCEEncryptionService(); - } catch (NoSuchAlgorithmException e) { - Throwables.propagate(e); - } catch (CertificateException e) { - Throwables.propagate(e); - } - } - @Test void testNormal() throws Exception { HttpResponse http = new HttpResponse(400, "boa", Payloads.newStringPayload("")); @@ -72,8 +57,8 @@ public class ParseObjectMetadataFromHeadersTest { http.getHeaders().put(HttpHeaders.CACHE_CONTROL, "cacheControl"); http.getHeaders().put("Content-Disposition", "contentDisposition"); http.getHeaders().put(HttpHeaders.CONTENT_ENCODING, "encoding"); - ParseObjectMetadataFromHeaders parser = new ParseObjectMetadataFromHeaders(blobParser(http, "\"abc\""), - blobToObjectMetadata, encryptionService, "x-amz-meta-"); + ParseObjectMetadataFromHeaders parser = new ParseObjectMetadataFromHeaders(blobParser(http, "\"abcd\""), + blobToObjectMetadata, "x-amz-meta-"); MutableObjectMetadata response = parser.apply(http); assertEquals(response, expects); } @@ -87,9 +72,9 @@ public class ParseObjectMetadataFromHeadersTest { http.getHeaders().put(HttpHeaders.CACHE_CONTROL, "cacheControl"); http.getHeaders().put("Content-Disposition", "contentDisposition"); http.getHeaders().put(HttpHeaders.CONTENT_ENCODING, "encoding"); - http.getHeaders().put("x-amz-meta-object-eTag", "\"abc\""); + http.getHeaders().put("x-amz-meta-object-eTag", "\"abcd\""); ParseObjectMetadataFromHeaders parser = new ParseObjectMetadataFromHeaders(blobParser(http, null), - blobToObjectMetadata, encryptionService, "x-amz-meta-"); + blobToObjectMetadata, "x-amz-meta-"); MutableObjectMetadata response = parser.apply(http); assertEquals(response, expects); } @@ -120,9 +105,9 @@ public class ParseObjectMetadataFromHeadersTest { expects.setCacheControl("cacheControl"); expects.setContentDisposition("contentDisposition"); expects.setContentEncoding("encoding"); - expects.setContentMD5(encryptionService.fromHex("abc")); + expects.setContentMD5(CryptoStreams.hex("abcd")); expects.setContentType("type"); - expects.setETag("\"abc\""); + expects.setETag("\"abcd\""); expects.setKey("key"); expects.setLastModified(now); expects.setOwner(null); diff --git a/aws/core/src/test/java/org/jclouds/aws/s3/internal/StubS3AsyncClient.java b/aws/core/src/test/java/org/jclouds/aws/s3/internal/StubS3AsyncClient.java index cfa4c49a9f..27e86b6b7f 100755 --- a/aws/core/src/test/java/org/jclouds/aws/s3/internal/StubS3AsyncClient.java +++ b/aws/core/src/test/java/org/jclouds/aws/s3/internal/StubS3AsyncClient.java @@ -21,7 +21,6 @@ package org.jclouds.aws.s3.internal; import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.util.concurrent.Futures.immediateFailedFuture; import static com.google.common.util.concurrent.Futures.immediateFuture; -import static org.jclouds.concurrent.ConcurrentUtils.compose; import java.util.Date; import java.util.Map; @@ -67,6 +66,7 @@ import org.jclouds.blobstore.domain.BlobMetadata; import org.jclouds.blobstore.domain.MutableBlobMetadata; import org.jclouds.blobstore.functions.HttpGetOptionsListToGetOptions; import org.jclouds.blobstore.options.ListContainerOptions; +import org.jclouds.concurrent.Futures; import org.jclouds.date.DateService; import org.jclouds.domain.Location; import org.jclouds.domain.LocationScope; @@ -144,7 +144,7 @@ public class StubS3AsyncClient implements S3AsyncClient { public ListenableFuture listBucket(final String name, ListBucketOptions... optionsList) { ListContainerOptions options = bucket2ContainerListOptions.apply(optionsList); - return compose(blobStore.list(name, options), resource2BucketList, service); + return Futures.compose(blobStore.list(name, options), resource2BucketList, service); } public ListenableFuture copyObject(final String sourceBucket, final String sourceObject, @@ -272,11 +272,11 @@ public class StubS3AsyncClient implements S3AsyncClient { public ListenableFuture getObject(final String bucketName, final String key, final GetOptions... options) { org.jclouds.blobstore.options.GetOptions getOptions = httpGetOptionsConverter.apply(options); - return compose(blobStore.getBlob(bucketName, key, getOptions), blob2Object, service); + return Futures.compose(blobStore.getBlob(bucketName, key, getOptions), blob2Object, service); } public ListenableFuture headObject(String bucketName, String key) { - return compose(blobStore.blobMetadata(bucketName, key), new Function() { + return Futures.compose(blobStore.blobMetadata(bucketName, key), new Function() { @Override public ObjectMetadata apply(BlobMetadata from) { return blob2ObjectMetadata.apply(from); diff --git a/aws/core/src/test/java/org/jclouds/aws/s3/xml/ListBucketHandlerTest.java b/aws/core/src/test/java/org/jclouds/aws/s3/xml/ListBucketHandlerTest.java index 8b7c6cb900..c38222ae0c 100755 --- a/aws/core/src/test/java/org/jclouds/aws/s3/xml/ListBucketHandlerTest.java +++ b/aws/core/src/test/java/org/jclouds/aws/s3/xml/ListBucketHandlerTest.java @@ -21,8 +21,6 @@ package org.jclouds.aws.s3.xml; import static org.testng.Assert.assertEquals; import java.io.InputStream; -import java.security.NoSuchAlgorithmException; -import java.security.cert.CertificateException; import java.util.TreeSet; import org.jclouds.aws.s3.domain.CanonicalUser; @@ -31,9 +29,8 @@ import org.jclouds.aws.s3.domain.ObjectMetadata; import org.jclouds.aws.s3.domain.ObjectMetadata.StorageClass; import org.jclouds.aws.s3.domain.internal.BucketListObjectMetadata; import org.jclouds.aws.s3.domain.internal.ListBucketResponseImpl; +import org.jclouds.crypto.CryptoStreams; import org.jclouds.date.DateService; -import org.jclouds.encryption.EncryptionService; -import org.jclouds.encryption.internal.JCEEncryptionService; import org.jclouds.http.HttpException; import org.jclouds.http.functions.BaseHandlerTest; import org.jclouds.http.functions.ParseSax; @@ -41,7 +38,6 @@ import org.jclouds.util.Utils; import org.testng.annotations.BeforeTest; import org.testng.annotations.Test; -import com.google.common.base.Throwables; import com.google.common.collect.ImmutableList; @Test(groups = "unit", testName = "s3.ListBucketHandlerTest") @@ -50,17 +46,6 @@ public class ListBucketHandlerTest extends BaseHandlerTest { public static final String listBucketWithSlashDelimiterAndCommonPrefixApps = " / apps/"; private DateService dateService; - protected volatile static EncryptionService encryptionService; - static { - try { - encryptionService = new JCEEncryptionService(); - } catch (NoSuchAlgorithmException e) { - Throwables.propagate(e); - } catch (CertificateException e) { - Throwables.propagate(e); - } - } - @BeforeTest @Override protected void setUpInjector() { @@ -74,47 +59,50 @@ public class ListBucketHandlerTest extends BaseHandlerTest { CanonicalUser owner = new CanonicalUser("e1a5f66a480ca99a4fdfe8e318c3020446c9989d7004e7778029fbcc5d990fa0", "ferncam"); ListBucketResponse expected = new ListBucketResponseImpl("adriancole.org.jclouds.aws.s3.amazons3testdelimiter", - ImmutableList.of( - (ObjectMetadata) new BucketListObjectMetadata("apps/0", dateService - .iso8601DateParse("2009-05-07T18:27:08.000Z"), "\"c82e6a0025c31c5de5947fda62ac51ab\"", - encryptionService.fromHex("c82e6a0025c31c5de5947fda62ac51ab"), 8, owner, - StorageClass.STANDARD), - (ObjectMetadata) new BucketListObjectMetadata("apps/1", dateService - .iso8601DateParse("2009-05-07T18:27:09.000Z"), "\"944fab2c5a9a6bacf07db5e688310d7a\"", - encryptionService.fromHex("944fab2c5a9a6bacf07db5e688310d7a"), 8, owner, - StorageClass.STANDARD), - (ObjectMetadata) new BucketListObjectMetadata("apps/2", dateService - .iso8601DateParse("2009-05-07T18:27:09.000Z"), "\"a227b8888045c8fd159fb495214000f0\"", - encryptionService.fromHex("a227b8888045c8fd159fb495214000f0"), 8, owner, - StorageClass.STANDARD), - (ObjectMetadata) new BucketListObjectMetadata("apps/3", dateService - .iso8601DateParse("2009-05-07T18:27:09.000Z"), "\"c9caa76c3dec53e2a192608ce73eef03\"", - encryptionService.fromHex("c9caa76c3dec53e2a192608ce73eef03"), 8, owner, - StorageClass.STANDARD), - (ObjectMetadata) new BucketListObjectMetadata("apps/4", dateService - .iso8601DateParse("2009-05-07T18:27:09.000Z"), "\"1ce5d0dcc6154a647ea90c7bdf82a224\"", - encryptionService.fromHex("1ce5d0dcc6154a647ea90c7bdf82a224"), 8, owner, - StorageClass.STANDARD), - (ObjectMetadata) new BucketListObjectMetadata("apps/5", dateService - .iso8601DateParse("2009-05-07T18:27:09.000Z"), "\"79433524d87462ee05708a8ef894ed55\"", - encryptionService.fromHex("79433524d87462ee05708a8ef894ed55"), 8, owner, - StorageClass.STANDARD), - (ObjectMetadata) new BucketListObjectMetadata("apps/6", dateService - .iso8601DateParse("2009-05-07T18:27:10.000Z"), "\"dd00a060b28ddca8bc5a21a49e306f67\"", - encryptionService.fromHex("dd00a060b28ddca8bc5a21a49e306f67"), 8, owner, - StorageClass.STANDARD), - (ObjectMetadata) new BucketListObjectMetadata("apps/7", dateService - .iso8601DateParse("2009-05-07T18:27:10.000Z"), "\"8cd06eca6e819a927b07a285d750b100\"", - encryptionService.fromHex("8cd06eca6e819a927b07a285d750b100"), 8, owner, - StorageClass.STANDARD), - (ObjectMetadata) new BucketListObjectMetadata("apps/8", dateService - .iso8601DateParse("2009-05-07T18:27:10.000Z"), "\"174495094d0633b92cbe46603eee6bad\"", - encryptionService.fromHex("174495094d0633b92cbe46603eee6bad"), 8, owner, - StorageClass.STANDARD), - (ObjectMetadata) new BucketListObjectMetadata("apps/9", dateService - .iso8601DateParse("2009-05-07T18:27:10.000Z"), "\"cd8a19b26fea8a827276df0ad11c580d\"", - encryptionService.fromHex("cd8a19b26fea8a827276df0ad11c580d"), 8, owner, - StorageClass.STANDARD)), "apps/", null, null, 1000, null, false, new TreeSet()); + ImmutableList + .of( + (ObjectMetadata) new BucketListObjectMetadata("apps/0", dateService + .iso8601DateParse("2009-05-07T18:27:08.000Z"), + "\"c82e6a0025c31c5de5947fda62ac51ab\"", CryptoStreams + .hex("c82e6a0025c31c5de5947fda62ac51ab"), 8, owner, + StorageClass.STANDARD), (ObjectMetadata) new BucketListObjectMetadata( + "apps/1", dateService.iso8601DateParse("2009-05-07T18:27:09.000Z"), + "\"944fab2c5a9a6bacf07db5e688310d7a\"", CryptoStreams + .hex("944fab2c5a9a6bacf07db5e688310d7a"), 8, owner, + StorageClass.STANDARD), (ObjectMetadata) new BucketListObjectMetadata( + "apps/2", dateService.iso8601DateParse("2009-05-07T18:27:09.000Z"), + "\"a227b8888045c8fd159fb495214000f0\"", CryptoStreams + .hex("a227b8888045c8fd159fb495214000f0"), 8, owner, + StorageClass.STANDARD), (ObjectMetadata) new BucketListObjectMetadata( + "apps/3", dateService.iso8601DateParse("2009-05-07T18:27:09.000Z"), + "\"c9caa76c3dec53e2a192608ce73eef03\"", CryptoStreams + .hex("c9caa76c3dec53e2a192608ce73eef03"), 8, owner, + StorageClass.STANDARD), (ObjectMetadata) new BucketListObjectMetadata( + "apps/4", dateService.iso8601DateParse("2009-05-07T18:27:09.000Z"), + "\"1ce5d0dcc6154a647ea90c7bdf82a224\"", CryptoStreams + .hex("1ce5d0dcc6154a647ea90c7bdf82a224"), 8, owner, + StorageClass.STANDARD), (ObjectMetadata) new BucketListObjectMetadata( + "apps/5", dateService.iso8601DateParse("2009-05-07T18:27:09.000Z"), + "\"79433524d87462ee05708a8ef894ed55\"", CryptoStreams + .hex("79433524d87462ee05708a8ef894ed55"), 8, owner, + StorageClass.STANDARD), (ObjectMetadata) new BucketListObjectMetadata( + "apps/6", dateService.iso8601DateParse("2009-05-07T18:27:10.000Z"), + "\"dd00a060b28ddca8bc5a21a49e306f67\"", CryptoStreams + .hex("dd00a060b28ddca8bc5a21a49e306f67"), 8, owner, + StorageClass.STANDARD), (ObjectMetadata) new BucketListObjectMetadata( + "apps/7", dateService.iso8601DateParse("2009-05-07T18:27:10.000Z"), + "\"8cd06eca6e819a927b07a285d750b100\"", CryptoStreams + .hex("8cd06eca6e819a927b07a285d750b100"), 8, owner, + StorageClass.STANDARD), (ObjectMetadata) new BucketListObjectMetadata( + "apps/8", dateService.iso8601DateParse("2009-05-07T18:27:10.000Z"), + "\"174495094d0633b92cbe46603eee6bad\"", CryptoStreams + .hex("174495094d0633b92cbe46603eee6bad"), 8, owner, + StorageClass.STANDARD), (ObjectMetadata) new BucketListObjectMetadata( + "apps/9", dateService.iso8601DateParse("2009-05-07T18:27:10.000Z"), + "\"cd8a19b26fea8a827276df0ad11c580d\"", CryptoStreams + .hex("cd8a19b26fea8a827276df0ad11c580d"), 8, owner, + StorageClass.STANDARD)), "apps/", null, null, 1000, null, false, + new TreeSet()); ListBucketResponse result = (ListBucketResponse) factory.create(injector.getInstance(ListBucketHandler.class)) .parse(is); diff --git a/aws/core/src/test/java/org/jclouds/aws/sqs/SQSClientLiveTest.java b/aws/core/src/test/java/org/jclouds/aws/sqs/SQSClientLiveTest.java index 9abc99b9ad..022f64e9be 100644 --- a/aws/core/src/test/java/org/jclouds/aws/sqs/SQSClientLiveTest.java +++ b/aws/core/src/test/java/org/jclouds/aws/sqs/SQSClientLiveTest.java @@ -30,10 +30,10 @@ import java.util.SortedSet; import org.jclouds.aws.AWSResponseException; import org.jclouds.aws.domain.Region; import org.jclouds.aws.sqs.domain.Queue; +import org.jclouds.crypto.CryptoStreams; import org.jclouds.logging.log4j.config.Log4JLoggingModule; import org.jclouds.rest.RestContext; import org.jclouds.rest.RestContextFactory; -import org.jclouds.util.Utils; import org.testng.annotations.AfterTest; import org.testng.annotations.BeforeGroups; import org.testng.annotations.Test; @@ -63,14 +63,14 @@ public class SQSClientLiveTest { String credential = checkNotNull(System.getProperty("jclouds.test.credential"), "jclouds.test.credential"); context = new RestContextFactory().createContext("sqs", identity, credential, ImmutableSet - . of(new Log4JLoggingModule())); + . of(new Log4JLoggingModule())); this.client = context.getApi(); } @Test void testListQueuesInRegion() throws InterruptedException { for (String region : Lists.newArrayList(null, Region.EU_WEST_1, Region.US_EAST_1, Region.US_WEST_1, - Region.AP_SOUTHEAST_1)) { + Region.AP_SOUTHEAST_1)) { SortedSet allResults = Sets.newTreeSet(client.listQueuesInRegion(region)); assertNotNull(allResults); if (allResults.size() >= 1) { @@ -87,7 +87,7 @@ public class SQSClientLiveTest { String queueName = PREFIX + "1"; for (final String region : Lists.newArrayList(null, Region.EU_WEST_1, Region.US_EAST_1, Region.US_WEST_1, - Region.AP_SOUTHEAST_1)) { + Region.AP_SOUTHEAST_1)) { try { SortedSet result = Sets.newTreeSet(client.listQueuesInRegion(region, queuePrefix(queueName))); if (result.size() >= 1) { @@ -121,9 +121,9 @@ public class SQSClientLiveTest { } @Test(dependsOnMethods = "testCreateQueue") - void testSendMessage() throws InterruptedException { + void testSendMessage() throws InterruptedException, IOException { String message = "hardyharhar"; - byte[] md5 = context.utils().encryption().md5(Utils.toInputStream(message)); + byte[] md5 = CryptoStreams.md5(message.getBytes()); for (Queue queue : queues) { assertEquals(client.sendMessage(queue, message), md5); } @@ -144,9 +144,8 @@ public class SQSClientLiveTest { private static final int INCONSISTENCY_WINDOW = 10000; /** - * Due to eventual consistency, container commands may not return correctly - * immediately. Hence, we will try up to the inconsistency window to see if - * the assertion completes. + * Due to eventual consistency, container commands may not return correctly immediately. Hence, + * we will try up to the inconsistency window to see if the assertion completes. */ protected static void assertEventually(Runnable assertion) throws InterruptedException { long start = System.currentTimeMillis(); @@ -156,7 +155,7 @@ public class SQSClientLiveTest { assertion.run(); if (i > 0) System.err.printf("%d attempts and %dms asserting %s%n", i + 1, System.currentTimeMillis() - start, - assertion.getClass().getSimpleName()); + assertion.getClass().getSimpleName()); return; } catch (AssertionError e) { error = e; diff --git a/aws/demos/speedtest-sqs/src/main/java/org/jclouds/aws/sqs/SpeedTest.java b/aws/demos/speedtest-sqs/src/main/java/org/jclouds/aws/sqs/SpeedTest.java index 8908d1fc4a..06557e5b66 100755 --- a/aws/demos/speedtest-sqs/src/main/java/org/jclouds/aws/sqs/SpeedTest.java +++ b/aws/demos/speedtest-sqs/src/main/java/org/jclouds/aws/sqs/SpeedTest.java @@ -18,16 +18,17 @@ */ package org.jclouds.aws.sqs; -import static org.jclouds.concurrent.ConcurrentUtils.sameThreadExecutor; import static org.jclouds.aws.sqs.options.ListQueuesOptions.Builder.queuePrefix; -import static org.jclouds.concurrent.ConcurrentUtils.awaitCompletion; +import static org.jclouds.concurrent.FutureIterables.awaitCompletion; import java.util.Map; import java.util.Set; import java.util.SortedSet; +import java.util.concurrent.Future; import org.jclouds.aws.domain.Region; import org.jclouds.aws.sqs.domain.Queue; +import org.jclouds.concurrent.MoreExecutors; import org.jclouds.enterprise.config.EnterpriseConfigurationModule; import org.jclouds.logging.ConsoleLogger; import org.jclouds.logging.Logger; @@ -38,7 +39,6 @@ import org.jclouds.rest.RestContextFactory; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Maps; import com.google.common.collect.Sets; -import java.util.concurrent.Future; import com.google.inject.Module; /** @@ -50,8 +50,8 @@ import com.google.inject.Module; * @author Adrian Cole */ public class SpeedTest { - private static final ImmutableSet REGIONS = ImmutableSet.of(Region.EU_WEST_1, - Region.US_EAST_1, Region.US_WEST_1, Region.AP_SOUTHEAST_1); + private static final ImmutableSet REGIONS = ImmutableSet.of(Region.EU_WEST_1, Region.US_EAST_1, + Region.US_WEST_1, Region.AP_SOUTHEAST_1); public static final int PARAMETERS = 4; public static final String INVALID_SYNTAX = "Invalid number of parameters. Syntax is: \"accesskeyid\" \"secretkey\" \"queueName\" \"messageCount\" "; @@ -84,11 +84,10 @@ public class SpeedTest { int messageCount = Integer.parseInt(args[3]); Set modules = isEnterprise ? ImmutableSet. of(new NullLoggingModule(), - new EnterpriseConfigurationModule()) : ImmutableSet - . of(new NullLoggingModule()); + new EnterpriseConfigurationModule()) : ImmutableSet. of(new NullLoggingModule()); - RestContext context = new RestContextFactory().createContext( - "sqs", accesskeyid, secretkey, modules); + RestContext context = new RestContextFactory().createContext("sqs", accesskeyid, + secretkey, modules); try { Set queues = Sets.newHashSet(); @@ -122,30 +121,25 @@ public class SpeedTest { } } - private static void runTests(int messageCount, String contextName, - RestContext context, Set queues) - throws InterruptedException { + private static void runTests(int messageCount, String contextName, RestContext context, + Set queues) throws InterruptedException { String message = "1"; long timeOut = messageCount * 200; // minimum rate should be at least 5/second for (Queue queue : queues) { - logger.info("context: %s, region: %s, queueName: %s", contextName, queue.getRegion(), - queue.getName()); + logger.info("context: %s, region: %s, queueName: %s", contextName, queue.getRegion(), queue.getName()); // fire off all the messages for the test Map> responses = Maps.newHashMap(); for (int i = 0; i < messageCount; i++) { - responses.put(new QueueMessage(queue, message), context.getAsyncApi().sendMessage( - queue, message)); + responses.put(new QueueMessage(queue, message), context.getAsyncApi().sendMessage(queue, message)); } - Map exceptions = awaitCompletion(responses, sameThreadExecutor(), - timeOut, traceLogger, String.format("context: %s, region: %s", contextName, queue - .getRegion())); + Map exceptions = awaitCompletion(responses, MoreExecutors.sameThreadExecutor(), + timeOut, traceLogger, String.format("context: %s, region: %s", contextName, queue.getRegion())); if (exceptions.size() > 0) - logger.error("problems in context: %s, region: %s: %s", contextName, queue.getRegion(), - exceptions); + logger.error("problems in context: %s, region: %s: %s", contextName, queue.getRegion(), exceptions); System.gc(); logger.info("pausing 5 seconds before the next run"); @@ -153,21 +147,20 @@ public class SpeedTest { } } - private static void createQueues(String queueName, - RestContext nullLoggingDefaultContext, Set queues) { + private static void createQueues(String queueName, RestContext nullLoggingDefaultContext, + Set queues) { for (String region : REGIONS) { logger.info("creating queue: %s in region %s", queueName, region); queues.add(nullLoggingDefaultContext.getApi().createQueueInRegion(region, queueName)); } } - private static boolean purgeQueues(String queueName, - RestContext nullLoggingDefaultContext) { + private static boolean purgeQueues(String queueName, RestContext nullLoggingDefaultContext) { boolean deleted = false; for (String region : REGIONS) { try { - SortedSet result = Sets.newTreeSet(nullLoggingDefaultContext.getApi() - .listQueuesInRegion(region, queuePrefix(queueName))); + SortedSet result = Sets.newTreeSet(nullLoggingDefaultContext.getApi().listQueuesInRegion(region, + queuePrefix(queueName))); if (result.size() >= 1) { nullLoggingDefaultContext.getApi().deleteQueue(result.last()); logger.info("deleted queue: %s in region %s", queueName, region); diff --git a/azure/src/main/java/org/jclouds/azure/storage/blob/blobstore/AzureAsyncBlobStore.java b/azure/src/main/java/org/jclouds/azure/storage/blob/blobstore/AzureAsyncBlobStore.java index 4dd2b83c25..7df8debcc3 100644 --- a/azure/src/main/java/org/jclouds/azure/storage/blob/blobstore/AzureAsyncBlobStore.java +++ b/azure/src/main/java/org/jclouds/azure/storage/blob/blobstore/AzureAsyncBlobStore.java @@ -19,12 +19,10 @@ package org.jclouds.azure.storage.blob.blobstore; import static com.google.common.base.Preconditions.checkNotNull; -import static org.jclouds.concurrent.ConcurrentUtils.compose; import static org.jclouds.azure.storage.options.ListOptions.Builder.includeMetadata; import java.util.Set; import java.util.concurrent.ExecutorService; -import com.google.common.util.concurrent.ListenableFuture; import javax.inject.Inject; import javax.inject.Named; @@ -54,11 +52,13 @@ import org.jclouds.blobstore.functions.BlobToHttpGetOptions; import org.jclouds.blobstore.internal.BaseAsyncBlobStore; import org.jclouds.blobstore.options.ListContainerOptions; import org.jclouds.blobstore.util.BlobUtils; +import org.jclouds.concurrent.Futures; import org.jclouds.domain.Location; import org.jclouds.http.options.GetOptions; import com.google.common.base.Function; import com.google.common.collect.Iterables; +import com.google.common.util.concurrent.ListenableFuture; /** * @author Adrian Cole @@ -101,15 +101,16 @@ public class AzureAsyncBlobStore extends BaseAsyncBlobStore { */ @Override public ListenableFuture> list() { - return compose( - async.listContainers(includeMetadata()), - new Function, org.jclouds.blobstore.domain.PageSet>() { - public org.jclouds.blobstore.domain.PageSet apply( - BoundedSet from) { - return new PageSetImpl(Iterables.transform(from, container2ResourceMd), from - .getNextMarker()); - } - }, service); + return Futures + .compose( + async.listContainers(includeMetadata()), + new Function, org.jclouds.blobstore.domain.PageSet>() { + public org.jclouds.blobstore.domain.PageSet apply( + BoundedSet from) { + return new PageSetImpl(Iterables.transform(from, container2ResourceMd), + from.getNextMarker()); + } + }, service); } /** @@ -146,7 +147,7 @@ public class AzureAsyncBlobStore extends BaseAsyncBlobStore { public ListenableFuture> list(String container, ListContainerOptions options) { ListBlobsOptions azureOptions = blobStore2AzureContainerListOptions.apply(options); ListenableFuture returnVal = async.listBlobs(container, azureOptions.includeMetadata()); - return compose(returnVal, azure2BlobStoreResourceList, service); + return Futures.compose(returnVal, azure2BlobStoreResourceList, service); } /** @@ -172,7 +173,7 @@ public class AzureAsyncBlobStore extends BaseAsyncBlobStore { public ListenableFuture getBlob(String container, String key, org.jclouds.blobstore.options.GetOptions options) { GetOptions azureOptions = blob2ObjectGetOptions.apply(options); ListenableFuture returnVal = async.getBlob(container, key, azureOptions); - return compose(returnVal, azureBlob2Blob, service); + return Futures.compose(returnVal, azureBlob2Blob, service); } /** @@ -224,7 +225,7 @@ public class AzureAsyncBlobStore extends BaseAsyncBlobStore { */ @Override public ListenableFuture blobMetadata(String container, String key) { - return compose(async.getBlobProperties(container, key), new Function() { + return Futures.compose(async.getBlobProperties(container, key), new Function() { @Override public BlobMetadata apply(BlobProperties from) { diff --git a/azure/src/main/java/org/jclouds/azure/storage/blob/domain/AzureBlob.java b/azure/src/main/java/org/jclouds/azure/storage/blob/domain/AzureBlob.java index b9c5661610..7fc4a33791 100644 --- a/azure/src/main/java/org/jclouds/azure/storage/blob/domain/AzureBlob.java +++ b/azure/src/main/java/org/jclouds/azure/storage/blob/domain/AzureBlob.java @@ -20,7 +20,7 @@ package org.jclouds.azure.storage.blob.domain; import javax.annotation.Nullable; -import org.jclouds.http.PayloadEnclosing; +import org.jclouds.io.PayloadEnclosing; import com.google.common.collect.Multimap; 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 63d2ace878..9e47ededac 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,9 +24,9 @@ import javax.inject.Inject; import org.jclouds.azure.storage.blob.domain.AzureBlob; import org.jclouds.azure.storage.blob.domain.MutableBlobProperties; -import org.jclouds.http.PayloadEnclosing; import org.jclouds.http.internal.PayloadEnclosingImpl; import org.jclouds.io.Payload; +import org.jclouds.io.PayloadEnclosing; import org.jclouds.io.payloads.DelegatingPayload; import com.google.common.collect.LinkedHashMultimap; diff --git a/azure/src/main/java/org/jclouds/azure/storage/blob/xml/ContainerNameEnumerationResultsHandler.java b/azure/src/main/java/org/jclouds/azure/storage/blob/xml/ContainerNameEnumerationResultsHandler.java index 891fdeb473..9df5ca5f78 100644 --- a/azure/src/main/java/org/jclouds/azure/storage/blob/xml/ContainerNameEnumerationResultsHandler.java +++ b/azure/src/main/java/org/jclouds/azure/storage/blob/xml/ContainerNameEnumerationResultsHandler.java @@ -31,8 +31,8 @@ import org.jclouds.azure.storage.blob.domain.LeaseStatus; import org.jclouds.azure.storage.blob.domain.ListBlobsResponse; import org.jclouds.azure.storage.blob.domain.internal.BlobPropertiesImpl; import org.jclouds.azure.storage.blob.domain.internal.HashSetListBlobsResponse; +import org.jclouds.crypto.CryptoStreams; import org.jclouds.date.DateService; -import org.jclouds.encryption.EncryptionService; import org.jclouds.http.HttpUtils; import org.jclouds.http.functions.ParseSax; import org.xml.sax.Attributes; @@ -49,8 +49,7 @@ import com.google.common.collect.Sets; * @see * @author Adrian Cole */ -public class ContainerNameEnumerationResultsHandler extends - ParseSax.HandlerWithResult { +public class ContainerNameEnumerationResultsHandler extends ParseSax.HandlerWithResult { private Set blobMetadata = Sets.newLinkedHashSet(); private String prefix; private String marker; @@ -63,7 +62,6 @@ public class ContainerNameEnumerationResultsHandler extends private StringBuilder currentText = new StringBuilder(); - private final EncryptionService encryptionService; private final DateService dateParser; private String delimiter; private String currentName; @@ -81,20 +79,17 @@ public class ContainerNameEnumerationResultsHandler extends private LeaseStatus currentLeaseStatus; @Inject - public ContainerNameEnumerationResultsHandler(EncryptionService encryptionService, - DateService dateParser) { - this.encryptionService = encryptionService; + public ContainerNameEnumerationResultsHandler(DateService dateParser) { this.dateParser = dateParser; } public ListBlobsResponse getResult() { - return new HashSetListBlobsResponse(blobMetadata, containerUrl, prefix, marker, maxResults, - nextMarker, delimiter, blobPrefixes); + return new HashSetListBlobsResponse(blobMetadata, containerUrl, prefix, marker, maxResults, nextMarker, + delimiter, blobPrefixes); } @Override - public void startElement(String uri, String localName, String qName, Attributes attributes) - throws SAXException { + public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { if (qName.equals("Blob")) { inBlob = true; inBlobPrefix = false; @@ -134,10 +129,9 @@ public class ContainerNameEnumerationResultsHandler extends } else if (qName.equals("LeaseStatus")) { currentLeaseStatus = LeaseStatus.fromValue(currentText.toString().trim()); } else if (qName.equals("Blob")) { - BlobProperties md = new BlobPropertiesImpl(currentBlobType, currentName, currentUrl, - currentLastModified, currentETag, currentSize, currentContentType, - currentContentMD5, currentContentEncoding, currentContentLanguage, - currentLeaseStatus, currentMetadata); + BlobProperties md = new BlobPropertiesImpl(currentBlobType, currentName, currentUrl, currentLastModified, + currentETag, currentSize, currentContentType, currentContentMD5, currentContentEncoding, + currentContentLanguage, currentLeaseStatus, currentMetadata); blobMetadata.add(md); currentBlobType = null; currentName = null; @@ -166,7 +160,7 @@ public class ContainerNameEnumerationResultsHandler extends currentSize = Long.parseLong(currentText.toString().trim()); } else if (qName.equals("Content-MD5")) { if (!currentText.toString().trim().equals("")) - currentContentMD5 = encryptionService.fromBase64(currentText.toString().trim()); + currentContentMD5 = CryptoStreams.base64(currentText.toString().trim()); } else if (qName.equals("Content-Type")) { currentContentType = currentText.toString().trim(); } else if (qName.equals("Content-Encoding")) { diff --git a/azure/src/main/java/org/jclouds/azure/storage/filters/SharedKeyLiteAuthentication.java b/azure/src/main/java/org/jclouds/azure/storage/filters/SharedKeyLiteAuthentication.java index 008edd404f..3914359abf 100644 --- a/azure/src/main/java/org/jclouds/azure/storage/filters/SharedKeyLiteAuthentication.java +++ b/azure/src/main/java/org/jclouds/azure/storage/filters/SharedKeyLiteAuthentication.java @@ -32,13 +32,15 @@ import javax.inject.Singleton; import javax.ws.rs.core.HttpHeaders; import org.jclouds.Constants; +import org.jclouds.crypto.Crypto; +import org.jclouds.crypto.CryptoStreams; import org.jclouds.date.TimeStamp; -import org.jclouds.encryption.EncryptionService; import org.jclouds.http.HttpException; import org.jclouds.http.HttpRequest; import org.jclouds.http.HttpRequestFilter; import org.jclouds.http.HttpUtils; import org.jclouds.http.internal.SignatureWire; +import org.jclouds.io.InputSuppliers; import org.jclouds.logging.Logger; import org.jclouds.util.Utils; @@ -59,7 +61,7 @@ public class SharedKeyLiteAuthentication implements HttpRequestFilter { private final String identity; private final byte[] key; private final Provider timeStampProvider; - private final EncryptionService encryptionService; + private final Crypto crypto; private final HttpUtils utils; @Resource @@ -67,16 +69,14 @@ public class SharedKeyLiteAuthentication implements HttpRequestFilter { Logger signatureLog = Logger.NULL; @Inject - public SharedKeyLiteAuthentication(SignatureWire signatureWire, - @Named(Constants.PROPERTY_IDENTITY) String identity, - @Named(Constants.PROPERTY_CREDENTIAL) String encodedKey, - @TimeStamp Provider timeStampProvider, EncryptionService encryptionService, - HttpUtils utils) { - this.encryptionService = encryptionService; + public SharedKeyLiteAuthentication(SignatureWire signatureWire, @Named(Constants.PROPERTY_IDENTITY) String identity, + @Named(Constants.PROPERTY_CREDENTIAL) String encodedKey, @TimeStamp Provider timeStampProvider, + Crypto crypto, HttpUtils utils) { + this.crypto = crypto; this.utils = utils; this.signatureWire = signatureWire; this.identity = identity; - this.key = encryptionService.fromBase64(encodedKey); + this.key = CryptoStreams.base64(encodedKey); this.timeStampProvider = timeStampProvider; } @@ -102,16 +102,13 @@ public class SharedKeyLiteAuthentication implements HttpRequestFilter { } private void appendPayloadMetadata(HttpRequest request, StringBuilder buffer) { - buffer.append( - utils.valueOrEmpty(request.getPayload() == null ? null : request.getPayload() - .getContentMD5())).append("\n"); - buffer.append( - utils.valueOrEmpty(request.getPayload() == null ? null : request.getPayload() - .getContentType())).append("\n"); + buffer.append(utils.valueOrEmpty(request.getPayload() == null ? null : request.getPayload().getContentMD5())) + .append("\n"); + buffer.append(utils.valueOrEmpty(request.getPayload() == null ? null : request.getPayload().getContentType())) + .append("\n"); } - private void calculateAndReplaceAuthHeader(HttpRequest request, String toSign) - throws HttpException { + private void calculateAndReplaceAuthHeader(HttpRequest request, String toSign) throws HttpException { String signature = signString(toSign); if (signatureWire.enabled()) signatureWire.input(Utils.toInputStream(signature)); @@ -122,7 +119,7 @@ public class SharedKeyLiteAuthentication implements HttpRequestFilter { public String signString(String toSign) { String signature; try { - signature = encryptionService.base64(encryptionService.hmacSha256(toSign, key)); + signature = CryptoStreams.base64(CryptoStreams.mac(InputSuppliers.of(toSign), crypto.hmacSHA256(key))); } catch (Exception e) { throw new HttpException("error signing request", e); } @@ -134,8 +131,7 @@ public class SharedKeyLiteAuthentication implements HttpRequestFilter { } private void replaceDateHeader(HttpRequest request) { - request.getHeaders().replaceValues(HttpHeaders.DATE, - Collections.singletonList(timeStampProvider.get())); + request.getHeaders().replaceValues(HttpHeaders.DATE, Collections.singletonList(timeStampProvider.get())); } private void appendCanonicalizedHeaders(HttpRequest request, StringBuilder toSign) { 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 0d45f1ea67..11a02bceed 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 @@ -42,8 +42,10 @@ 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.crypto.CryptoStreams; import org.jclouds.http.HttpResponseException; import org.jclouds.http.options.GetOptions; +import org.jclouds.io.Payloads; import org.jclouds.logging.log4j.config.Log4JLoggingModule; import org.jclouds.util.Utils; import org.testng.annotations.BeforeTest; @@ -73,8 +75,8 @@ public class AzureBlobClientLiveTest { public void setupClient() throws IOException { identity = System.getProperty("jclouds.test.identity"); String credential = System.getProperty("jclouds.test.credential"); - context = new BlobStoreContextFactory().createContext("azureblob", identity, credential, - ImmutableSet. of(new Log4JLoggingModule())); + context = new BlobStoreContextFactory().createContext("azureblob", identity, credential, ImmutableSet + . of(new Log4JLoggingModule())); client = (AzureBlobClient) context.getProviderSpecificContext().getApi(); } @@ -97,8 +99,7 @@ public class AzureBlobClientLiveTest { while (!created) { privateContainer = containerPrefix + new SecureRandom().nextInt(); try { - created = client.createContainer(privateContainer, withMetadata(ImmutableMultimap.of( - "foo", "bar"))); + created = client.createContainer(privateContainer, withMetadata(ImmutableMultimap.of("foo", "bar"))); } catch (UndeclaredThrowableException e) { HttpResponseException htpe = (HttpResponseException) e.getCause().getCause(); if (htpe.getResponse().getStatusCode() == 409) @@ -111,8 +112,8 @@ public class AzureBlobClientLiveTest { long containerCount = response.size(); assertTrue(containerCount >= 1); ListBlobsResponse list = client.listBlobs(privateContainer); - assertEquals(list.getUrl(), URI.create(String.format("https://%s.blob.core.windows.net/%s", - identity, 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 } @@ -164,15 +165,14 @@ public class AzureBlobClientLiveTest { } } ListBlobsResponse list = client.listBlobs(); - assertEquals(list.getUrl(), URI.create(String.format( - "https://%s.blob.core.windows.net/%%24root", identity))); + assertEquals(list.getUrl(), URI.create(String.format("https://%s.blob.core.windows.net/%%24root", identity))); } @Test public void testListContainersWithOptions() throws Exception { - BoundedSet response = client.listContainers(ListOptions.Builder.prefix( - privateContainer).maxResults(1).includeMetadata()); + BoundedSet response = client.listContainers(ListOptions.Builder.prefix(privateContainer) + .maxResults(1).includeMetadata()); assert null != response; long initialContainerCount = response.size(); assertTrue(initialContainerCount >= 0); @@ -186,8 +186,7 @@ public class AzureBlobClientLiveTest { // TODO loop for up to 30 seconds checking if they are really gone } - @Test(timeOut = 5 * 60 * 1000, dependsOnMethods = { "testCreateContainer", - "testCreatePublicContainer" }) + @Test(timeOut = 5 * 60 * 1000, dependsOnMethods = { "testCreateContainer", "testCreatePublicContainer" }) public void testListOwnedContainers() throws Exception { // Test default listing @@ -197,8 +196,7 @@ public class AzureBlobClientLiveTest { // Test listing with options response = client.listContainers(ListOptions.Builder.prefix( - privateContainer.substring(0, privateContainer.length() - 1)).maxResults(1) - .includeMetadata()); + privateContainer.substring(0, privateContainer.length() - 1)).maxResults(1).includeMetadata()); assertEquals(response.size(), 1); assertEquals(Iterables.getOnlyElement(response).getName(), privateContainer); assertEquals(Iterables.getOnlyElement(response).getMetadata(), ImmutableMap.of("foo", "bar")); @@ -214,16 +212,14 @@ public class AzureBlobClientLiveTest { client.deleteContainer("does-not-exist"); } - @Test(timeOut = 5 * 60 * 1000, dependsOnMethods = { "testListOwnedContainers", - "testObjectOperations" }) + @Test(timeOut = 5 * 60 * 1000, dependsOnMethods = { "testListOwnedContainers", "testObjectOperations" }) public void testDeleteContainer() throws Exception { client.deleteContainer(privateContainer); client.deleteContainer(publicContainer); // TODO loop for up to 30 seconds checking if they are really gone } - @Test(timeOut = 5 * 60 * 1000, dependsOnMethods = { "testCreateContainer", - "testCreatePublicContainer" }) + @Test(timeOut = 5 * 60 * 1000, dependsOnMethods = { "testCreateContainer", "testCreatePublicContainer" }) public void testObjectOperations() throws Exception { String data = "Here is my data"; @@ -231,20 +227,18 @@ public class AzureBlobClientLiveTest { AzureBlob object = client.newBlob(); object.getProperties().setName("object"); object.setPayload(data); - context.utils().encryption().generateMD5BufferingIfNotRepeatable(object); + Payloads.calculateMD5(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(context.utils().encryption().hex(md5), context.utils().encryption().hex(object.getProperties() - .getContentMD5())); + assertEquals(CryptoStreams.hex(md5), CryptoStreams.hex(object.getProperties().getContentMD5())); // Test HEAD of missing object assert client.getBlobProperties(privateContainer, "non-existent-object") == null; // Test HEAD of object - BlobProperties metadata = client.getBlobProperties(privateContainer, object.getProperties() - .getName()); + BlobProperties metadata = client.getBlobProperties(privateContainer, object.getProperties().getName()); // TODO assertEquals(metadata.getName(), object.getProperties().getName()); // we can't check this while hacking around lack of content-md5, as GET of the first byte will // show incorrect length 1, the returned size, as opposed to the real length. This is an ok @@ -254,8 +248,7 @@ public class AzureBlobClientLiveTest { // assertEquals(metadata.getSize(), data.length()); assertEquals(metadata.getContentType(), "text/plain"); // Azure doesn't return the Content-MD5 on head request.. - assertEquals(context.utils().encryption().hex(md5), context.utils().encryption().hex(object.getProperties() - .getContentMD5())); + assertEquals(CryptoStreams.hex(md5), CryptoStreams.hex(object.getProperties().getContentMD5())); assertEquals(metadata.getETag(), newEtag); assertEquals(metadata.getMetadata().entrySet().size(), 1); assertEquals(metadata.getMetadata().get("mykey"), "metadata-value"); @@ -276,8 +269,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(context.utils().encryption().hex(md5), context.utils().encryption().hex(getBlob.getProperties() - .getContentMD5())); + assertEquals(CryptoStreams.hex(md5), CryptoStreams.hex(getBlob.getProperties().getContentMD5())); assertEquals(newEtag, getBlob.getProperties().getETag()); // wait until we can update metadata // assertEquals(getBlob.getProperties().getMetadata().entries().size(), 2); @@ -291,15 +283,12 @@ public class AzureBlobClientLiveTest { assertEquals(metadata.getMetadata().get("mykey"), "metadata-value"); // test listing - ListBlobsResponse response = client.listBlobs(privateContainer, ListBlobsOptions.Builder - .prefix( - object.getProperties().getName().substring(0, - object.getProperties().getName().length() - 1)).maxResults(1) - .includeMetadata()); + ListBlobsResponse response = client.listBlobs(privateContainer, ListBlobsOptions.Builder.prefix( + object.getProperties().getName().substring(0, object.getProperties().getName().length() - 1)) + .maxResults(1).includeMetadata()); assertEquals(response.size(), 1); assertEquals(Iterables.getOnlyElement(response).getName(), object.getProperties().getName()); - assertEquals(Iterables.getOnlyElement(response).getMetadata(), ImmutableMap.of("mykey", - "metadata-value")); + assertEquals(Iterables.getOnlyElement(response).getMetadata(), ImmutableMap.of("mykey", "metadata-value")); // Test PUT with invalid ETag (as if object's data was corrupted in transit) String correctEtag = newEtag; @@ -318,8 +307,7 @@ public class AzureBlobClientLiveTest { object.setPayload(bais); object.getPayload().setContentLength(new Long(data.getBytes().length)); newEtag = client.putBlob(privateContainer, object); - assertEquals(context.utils().encryption().hex(md5), context.utils().encryption().hex(getBlob.getProperties() - .getContentMD5())); + assertEquals(CryptoStreams.hex(md5), CryptoStreams.hex(getBlob.getProperties().getContentMD5())); // Test GET with options // Non-matching ETag @@ -333,8 +321,8 @@ public class AzureBlobClientLiveTest { // Matching ETag TODO this shouldn't fail!!! try { - getBlob = client.getBlob(privateContainer, object.getProperties().getName(), - GetOptions.Builder.ifETagMatches(newEtag)); + getBlob = client.getBlob(privateContainer, object.getProperties().getName(), GetOptions.Builder + .ifETagMatches(newEtag)); assertEquals(getBlob.getProperties().getETag(), newEtag); } catch (HttpResponseException e) { assertEquals(e.getResponse().getStatusCode(), 412); diff --git a/blobstore/src/main/clojure/org/jclouds/blobstore.clj b/blobstore/src/main/clojure/org/jclouds/blobstore.clj index a91394e368..74cfc3a0d1 100644 --- a/blobstore/src/main/clojure/org/jclouds/blobstore.clj +++ b/blobstore/src/main/clojure/org/jclouds/blobstore.clj @@ -43,7 +43,7 @@ See http://code.google.com/p/jclouds for details." AsyncBlobStore BlobStore BlobStoreContext BlobStoreContextFactory domain.BlobMetadata domain.StorageMetadata domain.Blob options.ListContainerOptions] - [org.jclouds.encryption.internal JCEEncryptionService] + [org.jclouds.io Payloads] [java.util Arrays] [java.security DigestOutputStream MessageDigest] [com.google.common.collect ImmutableSet])) @@ -135,12 +135,12 @@ Options can also be specified for extension modules (.list blobstore container-name list-options)) (apply list-container *blobstore* blobstore args))) -(defn- list-blobs-chunk [container prefix blobstore & [marker]] +(defn- list-blobs-chunk [container prefix #^BlobStore blobstore & [marker]] (apply list-container blobstore container :in-directory prefix (when (string? marker) [:after-marker marker]))) -(defn- list-blobs-chunks [container prefix blobstore marker] +(defn- list-blobs-chunks [container prefix #^BlobStore blobstore marker] (when marker (let [chunk (list-blobs-chunk container prefix blobstore marker)] (lazy-seq (cons chunk @@ -149,7 +149,7 @@ Options can also be specified for extension modules (defn list-blobs "Returns a lazy seq of all blobs in the given container." - ([container prefix blobstore] + ([container prefix #^BlobStore blobstore] (apply concat (list-blobs-chunks container prefix blobstore :start)))) (defn locations @@ -164,84 +164,84 @@ Options can also be specified for extension modules (create-container container-name nil *blobstore*)) ([container-name location] (create-container container-name location *blobstore*)) - ([container-name location blobstore] + ([container-name location #^BlobStore blobstore] (.createContainerInLocation blobstore location container-name))) (defn clear-container "Clear a container." ([container-name] (clear-container container-name *blobstore*)) - ([container-name blobstore] + ([container-name #^BlobStore blobstore] (.clearContainer blobstore container-name))) (defn delete-container "Delete a container." ([container-name] (delete-container container-name *blobstore*)) - ([container-name blobstore] + ([container-name #^BlobStore blobstore] (.deleteContainer blobstore container-name))) (defn container-exists? "Predicate to check presence of a container" ([container-name] (container-exists? container-name *blobstore*)) - ([container-name blobstore] + ([container-name #^BlobStore blobstore] (.containerExists blobstore container-name))) (defn directory-exists? "Predicate to check presence of a directory" ([container-name path] (directory-exists? container-name path *blobstore*)) - ([container-name path blobstore] + ([container-name path #^BlobStore blobstore] (.directoryExists blobstore container-name path))) (defn create-directory "Create a directory path." ([container-name path] (create-directory container-name path *blobstore*)) - ([container-name path blobstore] + ([container-name path #^BlobStore blobstore] (.createDirectory blobstore container-name path))) (defn delete-directory "Delete a directory path." ([container-name path] (delete-directory container-name path *blobstore*)) - ([container-name path blobstore] + ([container-name path #^BlobStore blobstore] (.deleteDirectory blobstore container-name path))) (defn blob-exists? "Predicate to check presence of a blob" ([container-name path] (blob-exists? container-name path *blobstore*)) - ([container-name path blobstore] + ([container-name path #^BlobStore blobstore] (.blobExists blobstore container-name path))) (defn put-blob "Put a blob. Metadata in the blob determines location." ([container-name blob] (put-blob container-name blob *blobstore*)) - ([container-name blob blobstore] + ([container-name blob #^BlobStore blobstore] (.putBlob blobstore container-name blob))) (defn blob-metadata "Get metadata from given path" ([container-name path] (blob-metadata container-name path *blobstore*)) - ([container-name path blobstore] + ([container-name path #^BlobStore blobstore] (.blobMetadata blobstore container-name path))) (defn get-blob "Get blob from given path" ([container-name path] (get-blob container-name path *blobstore*)) - ([container-name path blobstore] + ([container-name path #^BlobStore blobstore] (.getBlob blobstore container-name path))) (defn remove-blob "Remove blob from given path" ([container-name path] (remove-blob container-name path *blobstore*)) - ([container-name path blobstore] + ([container-name path #^BlobStore blobstore] (.removeBlob blobstore container-name path))) (defn count-blobs @@ -281,23 +281,18 @@ example: "add a content md5 to a blob, or make a new blob that has an md5. note that this implies rebuffering, if the blob's payload isn't repeatable" ([#^Blob blob] - (md5-blob *blobstore*)) - ([blob-or-name blobstore-or-payload] - (if (blobstore? blobstore-or-payload) - (-> (blobstore-context blobstore-or-payload) - .utils - .encryption - (.generateMD5BufferingIfNotRepeatable blob-or-name)) - (md5-blob blob-or-name blobstore-or-payload *blobstore*))) + (Payloads/calculateMD5 blob)) + ([#^String name payload] + (blob name payload *blobstore*)) ([#^String name payload #^BlobStore blobstore] - (md5-blob (blob name payload blobstore) blobstore))) + (md5-blob (blob name payload blobstore)))) (defn upload-blob "Create anrepresenting text data: container, name, string -> etag" ([container-name name data] (upload-blob container-name name data *blobstore*)) - ([container-name name data blobstore] + ([container-name name data #^BlobStore blobstore] (put-blob container-name (md5-blob name data blobstore) blobstore))) diff --git a/blobstore/src/main/java/org/jclouds/blobstore/TransientAsyncBlobStore.java b/blobstore/src/main/java/org/jclouds/blobstore/TransientAsyncBlobStore.java index 3fc30ba267..4a0e0498fd 100755 --- a/blobstore/src/main/java/org/jclouds/blobstore/TransientAsyncBlobStore.java +++ b/blobstore/src/main/java/org/jclouds/blobstore/TransientAsyncBlobStore.java @@ -77,19 +77,22 @@ import org.jclouds.blobstore.options.GetOptions; import org.jclouds.blobstore.options.ListContainerOptions; import org.jclouds.blobstore.strategy.IfDirectoryReturnNameStrategy; import org.jclouds.blobstore.util.BlobUtils; +import org.jclouds.crypto.Crypto; +import org.jclouds.crypto.CryptoStreams; import org.jclouds.date.DateService; import org.jclouds.domain.Location; -import org.jclouds.encryption.EncryptionService; import org.jclouds.http.HttpCommand; import org.jclouds.http.HttpRequest; import org.jclouds.http.HttpResponse; import org.jclouds.http.HttpResponseException; import org.jclouds.http.options.HttpRequestOptions; +import org.jclouds.io.Payloads; import org.jclouds.io.payloads.ByteArrayPayload; import org.jclouds.io.payloads.DelegatingPayload; import com.google.common.base.Function; import com.google.common.base.Predicate; +import com.google.common.base.Throwables; import com.google.common.collect.Iterables; import com.google.common.collect.Multimaps; import com.google.common.io.Closeables; @@ -106,7 +109,7 @@ import com.google.inject.internal.Nullable; public class TransientAsyncBlobStore extends BaseAsyncBlobStore { protected final DateService dateService; - protected final EncryptionService encryptionService; + protected final Crypto crypto; protected final ConcurrentMap> containerToBlobs; protected final ConcurrentMap containerToLocation; protected final HttpGetOptionsListToGetOptions httpGetOptionsConverter; @@ -114,8 +117,8 @@ public class TransientAsyncBlobStore extends BaseAsyncBlobStore { protected final Factory blobFactory; @Inject - protected TransientAsyncBlobStore(BlobStoreContext context, DateService dateService, - EncryptionService encryptionService, ConcurrentMap> containerToBlobs, + protected TransientAsyncBlobStore(BlobStoreContext context, DateService dateService, Crypto crypto, + ConcurrentMap> containerToBlobs, ConcurrentMap containerToLocation, HttpGetOptionsListToGetOptions httpGetOptionsConverter, IfDirectoryReturnNameStrategy ifDirectoryReturnName, Blob.Factory blobFactory, BlobUtils blobUtils, @@ -124,7 +127,7 @@ public class TransientAsyncBlobStore extends BaseAsyncBlobStore { super(context, blobUtils, service, defaultLocation, locations); this.blobFactory = blobFactory; this.dateService = dateService; - this.encryptionService = encryptionService; + this.crypto = crypto; this.containerToBlobs = containerToBlobs; this.containerToLocation = containerToLocation; this.httpGetOptionsConverter = httpGetOptionsConverter; @@ -464,20 +467,23 @@ public class TransientAsyncBlobStore extends BaseAsyncBlobStore { payload = (object.getPayload() instanceof DelegatingPayload) ? (DelegatingPayload.class.cast( object.getPayload()).getDelegate() instanceof ByteArrayPayload) ? ByteArrayPayload.class .cast(DelegatingPayload.class.cast(object.getPayload()).getDelegate()) : null : null; - if (payload == null || !(payload instanceof ByteArrayPayload)) { - InputStream input = object.getPayload().getInput(); - try { - String oldContentType = object.getPayload().getContentType(); - payload = encryptionService.generatePayloadWithMD5For(input); - payload.setContentType(oldContentType); - } finally { - Closeables.closeQuietly(input); + try { + if (payload == null || !(payload instanceof ByteArrayPayload)) { + InputStream input = object.getPayload().getInput(); + try { + String oldContentType = object.getPayload().getContentType(); + payload = (ByteArrayPayload) Payloads.calculateMD5(Payloads.newPayload(object.getPayload().getInput())); + payload.setContentType(oldContentType); + } finally { + Closeables.closeQuietly(input); + } + } else { + if (payload.getContentMD5() == null) + Payloads.calculateMD5(object, crypto.md5()); } - } else { - if (payload.getContentMD5() == null) - payload = (ByteArrayPayload) encryptionService.generateMD5BufferingIfNotRepeatable(payload); + } catch (IOException e) { + Throwables.propagate(e); } - Blob blob = blobFactory.create(copy(object.getMetadata())); blob.setPayload(payload); blob.getMetadata().setLastModified(new Date()); @@ -485,7 +491,7 @@ public class TransientAsyncBlobStore extends BaseAsyncBlobStore { blob.getMetadata().setContentMD5(payload.getContentMD5()); blob.getMetadata().setContentType(payload.getContentType()); - String eTag = encryptionService.hex(payload.getContentMD5()); + String eTag = CryptoStreams.hex(payload.getContentMD5()); blob.getMetadata().setETag(eTag); container.put(blob.getMetadata().getName(), blob); @@ -495,7 +501,7 @@ public class TransientAsyncBlobStore extends BaseAsyncBlobStore { blob.getAllHeaders().put(HttpHeaders.ETAG, eTag); blob.getAllHeaders().put(HttpHeaders.CONTENT_TYPE, payload.getContentType()); blob.getAllHeaders().put(HttpHeaders.CONTENT_LENGTH, payload.getContentLength() + ""); - blob.getAllHeaders().put("Content-MD5", encryptionService.base64(payload.getContentMD5())); + blob.getAllHeaders().put("Content-MD5", CryptoStreams.base64(payload.getContentMD5())); blob.getAllHeaders().putAll(Multimaps.forMap(blob.getMetadata().getUserMetadata())); return immediateFuture(eTag); 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 77ce77b62c..dda4960da4 100644 --- a/blobstore/src/main/java/org/jclouds/blobstore/config/BlobStoreMapModule.java +++ b/blobstore/src/main/java/org/jclouds/blobstore/config/BlobStoreMapModule.java @@ -31,7 +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 org.jclouds.crypto.Crypto; import com.google.inject.AbstractModule; import com.google.inject.Scopes; @@ -84,14 +84,14 @@ public class BlobStoreMapModule extends AbstractModule { @Inject PutBlobsStrategy putBlobsStrategy; @Inject - EncryptionService encryptionService; + Crypto crypto; @Inject ListContainerAndRecurseThroughFolders listStrategy; public InputStreamMap create(String containerName, ListContainerOptions options) { return new InputStreamMapImpl(connection, blobFactory, getAllBlobs, listStrategy, containsValueStrategy, putBlobsStrategy, containerName, options, - encryptionService); + crypto); } } diff --git a/blobstore/src/main/java/org/jclouds/blobstore/domain/Blob.java b/blobstore/src/main/java/org/jclouds/blobstore/domain/Blob.java index 3a00c6ddbf..e3179bea44 100644 --- a/blobstore/src/main/java/org/jclouds/blobstore/domain/Blob.java +++ b/blobstore/src/main/java/org/jclouds/blobstore/domain/Blob.java @@ -18,7 +18,7 @@ */ package org.jclouds.blobstore.domain; -import org.jclouds.http.PayloadEnclosing; +import org.jclouds.io.PayloadEnclosing; import com.google.common.collect.Multimap; import com.google.inject.internal.Nullable; 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 e11f53d522..b9b666f4a7 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,9 +25,9 @@ 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.http.PayloadEnclosing; import org.jclouds.http.internal.PayloadEnclosingImpl; import org.jclouds.io.Payload; +import org.jclouds.io.PayloadEnclosing; import org.jclouds.io.payloads.DelegatingPayload; import com.google.common.collect.LinkedHashMultimap; 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 c17e2869ec..e058790a22 100644 --- a/blobstore/src/main/java/org/jclouds/blobstore/functions/ObjectMD5.java +++ b/blobstore/src/main/java/org/jclouds/blobstore/functions/ObjectMD5.java @@ -18,23 +18,26 @@ */ package org.jclouds.blobstore.functions; +import java.io.IOException; + import javax.inject.Inject; import org.jclouds.blobstore.domain.Blob; -import org.jclouds.encryption.EncryptionService; +import org.jclouds.crypto.Crypto; import org.jclouds.io.Payloads; import com.google.common.base.Function; +import com.google.common.base.Throwables; public class ObjectMD5 implements Function { protected final Blob.Factory blobFactory; - protected final EncryptionService encryptionService; + protected final Crypto crypto; @Inject - ObjectMD5(EncryptionService encryptionService, Blob.Factory blobFactory) { + ObjectMD5(Crypto crypto, Blob.Factory blobFactory) { this.blobFactory = blobFactory; - this.encryptionService = encryptionService; + this.crypto = crypto; } public byte[] apply(Object from) { @@ -46,7 +49,11 @@ public class ObjectMD5 implements Function { object.setPayload(Payloads.newPayload(from)); } if (object.getMetadata().getContentMD5() == null) - encryptionService.generateMD5BufferingIfNotRepeatable(object); + try { + Payloads.calculateMD5(object, crypto.md5()); + } catch (IOException e) { + Throwables.propagate(e); + } return object.getPayload().getContentMD5(); } diff --git a/blobstore/src/main/java/org/jclouds/blobstore/internal/BaseAsyncBlobStore.java b/blobstore/src/main/java/org/jclouds/blobstore/internal/BaseAsyncBlobStore.java index 9ac37548c6..1c92e7f1e9 100644 --- a/blobstore/src/main/java/org/jclouds/blobstore/internal/BaseAsyncBlobStore.java +++ b/blobstore/src/main/java/org/jclouds/blobstore/internal/BaseAsyncBlobStore.java @@ -38,7 +38,6 @@ import org.jclouds.blobstore.domain.StorageMetadata; import org.jclouds.blobstore.options.ListContainerOptions; import org.jclouds.blobstore.util.BlobUtils; import org.jclouds.blobstore.util.internal.BlobUtilsImpl; -import static org.jclouds.concurrent.ConcurrentUtils.*; import org.jclouds.domain.Location; import org.jclouds.util.Utils; @@ -114,7 +113,7 @@ public abstract class BaseAsyncBlobStore implements AsyncBlobStore { */ @Override public ListenableFuture countBlobs(final String containerName, final ListContainerOptions options) { - return makeListenable(service.submit(new Callable() { + return org.jclouds.concurrent.Futures.makeListenable(service.submit(new Callable() { public Long call() throws Exception { return blobUtils.countBlobs(containerName, options); } @@ -142,7 +141,7 @@ public abstract class BaseAsyncBlobStore implements AsyncBlobStore { */ @Override public ListenableFuture clearContainer(final String containerName, final ListContainerOptions options) { - return makeListenable(service.submit(new Callable() { + return org.jclouds.concurrent.Futures.makeListenable(service.submit(new Callable() { public Void call() throws Exception { blobUtils.clearContainer(containerName, options); @@ -160,7 +159,7 @@ public abstract class BaseAsyncBlobStore implements AsyncBlobStore { */ @Override public ListenableFuture deleteDirectory(final String containerName, final String directory) { - return makeListenable(service.submit(new Callable() { + return org.jclouds.concurrent.Futures.makeListenable(service.submit(new Callable() { public Void call() throws Exception { blobUtils.deleteDirectory(containerName, directory); @@ -179,7 +178,7 @@ public abstract class BaseAsyncBlobStore implements AsyncBlobStore { * virtual path */ public ListenableFuture directoryExists(final String containerName, final String directory) { - return makeListenable(service.submit(new Callable() { + return org.jclouds.concurrent.Futures.makeListenable(service.submit(new Callable() { public Boolean call() throws Exception { return blobUtils.directoryExists(containerName, directory); @@ -200,7 +199,7 @@ public abstract class BaseAsyncBlobStore implements AsyncBlobStore { public ListenableFuture createDirectory(final String containerName, final String directory) { return blobUtils.directoryExists(containerName, directory) ? Futures.immediateFuture((Void) null) - : makeListenable(service.submit(new Callable() { + : org.jclouds.concurrent.Futures.makeListenable(service.submit(new Callable() { public Void call() throws Exception { blobUtils.createDirectory(containerName, directory); return null; @@ -230,7 +229,7 @@ public abstract class BaseAsyncBlobStore implements AsyncBlobStore { */ @Override public ListenableFuture deleteContainer(final String container) { - return makeListenable(service.submit(new Callable() { + return org.jclouds.concurrent.Futures.makeListenable(service.submit(new Callable() { public Void call() throws Exception { deleteAndEnsurePathGone(container); 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 d6e117606b..417ca5d7d7 100755 --- a/blobstore/src/main/java/org/jclouds/blobstore/internal/InputStreamMapImpl.java +++ b/blobstore/src/main/java/org/jclouds/blobstore/internal/InputStreamMapImpl.java @@ -23,6 +23,7 @@ import static com.google.common.collect.Lists.newArrayList; import static org.jclouds.io.Payloads.newPayload; import java.io.File; +import java.io.IOException; import java.io.InputStream; import java.util.Collection; import java.util.Map; @@ -38,8 +39,9 @@ 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.crypto.Crypto; import org.jclouds.io.Payload; +import org.jclouds.io.Payloads; import org.jclouds.io.payloads.ByteArrayPayload; import org.jclouds.io.payloads.FilePayload; import org.jclouds.io.payloads.InputStreamPayload; @@ -47,6 +49,7 @@ import org.jclouds.io.payloads.StringPayload; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Function; +import com.google.common.base.Throwables; /** * Map representation of a live connection to a BlobStore. All put operations will result in ETag @@ -59,16 +62,16 @@ import com.google.common.base.Function; * @see BaseBlobMap */ public class InputStreamMapImpl extends BaseBlobMap implements InputStreamMap { - protected final EncryptionService encryptionService; + protected final Crypto crypto; @Inject public InputStreamMapImpl(BlobStore connection, Blob.Factory blobFactory, GetBlobsInListStrategy getAllBlobs, ListContainerAndRecurseThroughFolders listStrategy, ContainsValueInListStrategy containsValueStrategy, PutBlobsStrategy putBlobsStrategy, - String containerName, ListContainerOptions options, EncryptionService encryptionService) { + String containerName, ListContainerOptions options, Crypto crypto) { super(connection, getAllBlobs, containsValueStrategy, putBlobsStrategy, listStrategy, containerName, options); - this.encryptionService = encryptionService; + this.crypto = crypto; } @Override @@ -144,7 +147,11 @@ public class InputStreamMapImpl extends BaseBlobMap implements Inpu Blob newBlobWithMD5(String name, Object value) { Blob blob = blobstore.newBlob(prefixer.apply(name)); blob.setPayload(newPayload(value)); - encryptionService.generateMD5BufferingIfNotRepeatable(blob); + try { + Payloads.calculateMD5(blob, crypto.md5()); + } catch (IOException e) { + Throwables.propagate(e); + } return blob; } diff --git a/blobstore/src/main/java/org/jclouds/blobstore/strategy/internal/DeleteAllKeysInList.java b/blobstore/src/main/java/org/jclouds/blobstore/strategy/internal/DeleteAllKeysInList.java index 402c208247..25f2903a6c 100644 --- a/blobstore/src/main/java/org/jclouds/blobstore/strategy/internal/DeleteAllKeysInList.java +++ b/blobstore/src/main/java/org/jclouds/blobstore/strategy/internal/DeleteAllKeysInList.java @@ -19,7 +19,7 @@ package org.jclouds.blobstore.strategy.internal; import static org.jclouds.blobstore.options.ListContainerOptions.Builder.recursive; -import static org.jclouds.concurrent.ConcurrentUtils.awaitCompletion; +import static org.jclouds.concurrent.FutureIterables.awaitCompletion; import java.util.Map; import java.util.concurrent.ExecutorService; diff --git a/blobstore/src/main/java/org/jclouds/blobstore/strategy/internal/FetchBlobMetadata.java b/blobstore/src/main/java/org/jclouds/blobstore/strategy/internal/FetchBlobMetadata.java index 68782f6407..a8d87e3b58 100644 --- a/blobstore/src/main/java/org/jclouds/blobstore/strategy/internal/FetchBlobMetadata.java +++ b/blobstore/src/main/java/org/jclouds/blobstore/strategy/internal/FetchBlobMetadata.java @@ -19,7 +19,7 @@ package org.jclouds.blobstore.strategy.internal; import static com.google.common.base.Preconditions.checkState; -import static org.jclouds.concurrent.ConcurrentUtils.transformParallel; +import static org.jclouds.concurrent.FutureIterables.transformParallel; import java.util.concurrent.ExecutorService; import java.util.concurrent.Future; diff --git a/blobstore/src/main/java/org/jclouds/blobstore/strategy/internal/GetAllBlobsInListAndRetryOnFailure.java b/blobstore/src/main/java/org/jclouds/blobstore/strategy/internal/GetAllBlobsInListAndRetryOnFailure.java index 2b2eca49a8..2bfa72d5dc 100644 --- a/blobstore/src/main/java/org/jclouds/blobstore/strategy/internal/GetAllBlobsInListAndRetryOnFailure.java +++ b/blobstore/src/main/java/org/jclouds/blobstore/strategy/internal/GetAllBlobsInListAndRetryOnFailure.java @@ -18,7 +18,7 @@ */ package org.jclouds.blobstore.strategy.internal; -import static org.jclouds.concurrent.ConcurrentUtils.transformParallel; +import static org.jclouds.concurrent.FutureIterables.transformParallel; import java.util.concurrent.ExecutorService; import java.util.concurrent.Future; diff --git a/blobstore/src/main/java/org/jclouds/blobstore/strategy/internal/MarkersDeleteDirectoryStrategy.java b/blobstore/src/main/java/org/jclouds/blobstore/strategy/internal/MarkersDeleteDirectoryStrategy.java index 5687b4be43..ea80f1aacd 100644 --- a/blobstore/src/main/java/org/jclouds/blobstore/strategy/internal/MarkersDeleteDirectoryStrategy.java +++ b/blobstore/src/main/java/org/jclouds/blobstore/strategy/internal/MarkersDeleteDirectoryStrategy.java @@ -18,7 +18,7 @@ */ package org.jclouds.blobstore.strategy.internal; -import static org.jclouds.concurrent.ConcurrentUtils.awaitCompletion; +import static org.jclouds.concurrent.FutureIterables.awaitCompletion; import java.util.Map; import java.util.Set; diff --git a/blobstore/src/main/java/org/jclouds/blobstore/strategy/internal/PutBlobsStrategyImpl.java b/blobstore/src/main/java/org/jclouds/blobstore/strategy/internal/PutBlobsStrategyImpl.java index b908825eb0..db062655bd 100644 --- a/blobstore/src/main/java/org/jclouds/blobstore/strategy/internal/PutBlobsStrategyImpl.java +++ b/blobstore/src/main/java/org/jclouds/blobstore/strategy/internal/PutBlobsStrategyImpl.java @@ -18,7 +18,7 @@ */ package org.jclouds.blobstore.strategy.internal; -import static org.jclouds.concurrent.ConcurrentUtils.awaitCompletion; +import static org.jclouds.concurrent.FutureIterables.awaitCompletion; import java.util.Map; import java.util.concurrent.ExecutorService; 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 76b2279fe8..5ba835329e 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 @@ -24,8 +24,7 @@ import static org.jclouds.blobstore.options.GetOptions.Builder.ifModifiedSince; import static org.jclouds.blobstore.options.GetOptions.Builder.ifUnmodifiedSince; import static org.jclouds.blobstore.options.GetOptions.Builder.range; import static org.jclouds.blobstore.util.BlobStoreUtils.getContentAsStringOrNullAndClose; -import static org.jclouds.concurrent.ConcurrentUtils.awaitCompletion; -import static org.jclouds.concurrent.ConcurrentUtils.compose; +import static org.jclouds.concurrent.FutureIterables.awaitCompletion; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertNotNull; import static org.testng.Assert.assertNull; @@ -51,11 +50,13 @@ 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.concurrent.Futures; +import org.jclouds.crypto.Crypto; +import org.jclouds.crypto.CryptoStreams; +import org.jclouds.encryption.internal.JCECrypto; import org.jclouds.http.BaseJettyTest; import org.jclouds.http.HttpResponseException; -import org.jclouds.io.Payload; +import org.jclouds.io.InputSuppliers; import org.jclouds.io.Payloads; import org.jclouds.logging.Logger; import org.jclouds.util.Utils; @@ -76,16 +77,15 @@ import com.google.common.io.InputSupplier; * @author Adrian Cole */ public class BaseBlobIntegrationTest extends BaseBlobStoreIntegrationTest { - private byte[] oneHundredOneConstitutions; + private InputSupplier oneHundredOneConstitutions; private byte[] oneHundredOneConstitutionsMD5; @BeforeClass(groups = { "integration", "live" }) @Override public void setUpResourcesOnThisThread(ITestContext testContext) throws Exception { super.setUpResourcesOnThisThread(testContext); - Payload result = context.utils().encryption().generatePayloadWithMD5For(getTestDataSupplier().getInput()); - oneHundredOneConstitutions = (byte[]) result.getRawContent(); - oneHundredOneConstitutionsMD5 = result.getContentMD5(); + oneHundredOneConstitutions = getTestDataSupplier(); + oneHundredOneConstitutionsMD5 = CryptoStreams.md5(oneHundredOneConstitutions); } @SuppressWarnings("unchecked") @@ -112,13 +112,16 @@ public class BaseBlobIntegrationTest extends BaseBlobStoreIntegrationTest { Map> responses = Maps.newHashMap(); for (int i = 0; i < 10; i++) { - responses.put(i, compose(context.getAsyncBlobStore().getBlob(containerName, key), + responses.put(i, Futures.compose(context.getAsyncBlobStore().getBlob(containerName, key), new Function() { @Override public Void apply(Blob from) { - assertEquals(context.utils().encryption().md5(from.getPayload().getInput()), - oneHundredOneConstitutionsMD5); + try { + assertEquals(CryptoStreams.md5(from.getPayload()), oneHundredOneConstitutionsMD5); + } catch (IOException e) { + Throwables.propagate(e); + } return null; } @@ -138,7 +141,7 @@ public class BaseBlobIntegrationTest extends BaseBlobStoreIntegrationTest { Blob sourceObject = context.getBlobStore().newBlob(key); sourceObject.getMetadata().setContentType("text/plain"); sourceObject.getMetadata().setContentMD5(oneHundredOneConstitutionsMD5); - sourceObject.setPayload(oneHundredOneConstitutions); + sourceObject.setPayload(oneHundredOneConstitutions.getInput()); context.getBlobStore().putBlob(containerName, sourceObject); } @@ -409,7 +412,7 @@ public class BaseBlobIntegrationTest extends BaseBlobStoreIntegrationTest { blob.getMetadata().setContentType(type); blob.setPayload(Payloads.newPayload(content)); if (content instanceof InputStream) { - context.utils().encryption().generateMD5BufferingIfNotRepeatable(blob); + Payloads.calculateMD5(blob, context.utils().crypto().md5()); } String containerName = getContainerName(); try { @@ -424,10 +427,10 @@ public class BaseBlobIntegrationTest extends BaseBlobStoreIntegrationTest { } } - protected volatile static EncryptionService encryptionService; + protected volatile static Crypto crypto; static { try { - encryptionService = new JCEEncryptionService(); + crypto = new JCECrypto(); } catch (NoSuchAlgorithmException e) { Throwables.propagate(e); } catch (CertificateException e) { @@ -436,7 +439,7 @@ public class BaseBlobIntegrationTest extends BaseBlobStoreIntegrationTest { } @Test(groups = { "integration", "live" }) - public void testMetadata() throws InterruptedException { + public void testMetadata() throws InterruptedException, IOException { String key = "hello"; Blob blob = context.getBlobStore().newBlob(key); @@ -447,7 +450,7 @@ public class BaseBlobIntegrationTest extends BaseBlobStoreIntegrationTest { // normalize the // providers. blob.getMetadata().getUserMetadata().put("Adrian", "powderpuff"); - blob.getMetadata().setContentMD5(encryptionService.md5(Utils.toInputStream(TEST_STRING))); + Payloads.calculateMD5(blob, context.utils().crypto().md5()); String containerName = getContainerName(); try { assertNull(context.getBlobStore().blobMetadata(containerName, "powderpuff")); @@ -473,11 +476,11 @@ public class BaseBlobIntegrationTest extends BaseBlobStoreIntegrationTest { } } - protected void validateMetadata(BlobMetadata metadata) { + protected void validateMetadata(BlobMetadata metadata) throws IOException { assert metadata.getContentType().startsWith("text/plain") : metadata.getContentType(); assertEquals(metadata.getSize(), new Long(TEST_STRING.length())); assertEquals(metadata.getUserMetadata().get("adrian"), "powderpuff"); - assertEquals(metadata.getContentMD5(), encryptionService.md5(Utils.toInputStream(TEST_STRING))); + assertEquals(metadata.getContentMD5(), CryptoStreams.md5(InputSuppliers.of(TEST_STRING))); } } \ No newline at end of file diff --git a/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseBlobLiveTest.java b/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseBlobLiveTest.java index 4cbf4ad42a..484617ecbe 100755 --- a/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseBlobLiveTest.java +++ b/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseBlobLiveTest.java @@ -26,7 +26,7 @@ import java.net.URL; import java.net.URLConnection; import org.jclouds.blobstore.domain.Blob; -import org.jclouds.encryption.internal.JCEEncryptionService; +import org.jclouds.crypto.CryptoStreams; import org.testng.annotations.Optional; import org.testng.annotations.Parameters; import org.testng.annotations.Test; @@ -41,25 +41,20 @@ import org.testng.annotations.Test; @Test(groups = { "live" }, testName = "blobstore.BlobLiveTest") public class BaseBlobLiveTest extends BaseBlobStoreIntegrationTest { - private static final String sysHttpStreamUrl = System - .getProperty("jclouds.blobstore.httpstream.url"); - private static final String sysHttpStreamETag = System - .getProperty("jclouds.blobstore.httpstream.md5"); + private static final String sysHttpStreamUrl = System.getProperty("jclouds.blobstore.httpstream.url"); + private static final String sysHttpStreamETag = System.getProperty("jclouds.blobstore.httpstream.md5"); @Test @Parameters( { "jclouds.blobstore.httpstream.url", "jclouds.blobstore.httpstream.md5" }) - public void testCopyUrl(@Optional String httpStreamUrl, @Optional String httpStreamETag) - throws Exception { - httpStreamUrl = checkNotNull(httpStreamUrl != null ? httpStreamUrl : sysHttpStreamUrl, - "httpStreamUrl"); + public void testCopyUrl(@Optional String httpStreamUrl, @Optional String httpStreamETag) throws Exception { + httpStreamUrl = checkNotNull(httpStreamUrl != null ? httpStreamUrl : sysHttpStreamUrl, "httpStreamUrl"); - httpStreamETag = checkNotNull(httpStreamETag != null ? httpStreamETag : sysHttpStreamETag, - "httpStreamMd5"); + httpStreamETag = checkNotNull(httpStreamETag != null ? httpStreamETag : sysHttpStreamETag, "httpStreamMd5"); String key = "hello"; URL url = new URL(httpStreamUrl); - byte[] md5 = new JCEEncryptionService().fromHex(httpStreamETag); + byte[] md5 = CryptoStreams.hex(httpStreamETag); URLConnection connection = url.openConnection(); long length = connection.getContentLength(); 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 4d14b3d54d..2b11d5332e 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 @@ -36,6 +36,7 @@ import org.jclouds.blobstore.BlobMap; import org.jclouds.blobstore.BlobStoreContext; import org.jclouds.blobstore.domain.Blob; import org.jclouds.blobstore.options.ListContainerOptions; +import org.jclouds.io.Payloads; import org.jclouds.util.Utils; import org.testng.annotations.Test; @@ -74,7 +75,7 @@ public abstract class BaseBlobMapIntegrationTest extends BaseMapIntegrationTest< } @Test(groups = { "integration", "live" }) - public void testRemove() throws InterruptedException, ExecutionException, TimeoutException { + public void testRemove() throws InterruptedException, ExecutionException, TimeoutException, IOException { String bucketName = getContainerName(); try { Map map = createMap(context, bucketName); @@ -118,7 +119,7 @@ public abstract class BaseBlobMapIntegrationTest extends BaseMapIntegrationTest< .getValue())); Blob blob = entry.getValue(); blob.setPayload(""); - context.utils().encryption().generateMD5BufferingIfNotRepeatable(blob); + Payloads.calculateMD5(blob); entry.setValue(blob); } assertConsistencyAware(new Runnable() { @@ -139,14 +140,14 @@ public abstract class BaseBlobMapIntegrationTest extends BaseMapIntegrationTest< } @Test(groups = { "integration", "live" }) - public void testContains() throws InterruptedException, ExecutionException, TimeoutException { + public void testContains() throws InterruptedException, ExecutionException, TimeoutException, IOException { String bucketName = getContainerName(); try { Map map = createMap(context, bucketName); putStringWithMD5(map, "one", "apple"); Blob blob = context.getBlobStore().newBlob("one"); blob.setPayload("apple"); - context.utils().encryption().generateMD5BufferingIfNotRepeatable(blob); + Payloads.calculateMD5(blob); assertConsistencyAwareContainsValue(map, blob); } finally { returnContainer(bucketName); @@ -174,11 +175,11 @@ public abstract class BaseBlobMapIntegrationTest extends BaseMapIntegrationTest< Map map = createMap(context, bucketName); Blob blob = context.getBlobStore().newBlob("one"); blob.setPayload(Utils.toInputStream("apple")); - context.utils().encryption().generateMD5BufferingIfNotRepeatable(blob); + Payloads.calculateMD5(blob); Blob old = map.put(blob.getMetadata().getName(), blob); getOneReturnsAppleAndOldValueIsNull(map, old); blob.setPayload(Utils.toInputStream("bear")); - context.utils().encryption().generateMD5BufferingIfNotRepeatable(blob); + Payloads.calculateMD5(blob); Blob apple = map.put(blob.getMetadata().getName(), blob); getOneReturnsBearAndOldValueIsApple(map, apple); } finally { @@ -239,10 +240,10 @@ public abstract class BaseBlobMapIntegrationTest extends BaseMapIntegrationTest< } @Override - protected void putStringWithMD5(Map map, String key, String text) { + protected void putStringWithMD5(Map map, String key, String text) throws IOException { Blob blob = context.getBlobStore().newBlob(key); blob.setPayload(text); - context.utils().encryption().generateMD5BufferingIfNotRepeatable(blob); + Payloads.calculateMD5(blob); map.put(key, blob); } diff --git a/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseContainerIntegrationTest.java b/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseContainerIntegrationTest.java index cc13116cff..17c255a109 100755 --- a/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseContainerIntegrationTest.java +++ b/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseContainerIntegrationTest.java @@ -23,9 +23,9 @@ import static com.google.common.collect.Iterables.get; import static org.jclouds.blobstore.options.ListContainerOptions.Builder.afterMarker; import static org.jclouds.blobstore.options.ListContainerOptions.Builder.inDirectory; import static org.jclouds.blobstore.options.ListContainerOptions.Builder.maxResults; -import static org.jclouds.util.Utils.toInputStream; import static org.testng.Assert.assertEquals; +import java.io.IOException; import java.io.UnsupportedEncodingException; import java.util.Set; import java.util.concurrent.ExecutionException; @@ -37,6 +37,9 @@ import org.jclouds.blobstore.domain.Blob; import org.jclouds.blobstore.domain.BlobMetadata; import org.jclouds.blobstore.domain.PageSet; import org.jclouds.blobstore.domain.StorageMetadata; +import org.jclouds.crypto.CryptoStreams; +import org.jclouds.io.InputSuppliers; +import org.jclouds.io.Payloads; import org.testng.annotations.Test; /** @@ -68,7 +71,7 @@ public class BaseContainerIntegrationTest extends BaseBlobStoreIntegrationTest { } @Test(groups = { "integration", "live" }) - public void testWithDetails() throws InterruptedException { + public void testWithDetails() throws InterruptedException, IOException { String key = "hello"; Blob object = context.getBlobStore().newBlob(key); @@ -79,7 +82,7 @@ public class BaseContainerIntegrationTest extends BaseBlobStoreIntegrationTest { // normalize the // providers. object.getMetadata().getUserMetadata().put("Adrian", "powderpuff"); - object.getMetadata().setContentMD5(context.utils().encryption().md5(toInputStream(TEST_STRING))); + Payloads.calculateMD5(object, context.utils().crypto().md5()); String containerName = getContainerName(); try { addBlobToContainer(containerName, object); @@ -93,7 +96,7 @@ public class BaseContainerIntegrationTest extends BaseBlobStoreIntegrationTest { assert metadata.getContentType().startsWith("text/plain") : metadata.getContentType(); assertEquals(metadata.getSize(), new Long(TEST_STRING.length())); assertEquals(metadata.getUserMetadata().get("adrian"), "powderpuff"); - assertEquals(metadata.getContentMD5(), context.utils().encryption().md5(toInputStream(TEST_STRING))); + assertEquals(metadata.getContentMD5(), CryptoStreams.md5(InputSuppliers.of(TEST_STRING))); } finally { returnContainer(containerName); } diff --git a/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseMapIntegrationTest.java b/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseMapIntegrationTest.java index 8e8cdd7fa8..a0fa3de6b8 100755 --- a/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseMapIntegrationTest.java +++ b/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseMapIntegrationTest.java @@ -104,7 +104,7 @@ public abstract class BaseMapIntegrationTest extends BaseBlobStoreIntegration ListContainerOptions options); @Test(groups = { "integration", "live" }) - public void testClear() throws InterruptedException, ExecutionException, TimeoutException { + public void testClear() throws InterruptedException, ExecutionException, TimeoutException, IOException { String containerNameName = getContainerName(); try { Map map = createMap(context, containerNameName); @@ -122,7 +122,7 @@ public abstract class BaseMapIntegrationTest extends BaseBlobStoreIntegration public abstract void testRemove() throws IOException, InterruptedException, ExecutionException, TimeoutException; @Test(groups = { "integration", "live" }) - public void testKeySet() throws InterruptedException, ExecutionException, TimeoutException { + public void testKeySet() throws InterruptedException, ExecutionException, TimeoutException, IOException { String containerNameName = getContainerName(); try { Map map = createMap(context, containerNameName); @@ -239,7 +239,7 @@ public abstract class BaseMapIntegrationTest extends BaseBlobStoreIntegration } @Test(groups = { "integration", "live" }) - public void testContainsKey() throws InterruptedException, ExecutionException, TimeoutException { + public void testContainsKey() throws InterruptedException, ExecutionException, TimeoutException, IOException { String containerNameName = getContainerName(); try { Map map = createMap(context, containerNameName); @@ -281,7 +281,7 @@ public abstract class BaseMapIntegrationTest extends BaseBlobStoreIntegration } @Test(groups = { "integration", "live" }) - public void testIsEmpty() throws InterruptedException, ExecutionException, TimeoutException { + public void testIsEmpty() throws InterruptedException, ExecutionException, TimeoutException, IOException { String containerNameName = getContainerName(); try { Map map = createMap(context, containerNameName); @@ -310,7 +310,7 @@ public abstract class BaseMapIntegrationTest extends BaseBlobStoreIntegration } abstract protected void putStringWithMD5(Map map, String key, String value) throws InterruptedException, - ExecutionException, TimeoutException; + ExecutionException, TimeoutException, IOException; protected void fourLeftRemovingOne(Map map) throws InterruptedException { map.remove("one"); diff --git a/chef/core/src/main/java/org/jclouds/chef/binders/BindChecksumsToJsonPayload.java b/chef/core/src/main/java/org/jclouds/chef/binders/BindChecksumsToJsonPayload.java index 63c89119f6..6ff64b1a27 100644 --- a/chef/core/src/main/java/org/jclouds/chef/binders/BindChecksumsToJsonPayload.java +++ b/chef/core/src/main/java/org/jclouds/chef/binders/BindChecksumsToJsonPayload.java @@ -29,11 +29,10 @@ import static com.google.common.base.Preconditions.checkNotNull; import java.util.List; import java.util.Set; -import javax.inject.Inject; import javax.inject.Singleton; import javax.ws.rs.core.MediaType; -import org.jclouds.encryption.EncryptionService; +import org.jclouds.crypto.CryptoStreams; import org.jclouds.http.HttpRequest; import org.jclouds.rest.binders.BindToStringPayload; @@ -46,17 +45,10 @@ import com.google.common.primitives.Bytes; */ @Singleton public class BindChecksumsToJsonPayload extends BindToStringPayload { - private final EncryptionService encryptionService; - - @Inject - BindChecksumsToJsonPayload(EncryptionService encryptionService) { - this.encryptionService = encryptionService; - } @SuppressWarnings("unchecked") public void bindToRequest(HttpRequest request, Object input) { - checkArgument(checkNotNull(input, "input") instanceof Set, - "this binder is only valid for Set!"); + checkArgument(checkNotNull(input, "input") instanceof Set, "this binder is only valid for Set!"); Set> md5s = (Set>) input; @@ -64,7 +56,7 @@ public class BindChecksumsToJsonPayload extends BindToStringPayload { builder.append("{\"checksums\":{"); for (List md5 : md5s) - builder.append(String.format("\"%s\":null,", encryptionService.hex(Bytes.toArray(md5)))); + builder.append(String.format("\"%s\":null,", CryptoStreams.hex(Bytes.toArray(md5)))); builder.deleteCharAt(builder.length() - 1); builder.append("}}"); super.bindToRequest(request, builder.toString()); diff --git a/chef/core/src/main/java/org/jclouds/chef/config/BaseChefRestClientModule.java b/chef/core/src/main/java/org/jclouds/chef/config/BaseChefRestClientModule.java index f85aec8f00..49d932c8d3 100644 --- a/chef/core/src/main/java/org/jclouds/chef/config/BaseChefRestClientModule.java +++ b/chef/core/src/main/java/org/jclouds/chef/config/BaseChefRestClientModule.java @@ -21,8 +21,9 @@ package org.jclouds.chef.config; import static org.jclouds.Constants.PROPERTY_CREDENTIAL; import static org.jclouds.Constants.PROPERTY_SESSION_INTERVAL; -import java.io.UnsupportedEncodingException; +import java.io.IOException; import java.security.PrivateKey; +import java.security.spec.InvalidKeySpecException; import java.util.Map; import java.util.concurrent.TimeUnit; @@ -31,15 +32,17 @@ import javax.inject.Singleton; import org.jclouds.chef.handlers.ChefClientErrorRetryHandler; import org.jclouds.chef.handlers.ChefErrorHandler; +import org.jclouds.crypto.Crypto; +import org.jclouds.crypto.Pems; import org.jclouds.date.DateService; import org.jclouds.date.TimeStamp; -import org.jclouds.encryption.EncryptionService; import org.jclouds.http.HttpErrorHandler; import org.jclouds.http.HttpRetryHandler; import org.jclouds.http.RequiresHttp; import org.jclouds.http.annotation.ClientError; import org.jclouds.http.annotation.Redirection; import org.jclouds.http.annotation.ServerError; +import org.jclouds.io.InputSuppliers; import org.jclouds.rest.ConfiguresRestClient; import org.jclouds.rest.config.RestClientModule; @@ -61,7 +64,7 @@ public class BaseChefRestClientModule extends RestClientModule { } protected BaseChefRestClientModule(Class syncClientType, Class asyncClientType, - Map, Class> delegates) { + Map, Class> delegates) { super(syncClientType, asyncClientType, delegates); } @@ -86,9 +89,9 @@ public class BaseChefRestClientModule extends RestClientModule { @Provides @Singleton - public PrivateKey provideKey(EncryptionService encryptionService, @Named(PROPERTY_CREDENTIAL) String pem) - throws UnsupportedEncodingException { - return encryptionService.privateKeyFromPEM(pem.getBytes("UTF-8")); + public PrivateKey provideKey(Crypto crypto, @Named(PROPERTY_CREDENTIAL) String pem) throws InvalidKeySpecException, + IOException { + return crypto.rsaKeyFactory().generatePrivate(Pems.privateKeySpec(InputSuppliers.of(pem))); } @Override diff --git a/chef/core/src/main/java/org/jclouds/chef/config/ChefParserModule.java b/chef/core/src/main/java/org/jclouds/chef/config/ChefParserModule.java index 2eca448385..8802954add 100644 --- a/chef/core/src/main/java/org/jclouds/chef/config/ChefParserModule.java +++ b/chef/core/src/main/java/org/jclouds/chef/config/ChefParserModule.java @@ -18,11 +18,14 @@ */ package org.jclouds.chef.config; +import java.io.IOException; import java.io.UnsupportedEncodingException; import java.lang.reflect.Type; import java.security.PrivateKey; import java.security.PublicKey; +import java.security.cert.CertificateException; import java.security.cert.X509Certificate; +import java.security.spec.InvalidKeySpecException; import java.util.Map; import javax.inject.Inject; @@ -31,7 +34,9 @@ import javax.inject.Singleton; import org.jclouds.Constants; import org.jclouds.chef.domain.DataBagItem; -import org.jclouds.encryption.EncryptionService; +import org.jclouds.crypto.Crypto; +import org.jclouds.crypto.Pems; +import org.jclouds.io.InputSuppliers; import org.jclouds.json.config.GsonModule.DateAdapter; import org.jclouds.json.config.GsonModule.Iso8601DateAdapter; @@ -61,11 +66,11 @@ public class ChefParserModule extends AbstractModule { @Singleton public static class PrivateKeyAdapterImpl implements PrivateKeyAdapter { - private final EncryptionService encryptionService; + private final Crypto crypto; @Inject - PrivateKeyAdapterImpl(EncryptionService encryptionService) { - this.encryptionService = encryptionService; + PrivateKeyAdapterImpl(Crypto crypto) { + this.crypto = crypto; } @Override @@ -73,10 +78,16 @@ public class ChefParserModule extends AbstractModule { throws JsonParseException { String keyText = json.getAsString().replaceAll("\\n", "\n"); try { - return encryptionService.privateKeyFromPEM(keyText.getBytes("UTF-8")); + return crypto.rsaKeyFactory().generatePrivate(Pems.privateKeySpec(InputSuppliers.of(keyText))); } catch (UnsupportedEncodingException e) { Throwables.propagate(e); return null; + } catch (InvalidKeySpecException e) { + Throwables.propagate(e); + return null; + } catch (IOException e) { + Throwables.propagate(e); + return null; } } } @@ -88,11 +99,11 @@ public class ChefParserModule extends AbstractModule { @Singleton public static class PublicKeyAdapterImpl implements PublicKeyAdapter { - private final EncryptionService encryptionService; + private final Crypto crypto; @Inject - PublicKeyAdapterImpl(EncryptionService encryptionService) { - this.encryptionService = encryptionService; + PublicKeyAdapterImpl(Crypto crypto) { + this.crypto = crypto; } @Override @@ -100,10 +111,16 @@ public class ChefParserModule extends AbstractModule { throws JsonParseException { String keyText = json.getAsString().replaceAll("\\n", "\n"); try { - return encryptionService.publicKeyFromPEM(keyText.getBytes("UTF-8")); + return crypto.rsaKeyFactory().generatePublic(Pems.publicKeySpec(InputSuppliers.of(keyText))); } catch (UnsupportedEncodingException e) { Throwables.propagate(e); return null; + } catch (InvalidKeySpecException e) { + Throwables.propagate(e); + return null; + } catch (IOException e) { + Throwables.propagate(e); + return null; } } } @@ -115,11 +132,11 @@ public class ChefParserModule extends AbstractModule { @Singleton public static class X509CertificateAdapterImpl implements X509CertificateAdapter { - private final EncryptionService encryptionService; + private final Crypto crypto; @Inject - X509CertificateAdapterImpl(EncryptionService encryptionService) { - this.encryptionService = encryptionService; + X509CertificateAdapterImpl(Crypto crypto) { + this.crypto = crypto; } @Override @@ -127,10 +144,16 @@ public class ChefParserModule extends AbstractModule { throws JsonParseException { String keyText = json.getAsString().replaceAll("\\n", "\n"); try { - return encryptionService.x509CertificateFromPEM(keyText.getBytes("UTF-8")); + return Pems.x509Certificate(InputSuppliers.of(keyText), crypto.certFactory()); } catch (UnsupportedEncodingException e) { Throwables.propagate(e); return null; + } catch (IOException e) { + Throwables.propagate(e); + return null; + } catch (CertificateException e) { + Throwables.propagate(e); + return null; } } } diff --git a/chef/core/src/main/java/org/jclouds/chef/filters/SignedHeaderAuth.java b/chef/core/src/main/java/org/jclouds/chef/filters/SignedHeaderAuth.java index b8d7133522..af3db8945b 100644 --- a/chef/core/src/main/java/org/jclouds/chef/filters/SignedHeaderAuth.java +++ b/chef/core/src/main/java/org/jclouds/chef/filters/SignedHeaderAuth.java @@ -37,17 +37,20 @@ import javax.inject.Provider; import javax.inject.Singleton; import org.jclouds.Constants; +import org.jclouds.crypto.Crypto; +import org.jclouds.crypto.CryptoStreams; import org.jclouds.date.TimeStamp; -import org.jclouds.encryption.EncryptionService; import org.jclouds.http.HttpException; import org.jclouds.http.HttpRequest; import org.jclouds.http.HttpRequestFilter; import org.jclouds.http.HttpUtils; import org.jclouds.http.internal.SignatureWire; +import org.jclouds.io.InputSuppliers; import org.jclouds.io.Payload; import org.jclouds.io.Payloads; import org.jclouds.io.payloads.MultipartForm; import org.jclouds.io.payloads.Part; +import org.jclouds.io.payloads.RSAEncryptingPayload; import org.jclouds.logging.Logger; import org.jclouds.util.Utils; @@ -56,6 +59,7 @@ import com.google.common.base.Predicate; import com.google.common.base.Splitter; import com.google.common.base.Throwables; import com.google.common.collect.Iterables; +import com.google.common.io.ByteStreams; /** * Ported from mixlib-authentication in order to sign Chef requests. @@ -72,7 +76,7 @@ public class SignedHeaderAuth implements HttpRequestFilter { private final String userId; private final PrivateKey privateKey; private final Provider timeStampProvider; - private final EncryptionService encryptionService; + private final Crypto crypto; private final String emptyStringHash; private final HttpUtils utils; @@ -82,12 +86,12 @@ public class SignedHeaderAuth implements HttpRequestFilter { @Inject public SignedHeaderAuth(SignatureWire signatureWire, @Named(PROPERTY_IDENTITY) String userId, PrivateKey privateKey, - @TimeStamp Provider timeStampProvider, EncryptionService encryptionService, HttpUtils utils) { + @TimeStamp Provider timeStampProvider, Crypto crypto, HttpUtils utils) { this.signatureWire = signatureWire; this.userId = userId; this.privateKey = privateKey; this.timeStampProvider = timeStampProvider; - this.encryptionService = encryptionService; + this.crypto = crypto; this.emptyStringHash = hashBody(Payloads.newStringPayload("")); this.utils = utils; } @@ -129,7 +133,7 @@ public class SignedHeaderAuth implements HttpRequestFilter { @VisibleForTesting String hashPath(String path) { try { - return encryptionService.base64(encryptionService.sha1(Utils.toInputStream(canonicalPath(path)))); + return CryptoStreams.base64(CryptoStreams.digest(InputSuppliers.of(canonicalPath(path)), crypto.sha1())); } catch (Exception e) { Throwables.propagateIfPossible(e); throw new HttpException("error creating sigature for path: " + path, e); @@ -154,7 +158,7 @@ public class SignedHeaderAuth implements HttpRequestFilter { checkArgument(payload != null, "payload was null"); checkArgument(payload.isRepeatable(), "payload must be repeatable: " + payload); try { - return encryptionService.base64(encryptionService.sha1(payload.getInput())); + return CryptoStreams.base64(CryptoStreams.digest(payload, crypto.sha1())); } catch (Exception e) { Throwables.propagateIfPossible(e); throw new HttpException("error creating sigature for payload: " + payload, e); @@ -182,8 +186,9 @@ public class SignedHeaderAuth implements HttpRequestFilter { public String sign(String toSign) { try { - byte[] encrypted = encryptionService.rsaEncrypt(Payloads.newStringPayload(toSign), privateKey); - return encryptionService.base64(encrypted); + byte[] encrypted = ByteStreams.toByteArray(new RSAEncryptingPayload(Payloads.newStringPayload(toSign), + privateKey)); + return CryptoStreams.base64(encrypted); } catch (Exception e) { throw new HttpException("error signing request", e); } diff --git a/chef/core/src/main/java/org/jclouds/chef/strategy/internal/DeleteAllClientsAndNodesInListImpl.java b/chef/core/src/main/java/org/jclouds/chef/strategy/internal/DeleteAllClientsAndNodesInListImpl.java index 41f292c360..5bface33ef 100644 --- a/chef/core/src/main/java/org/jclouds/chef/strategy/internal/DeleteAllClientsAndNodesInListImpl.java +++ b/chef/core/src/main/java/org/jclouds/chef/strategy/internal/DeleteAllClientsAndNodesInListImpl.java @@ -19,7 +19,7 @@ package org.jclouds.chef.strategy.internal; import static com.google.common.collect.Maps.newHashMap; -import static org.jclouds.concurrent.ConcurrentUtils.awaitCompletion; +import static org.jclouds.concurrent.FutureIterables.awaitCompletion; import java.util.Map; import java.util.concurrent.ExecutorService; diff --git a/chef/core/src/main/java/org/jclouds/chef/strategy/internal/GetNodesImpl.java b/chef/core/src/main/java/org/jclouds/chef/strategy/internal/GetNodesImpl.java index ab467b1248..de830b8fed 100644 --- a/chef/core/src/main/java/org/jclouds/chef/strategy/internal/GetNodesImpl.java +++ b/chef/core/src/main/java/org/jclouds/chef/strategy/internal/GetNodesImpl.java @@ -19,7 +19,7 @@ package org.jclouds.chef.strategy.internal; import static com.google.common.collect.Iterables.filter; -import static org.jclouds.concurrent.ConcurrentUtils.transformParallel; +import static org.jclouds.concurrent.FutureIterables.transformParallel; import java.util.concurrent.ExecutorService; import java.util.concurrent.Future; diff --git a/chef/core/src/main/java/org/jclouds/ohai/functions/ByteArrayToMacAddress.java b/chef/core/src/main/java/org/jclouds/ohai/functions/ByteArrayToMacAddress.java index 21c1b043bd..236290ab20 100644 --- a/chef/core/src/main/java/org/jclouds/ohai/functions/ByteArrayToMacAddress.java +++ b/chef/core/src/main/java/org/jclouds/ohai/functions/ByteArrayToMacAddress.java @@ -18,7 +18,6 @@ */ package org.jclouds.ohai.functions; -import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.collect.Iterables.transform; import static com.google.common.collect.Lists.partition; import static com.google.common.primitives.Bytes.asList; @@ -26,10 +25,9 @@ import static com.google.common.primitives.Bytes.toArray; import java.util.List; -import javax.inject.Inject; import javax.inject.Singleton; -import org.jclouds.encryption.EncryptionService; +import org.jclouds.crypto.CryptoStreams; import com.google.common.base.Function; import com.google.common.base.Joiner; @@ -42,12 +40,6 @@ import com.google.common.base.Joiner; */ @Singleton public class ByteArrayToMacAddress implements Function { - private final EncryptionService encryptionService; - - @Inject - ByteArrayToMacAddress(EncryptionService encryptionService) { - this.encryptionService = checkNotNull(encryptionService, "encryptionService"); - } @Override public String apply(byte[] from) { @@ -55,7 +47,7 @@ public class ByteArrayToMacAddress implements Function { @Override public String apply(List from) { - return encryptionService.hex(toArray(from)); + return CryptoStreams.hex(toArray(from)); } })); diff --git a/chef/core/src/test/java/org/jclouds/chef/ChefAsyncClientTest.java b/chef/core/src/test/java/org/jclouds/chef/ChefAsyncClientTest.java index 4a57a4ac00..cae6ef883d 100644 --- a/chef/core/src/test/java/org/jclouds/chef/ChefAsyncClientTest.java +++ b/chef/core/src/test/java/org/jclouds/chef/ChefAsyncClientTest.java @@ -37,8 +37,8 @@ import org.jclouds.chef.domain.Role; import org.jclouds.chef.filters.SignedHeaderAuth; import org.jclouds.chef.filters.SignedHeaderAuthTest; import org.jclouds.chef.functions.ParseKeySetFromJson; +import org.jclouds.crypto.CryptoStreams; import org.jclouds.date.TimeStamp; -import org.jclouds.encryption.EncryptionService; import org.jclouds.http.HttpRequest; import org.jclouds.http.RequiresHttp; import org.jclouds.http.functions.ParseJson; @@ -88,12 +88,11 @@ public class ChefAsyncClientTest extends RestClientTest { } public void testGetUploadSandboxForChecksums() throws SecurityException, NoSuchMethodException, IOException { - EncryptionService encryptionService = injector.getInstance(EncryptionService.class); Method method = ChefAsyncClient.class.getMethod("getUploadSandboxForChecksums", Set.class); GeneratedHttpRequest httpRequest = processor.createRequest(method, ImmutableSet.of(Bytes - .asList(encryptionService.fromHex("0189e76ccc476701d6b374e5a1a27347")), Bytes.asList(encryptionService - .fromHex("0c5ecd7788cf4f6c7de2a57193897a6c")), Bytes.asList(encryptionService - .fromHex("1dda05ed139664f1f89b9dec482b77c0")))); + .asList(CryptoStreams.hex("0189e76ccc476701d6b374e5a1a27347")), Bytes.asList(CryptoStreams + .hex("0c5ecd7788cf4f6c7de2a57193897a6c")), Bytes.asList(CryptoStreams + .hex("1dda05ed139664f1f89b9dec482b77c0")))); assertRequestLineEquals(httpRequest, "POST http://localhost:4000/sandboxes HTTP/1.1"); assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\nX-Chef-Version: 0.9.8\n"); assertPayloadEquals( diff --git a/chef/core/src/test/java/org/jclouds/chef/ChefClientLiveTest.java b/chef/core/src/test/java/org/jclouds/chef/ChefClientLiveTest.java index 13f19e48c0..1e84a56190 100644 --- a/chef/core/src/test/java/org/jclouds/chef/ChefClientLiveTest.java +++ b/chef/core/src/test/java/org/jclouds/chef/ChefClientLiveTest.java @@ -41,6 +41,9 @@ import org.jclouds.chef.domain.Node; import org.jclouds.chef.domain.Resource; import org.jclouds.chef.domain.Role; import org.jclouds.chef.domain.UploadSandbox; +import org.jclouds.crypto.CryptoStreams; +import org.jclouds.crypto.Pems; +import org.jclouds.io.InputSuppliers; import org.jclouds.io.Payloads; import org.jclouds.io.payloads.FilePayload; import org.jclouds.logging.log4j.config.Log4JLoggingModule; @@ -108,7 +111,7 @@ public class ChefClientLiveTest { content.setContentType("application/x-binary"); // get an md5 so that you can see if the server already has it or not - adminConnection.utils().encryption().generateMD5BufferingIfNotRepeatable(content); + Payloads.calculateMD5(content); // Note that java collections cannot effectively do equals or hashcodes on // byte arrays, @@ -142,8 +145,7 @@ public class ChefClientLiveTest { @Test(dependsOnMethods = "testCreateClient") public void testGenerateKeyForClient() throws Exception { - clientKey = validatorConnection.utils().encryption().toPem( - validatorConnection.getApi().generateKeyForClient(PREFIX).getPrivateKey()); + clientKey = Pems.pem(validatorConnection.getApi().generateKeyForClient(PREFIX).getPrivateKey()); assertNotNull(clientKey); clientConnection.close(); @@ -163,7 +165,7 @@ public class ChefClientLiveTest { cookbookO.getTemplates()).build()) { try { InputStream stream = adminConnection.utils().http().get(resource.getUrl()); - byte[] md5 = adminConnection.utils().encryption().md5(stream); + byte[] md5 = CryptoStreams.md5(InputSuppliers.of(stream)); assertEquals(md5, resource.getChecksum()); } catch (NullPointerException e) { assert false : "resource not found: " + resource; @@ -205,8 +207,7 @@ public class ChefClientLiveTest { public void testCreateClient() throws Exception { validatorConnection.getApi().deleteClient(PREFIX); - clientKey = validatorConnection.utils().encryption().toPem( - validatorConnection.getApi().createClient(PREFIX).getPrivateKey()); + clientKey = Pems.pem(validatorConnection.getApi().createClient(PREFIX).getPrivateKey()); System.out.println(clientKey); assertNotNull(clientKey); diff --git a/chef/core/src/test/java/org/jclouds/chef/binders/BindHexEncodedMD5sToJsonPayloadTest.java b/chef/core/src/test/java/org/jclouds/chef/binders/BindHexEncodedMD5sToJsonPayloadTest.java index 5d3bd29d75..5e262beb74 100644 --- a/chef/core/src/test/java/org/jclouds/chef/binders/BindHexEncodedMD5sToJsonPayloadTest.java +++ b/chef/core/src/test/java/org/jclouds/chef/binders/BindHexEncodedMD5sToJsonPayloadTest.java @@ -31,7 +31,7 @@ import java.net.URI; import javax.ws.rs.HttpMethod; import org.jclouds.chef.config.ChefParserModule; -import org.jclouds.encryption.EncryptionService; +import org.jclouds.crypto.CryptoStreams; import org.jclouds.http.HttpRequest; import org.jclouds.json.config.GsonModule; import org.testng.annotations.Test; @@ -58,8 +58,7 @@ public class BindHexEncodedMD5sToJsonPayloadTest { @Test(enabled = false) public void testCorrect() { HttpRequest request = new HttpRequest(HttpMethod.POST, URI.create("http://localhost")); - binder.bindToRequest(request, ImmutableSet.of(injector.getInstance(EncryptionService.class).fromHex("abddef"), - injector.getInstance(EncryptionService.class).fromHex("1234"))); + binder.bindToRequest(request, ImmutableSet.of(CryptoStreams.hex("abddef"), CryptoStreams.hex("1234"))); assertEquals(request.getPayload().getRawContent(), "{\"checksums\":{\"abddef\":null,\"1234\":null}}"); } diff --git a/chef/core/src/test/java/org/jclouds/chef/filters/SignedHeaderAuthTest.java b/chef/core/src/test/java/org/jclouds/chef/filters/SignedHeaderAuthTest.java index 9b11c623c0..8f0bce1ce7 100644 --- a/chef/core/src/test/java/org/jclouds/chef/filters/SignedHeaderAuthTest.java +++ b/chef/core/src/test/java/org/jclouds/chef/filters/SignedHeaderAuthTest.java @@ -34,7 +34,7 @@ import javax.inject.Provider; import javax.ws.rs.HttpMethod; import javax.ws.rs.core.HttpHeaders; -import org.jclouds.encryption.EncryptionService; +import org.jclouds.crypto.Crypto; import org.jclouds.http.HttpRequest; import org.jclouds.http.HttpUtils; import org.jclouds.http.internal.SignatureWire; @@ -173,7 +173,7 @@ public class SignedHeaderAuthTest { } private SignedHeaderAuth signing_obj; - private EncryptionService encryptionService; + private Crypto crypto; /** * before class, as we need to ensure that the filter is threadsafe. @@ -187,7 +187,7 @@ public class SignedHeaderAuthTest { Injector injector = new RestContextFactory().createContextBuilder("chef", USER_ID, PRIVATE_KEY, ImmutableSet. of(new MockModule(), new NullLoggingModule()), new Properties()).buildInjector(); - encryptionService = injector.getInstance(EncryptionService.class); + crypto = injector.getInstance(Crypto.class); HttpUtils utils = injector.getInstance(HttpUtils.class); PrivateKey privateKey = injector.getInstance(PrivateKey.class); @@ -199,7 +199,7 @@ public class SignedHeaderAuthTest { return TIMESTAMP_ISO8601; } - }, encryptionService, utils); + }, crypto, utils); } } \ No newline at end of file diff --git a/chef/core/src/test/java/org/jclouds/chef/functions/ParseClientFromJsonTest.java b/chef/core/src/test/java/org/jclouds/chef/functions/ParseClientFromJsonTest.java index e8a5492e9b..ff15715f13 100644 --- a/chef/core/src/test/java/org/jclouds/chef/functions/ParseClientFromJsonTest.java +++ b/chef/core/src/test/java/org/jclouds/chef/functions/ParseClientFromJsonTest.java @@ -5,18 +5,24 @@ import static org.testng.Assert.assertEquals; import java.io.IOException; import java.security.PrivateKey; +import java.security.cert.CertificateException; import java.security.cert.X509Certificate; +import java.security.spec.InvalidKeySpecException; import org.jclouds.chef.config.ChefParserModule; import org.jclouds.chef.domain.Client; -import org.jclouds.encryption.EncryptionService; +import org.jclouds.crypto.Crypto; +import org.jclouds.crypto.Pems; import org.jclouds.http.HttpResponse; import org.jclouds.http.functions.ParseJson; import org.jclouds.io.Payloads; +import org.jclouds.io.payloads.RSADecryptingPayload; +import org.jclouds.io.payloads.RSAEncryptingPayload; import org.jclouds.json.config.GsonModule; import org.testng.annotations.BeforeTest; import org.testng.annotations.Test; +import com.google.common.io.ByteStreams; import com.google.inject.Guice; import com.google.inject.Injector; import com.google.inject.Key; @@ -33,30 +39,30 @@ public class ParseClientFromJsonTest { private static final String PRIVATE_KEY = "-----BEGIN RSA PRIVATE KEY-----\nMIIEpQIBAAKCAQEAyb2ZJJqGm0KKR+8nfQJNsSd+F9tXNMV7CfOcW6jsqs8EZgiV\nR09hD1IYOj4YqM0qJONlgyg4xRWewdSG7QTPj1lJpVAida9sXy2+kzyagZA1Am0O\nZcbqb5hoeIDgcX+eDa79s0u0DomjcfO9EKhvHLBz+zM+3QqPRkPV8nYTbfs+HjVz\nzOU6D1B0XR3+IPZZl2AnWs2d0qhnStHcDUvnRVQ0P482YwN9VgceOZtpPz0DCKEJ\n5Tx5STub8k0/zt/VAMHQafLSuQMLd2s4ZLuOZptN//uAsTmxireqd37z+8ZTdBbJ\n8LEpJ+iCXuSfm5aUh7iw6oxvToY2AL53+jK2UQIDAQABAoIBAQDA88B3i/xWn0vX\nBVxFamCYoecuNjGwXXkSyZew616A+EOCu47bh4aTurdFbYL0YFaAtaWvzlaN2eHg\nDb+HDuTefE29+WkcGk6SshPmiz5T0XOCAICWw6wSVDkHmGwS4jZvbAFm7W8nwGk9\nYhxgxFiRngswJZFopOLoF5WXs2td8guIYNslMpo7tu50iFnBHwKO2ZsPAk8t9nnS\nxlDavKruymEmqHCr3+dtio5eaenJcp3fjoXBQOKUk3ipII29XRB8NqeCVV/7Kxwq\nckqOBEbRwBclckyIbD+RiAgKvOelORjEiE9R42vuqvxRA6k9kd9o7utlX0AUtpEn\n3gZc6LepAoGBAP9ael5Y75+sK2JJUNOOhO8ae45cdsilp2yI0X+UBaSuQs2+dyPp\nkpEHAxd4pmmSvn/8c9TlEZhr+qYbABXVPlDncxpIuw2Ajbk7s/S4XaSKsRqpXL57\nzj/QOqLkRk8+OVV9q6lMeQNqLtEj1u6JPviX70Ro+FQtRttNOYbfdP/fAoGBAMpA\nXjR5woV5sUb+REg9vEuYo8RSyOarxqKFCIXVUNsLOx+22+AK4+CQpbueWN7jotrl\nYD6uT6svWi3AAC7kiY0UI/fjVPRCUi8tVoQUE0TaU5VLITaYOB+W/bBaDE4M9560\n1NuDWO90baA5dfU44iuzva02rGJXK9+nS3o8nk/PAoGBALOL6djnDe4mwAaG6Jco\ncd4xr8jkyPzCRZuyBCSBbwphIUXLc7hDprPky064ncJD1UDmwIdkXd/fpMkg2QmA\n/CUk6LEFjMisqHojOaCL9gQZJPhLN5QUN2x1PJWGjs1vQh8Tkx0iUUCOa8bQPXNR\n+34OTsW6TUna4CSZAycLfhffAoGBAIggVsefBCvuQkF0NeUhmDCRZfhnd8y55RHR\n1HCvqKIlpv+rhcX/zmyBLuteopYyRJRsOiE2FW00i8+rIPRu4Z3Q5nybx7w3PzV9\noHN5R5baE9OyI4KpZWztpYYitZF67NcnAvVULHHOvVJQGnKYfLHJYmrJF7GA1ojM\nAuMdFbjFAoGAPxUhxwFy8gaqBahKUEZn4F81HFP5ihGhkT4QL6AFPO2e+JhIGjuR\n27+85hcFqQ+HHVtFsm81b/a+R7P4UuCRgc8eCjxQMoJ1Xl4n7VbjPbHMnIN0Ryvd\nO4ZpWDWYnCO021JTOUUOJ4J/y0416Bvkw0z59y7sNX7wDBBHHbK/XCc=\n-----END RSA PRIVATE KEY-----\n"; private static final String CERTIFICATE = "-----BEGIN CERTIFICATE-----\nMIIClzCCAgCgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBnjELMAkGA1UEBhMCVVMx\nEzARBgNVBAgMCldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUxFjAUBgNVBAoM\nDU9wc2NvZGUsIEluYy4xHDAaBgNVBAsME0NlcnRpZmljYXRlIFNlcnZpY2UxMjAw\nBgNVBAMMKW9wc2NvZGUuY29tL2VtYWlsQWRkcmVzcz1hdXRoQG9wc2NvZGUuY29t\nMB4XDTEwMDczMDIwNDEzMFoXDTIwMDcyNzIwNDEzMFowADCCASIwDQYJKoZIhvcN\nAQEBBQADggEPADCCAQoCggEBAMm9mSSahptCikfvJ30CTbEnfhfbVzTFewnznFuo\n7KrPBGYIlUdPYQ9SGDo+GKjNKiTjZYMoOMUVnsHUhu0Ez49ZSaVQInWvbF8tvpM8\nmoGQNQJtDmXG6m+YaHiA4HF/ng2u/bNLtA6Jo3HzvRCobxywc/szPt0Kj0ZD1fJ2\nE237Ph41c8zlOg9QdF0d/iD2WZdgJ1rNndKoZ0rR3A1L50VUND+PNmMDfVYHHjmb\naT89AwihCeU8eUk7m/JNP87f1QDB0Gny0rkDC3drOGS7jmabTf/7gLE5sYq3qnd+\n8/vGU3QWyfCxKSfogl7kn5uWlIe4sOqMb06GNgC+d/oytlECAwEAATANBgkqhkiG\n9w0BAQUFAAOBgQBftzSZxstWw60GqRTDNN/F2GnrdtnKBoXzHww3r6jtGEylYq20\n5KfKpEx+sPX0gyZuYJiXC2CkEjImAluWKcdN9ZF6VD541sheAjbiaU7q7ZsztTxF\nWUH2tCvHeDXYKPKek3QzL7bYpUhLnCN/XxEv6ibeMDwtI7f5qpk2Aspzcw==\n-----END CERTIFICATE-----\n"; private ParseJson handler; - private EncryptionService encryptionService; + private Crypto crypto; private PrivateKey privateKey; private X509Certificate certificate; @BeforeTest - protected void setUpInjector() throws IOException { + protected void setUpInjector() throws IOException, CertificateException, InvalidKeySpecException { Injector injector = Guice.createInjector(new ChefParserModule(), new GsonModule()); handler = injector.getInstance(Key.get(new TypeLiteral>() { })); - encryptionService = injector.getInstance(EncryptionService.class); - certificate = encryptionService.x509CertificateFromPEM(CERTIFICATE.getBytes("UTF-8")); - privateKey = encryptionService.privateKeyFromPEM(PRIVATE_KEY.getBytes("UTF-8")); + crypto = injector.getInstance(Crypto.class); + certificate = Pems.x509Certificate(Payloads.newStringPayload(CERTIFICATE), null); + privateKey = crypto.rsaKeyFactory().generatePrivate(Pems.privateKeySpec(Payloads.newStringPayload(PRIVATE_KEY))); } - public void test() { + public void test() throws IOException { Client user = new Client(certificate, "jclouds", "adriancole-jcloudstest", "adriancole-jcloudstest", false, privateKey); - byte[] encrypted = encryptionService.rsaEncrypt(Payloads.newPayload("fooya"), user.getCertificate() - .getPublicKey()); + byte[] encrypted = ByteStreams.toByteArray(new RSAEncryptingPayload(Payloads.newPayload("fooya"), user + .getCertificate().getPublicKey())); - assertEquals(encryptionService.rsaDecrypt(Payloads.newPayload(encrypted), user.getPrivateKey()), "fooya" - .getBytes()); + assertEquals(ByteStreams.toByteArray(new RSADecryptingPayload(Payloads.newPayload(encrypted), user + .getPrivateKey())), "fooya".getBytes()); assertEquals(handler.apply(new HttpResponse(200, "ok", newInputStreamPayload(ParseClientFromJsonTest.class .getResourceAsStream("/client.json")))), user); diff --git a/chef/core/src/test/java/org/jclouds/chef/functions/ParseCookbookVersionFromJsonTest.java b/chef/core/src/test/java/org/jclouds/chef/functions/ParseCookbookVersionFromJsonTest.java index 790fd80d49..fe86284ad3 100644 --- a/chef/core/src/test/java/org/jclouds/chef/functions/ParseCookbookVersionFromJsonTest.java +++ b/chef/core/src/test/java/org/jclouds/chef/functions/ParseCookbookVersionFromJsonTest.java @@ -11,7 +11,7 @@ import org.jclouds.chef.domain.Attribute; import org.jclouds.chef.domain.CookbookVersion; import org.jclouds.chef.domain.Metadata; import org.jclouds.chef.domain.Resource; -import org.jclouds.encryption.EncryptionService; +import org.jclouds.crypto.CryptoStreams; import org.jclouds.http.HttpResponse; import org.jclouds.http.functions.ParseJson; import org.jclouds.io.Payloads; @@ -51,68 +51,69 @@ public class ParseCookbookVersionFromJsonTest { @Test(enabled = false) public void testBrew() throws IOException { CookbookVersion cookbook = handler.apply(new HttpResponse(200, "ok", Payloads - .newPayload(ParseCookbookVersionFromJsonTest.class.getResourceAsStream("/brew-cookbook.json")))); + .newPayload(ParseCookbookVersionFromJsonTest.class.getResourceAsStream("/brew-cookbook.json")))); assertEquals(cookbook, handler.apply(new HttpResponse(200, "ok", Payloads.newPayload(Utils.toInputStream(json - .toJson(cookbook)))))); + .toJson(cookbook)))))); } @Test(enabled = false) public void testTomcat() { CookbookVersion cookbook = handler.apply(new HttpResponse(200, "ok", Payloads - .newPayload(ParseCookbookVersionFromJsonTest.class.getResourceAsStream("/tomcat-cookbook.json")))); + .newPayload(ParseCookbookVersionFromJsonTest.class.getResourceAsStream("/tomcat-cookbook.json")))); assertEquals(cookbook, handler.apply(new HttpResponse(200, "ok", Payloads.newPayload(Utils.toInputStream(json - .toJson(cookbook)))))); + .toJson(cookbook)))))); } @Test(enabled = false) public void testMysql() throws IOException { CookbookVersion cookbook = handler.apply(new HttpResponse(200, "ok", Payloads - .newPayload(ParseCookbookVersionFromJsonTest.class.getResourceAsStream("/mysql-cookbook.json")))); + .newPayload(ParseCookbookVersionFromJsonTest.class.getResourceAsStream("/mysql-cookbook.json")))); assertEquals(cookbook, handler.apply(new HttpResponse(200, "ok", Payloads.newPayload(Utils.toInputStream(json - .toJson(cookbook)))))); + .toJson(cookbook)))))); } @Test(enabled = false) public void testApache() { - EncryptionService encryptionService = injector.getInstance(EncryptionService.class); assertEquals( - handler.apply(new HttpResponse(200, "ok", Payloads.newPayload(ParseCookbookVersionFromJsonTest.class - .getResourceAsStream("/apache-chef-demo-cookbook.json")))), - new CookbookVersion( - "apache-chef-demo-0.0.0", - ImmutableSet. of(), - ImmutableSet. of(), - ImmutableSet. of(), - new Metadata("Apache v2.0", "Your Name", ImmutableMap. of(), ImmutableMap - .> of(), "youremail@example.com", ImmutableMap.> of(), - "A fabulous new cookbook", ImmutableMap.> of(), ImmutableMap - .> of(), "0.0.0", ImmutableMap. of(), ImmutableMap - .> of(), "apache-chef-demo", ImmutableMap. of(), "", - ImmutableMap. of(), ImmutableMap. of()), - ImmutableSet. of(), - "apache-chef-demo", - ImmutableSet. of(), - ImmutableSet. of(), - ImmutableSet. of(), - "0.0.0", - ImmutableSet. of(), - ImmutableSet - . of( - new Resource( - "README", - URI - .create("https://s3.amazonaws.com/opscode-platform-production-data/organization-486ca3ac66264fea926aa0b4ff74341c/checksum-11637f98942eafbf49c71b7f2f048b78?AWSAccessKeyId=AKIAJOZTD2N26S7W6APA&Expires=1277766181&Signature=zgpNl6wSxjTNovqZu2nJq0JztU8%3D"), - encryptionService.fromHex("11637f98942eafbf49c71b7f2f048b78"), "README", "default"), - new Resource( - "Rakefile", - URI - .create("https://s3.amazonaws.com/opscode-platform-production-data/organization-486ca3ac66264fea926aa0b4ff74341c/checksum-ebcf925a1651b4e04b9cd8aac2bc54eb?AWSAccessKeyId=AKIAJOZTD2N26S7W6APA&Expires=1277766181&Signature=EFzzDSKKytTl7b%2FxrCeNLh05zj4%3D"), - encryptionService.fromHex("ebcf925a1651b4e04b9cd8aac2bc54eb"), "Rakefile", - "default")))); + handler.apply(new HttpResponse(200, "ok", Payloads.newPayload(ParseCookbookVersionFromJsonTest.class + .getResourceAsStream("/apache-chef-demo-cookbook.json")))), + new CookbookVersion( + "apache-chef-demo-0.0.0", + ImmutableSet. of(), + ImmutableSet. of(), + ImmutableSet. of(), + new Metadata("Apache v2.0", "Your Name", ImmutableMap. of(), ImmutableMap + .> of(), "youremail@example.com", ImmutableMap + .> of(), "A fabulous new cookbook", ImmutableMap + .> of(), ImmutableMap.> of(), "0.0.0", + ImmutableMap. of(), ImmutableMap.> of(), + "apache-chef-demo", ImmutableMap. of(), "", ImmutableMap + . of(), ImmutableMap. of()), + ImmutableSet. of(), + "apache-chef-demo", + ImmutableSet. of(), + ImmutableSet. of(), + ImmutableSet. of(), + "0.0.0", + ImmutableSet. of(), + ImmutableSet + . of( + new Resource( + "README", + URI + .create("https://s3.amazonaws.com/opscode-platform-production-data/organization-486ca3ac66264fea926aa0b4ff74341c/checksum-11637f98942eafbf49c71b7f2f048b78?AWSAccessKeyId=AKIAJOZTD2N26S7W6APA&Expires=1277766181&Signature=zgpNl6wSxjTNovqZu2nJq0JztU8%3D"), + CryptoStreams.hex("11637f98942eafbf49c71b7f2f048b78"), "README", + "default"), + new Resource( + "Rakefile", + URI + .create("https://s3.amazonaws.com/opscode-platform-production-data/organization-486ca3ac66264fea926aa0b4ff74341c/checksum-ebcf925a1651b4e04b9cd8aac2bc54eb?AWSAccessKeyId=AKIAJOZTD2N26S7W6APA&Expires=1277766181&Signature=EFzzDSKKytTl7b%2FxrCeNLh05zj4%3D"), + CryptoStreams.hex("ebcf925a1651b4e04b9cd8aac2bc54eb"), "Rakefile", + "default")))); } } diff --git a/chef/core/src/test/java/org/jclouds/chef/functions/ParseUploadSandboxFromJsonTest.java b/chef/core/src/test/java/org/jclouds/chef/functions/ParseUploadSandboxFromJsonTest.java index 12d706389e..4f21e610f5 100644 --- a/chef/core/src/test/java/org/jclouds/chef/functions/ParseUploadSandboxFromJsonTest.java +++ b/chef/core/src/test/java/org/jclouds/chef/functions/ParseUploadSandboxFromJsonTest.java @@ -9,7 +9,7 @@ import java.util.List; import org.jclouds.chef.config.ChefParserModule; import org.jclouds.chef.domain.ChecksumStatus; import org.jclouds.chef.domain.UploadSandbox; -import org.jclouds.encryption.EncryptionService; +import org.jclouds.crypto.CryptoStreams; import org.jclouds.http.HttpResponse; import org.jclouds.http.functions.ParseJson; import org.jclouds.io.Payloads; @@ -43,22 +43,21 @@ public class ParseUploadSandboxFromJsonTest { } public void test() { - EncryptionService encryptionService = injector.getInstance(EncryptionService.class); assertEquals( - handler.apply(new HttpResponse(200, "ok", Payloads.newPayload(ParseUploadSandboxFromJsonTest.class - .getResourceAsStream("/upload-site.json")))), - new UploadSandbox( - URI - .create("https://api.opscode.com/organizations/jclouds/sandboxes/d454f71e2a5f400c808d0c5d04c2c88c"), - ImmutableMap - ., ChecksumStatus> of( - Bytes.asList(encryptionService.fromHex("0c5ecd7788cf4f6c7de2a57193897a6c")), - new ChecksumStatus( - URI - .create("https://s3.amazonaws.com/opscode-platform-production-data/organization-486ca3ac66264fea926aa0b4ff74341c/sandbox-d454f71e2a5f400c808d0c5d04c2c88c/checksum-0c5ecd7788cf4f6c7de2a57193897a6c?AWSAccessKeyId=AKIAJOZTD2N26S7W6APA&Expires=1277344702&Signature=FtKyqvYEjhhEKmRY%2B0M8aGPMM7g%3D"), - true), Bytes.asList(encryptionService.fromHex("0189e76ccc476701d6b374e5a1a27347")), - new ChecksumStatus(), Bytes.asList(encryptionService - .fromHex("1dda05ed139664f1f89b9dec482b77c0")), new ChecksumStatus()), - "d454f71e2a5f400c808d0c5d04c2c88c")); + handler.apply(new HttpResponse(200, "ok", Payloads.newPayload(ParseUploadSandboxFromJsonTest.class + .getResourceAsStream("/upload-site.json")))), + new UploadSandbox( + URI + .create("https://api.opscode.com/organizations/jclouds/sandboxes/d454f71e2a5f400c808d0c5d04c2c88c"), + ImmutableMap + ., ChecksumStatus> of( + Bytes.asList(CryptoStreams.hex("0c5ecd7788cf4f6c7de2a57193897a6c")), + new ChecksumStatus( + URI + .create("https://s3.amazonaws.com/opscode-platform-production-data/organization-486ca3ac66264fea926aa0b4ff74341c/sandbox-d454f71e2a5f400c808d0c5d04c2c88c/checksum-0c5ecd7788cf4f6c7de2a57193897a6c?AWSAccessKeyId=AKIAJOZTD2N26S7W6APA&Expires=1277344702&Signature=FtKyqvYEjhhEKmRY%2B0M8aGPMM7g%3D"), + true), Bytes.asList(CryptoStreams + .hex("0189e76ccc476701d6b374e5a1a27347")), new ChecksumStatus(), + Bytes.asList(CryptoStreams.hex("1dda05ed139664f1f89b9dec482b77c0")), + new ChecksumStatus()), "d454f71e2a5f400c808d0c5d04c2c88c")); } } diff --git a/chef/core/src/test/java/org/jclouds/ohai/functions/ByteArrayToMacAddressTest.java b/chef/core/src/test/java/org/jclouds/ohai/functions/ByteArrayToMacAddressTest.java index be48d9d604..2b0b5f283c 100644 --- a/chef/core/src/test/java/org/jclouds/ohai/functions/ByteArrayToMacAddressTest.java +++ b/chef/core/src/test/java/org/jclouds/ohai/functions/ByteArrayToMacAddressTest.java @@ -27,7 +27,7 @@ import static org.testng.Assert.assertEquals; import java.io.IOException; -import org.jclouds.encryption.EncryptionService; +import org.jclouds.crypto.CryptoStreams; import org.testng.annotations.BeforeTest; import org.testng.annotations.Test; @@ -43,16 +43,14 @@ import com.google.inject.Injector; public class ByteArrayToMacAddressTest { private ByteArrayToMacAddress converter; - private EncryptionService encryptionService; @BeforeTest protected void setUpInjector() throws IOException { Injector injector = Guice.createInjector(); converter = injector.getInstance(ByteArrayToMacAddress.class); - encryptionService = injector.getInstance(EncryptionService.class); } public void test() { - assertEquals(converter.apply(encryptionService.fromHex("0026bb09e6c4")), "00:26:bb:09:e6:c4"); + assertEquals(converter.apply(CryptoStreams.hex("0026bb09e6c4")), "00:26:bb:09:e6:c4"); } } diff --git a/chef/servlet/src/main/java/org/jclouds/chef/servlet/ChefRegistrationListener.java b/chef/servlet/src/main/java/org/jclouds/chef/servlet/ChefRegistrationListener.java index ec1dcc58e7..653a6e4372 100644 --- a/chef/servlet/src/main/java/org/jclouds/chef/servlet/ChefRegistrationListener.java +++ b/chef/servlet/src/main/java/org/jclouds/chef/servlet/ChefRegistrationListener.java @@ -43,10 +43,13 @@ import org.jclouds.chef.ChefService; import org.jclouds.chef.domain.Client; import org.jclouds.chef.reference.ChefConstants; import org.jclouds.chef.servlet.functions.InitParamsToProperties; +import org.jclouds.crypto.Pems; import org.jclouds.logging.Logger; import org.jclouds.logging.jdk.JDKLogger; import org.jclouds.rest.RestContextFactory; +import com.google.common.base.Throwables; + /** * Registers a new node in Chef and binds its name to {@link ChefConstants.CHEF_NODE}, its role to * {@link ChefConstants.CHEF_ROLE} and the {@link ChefService} for the client to @@ -129,14 +132,14 @@ public class ChefRegistrationListener implements ServletContextListener { clientProperties.putAll(overrides); removeCredentials(clientProperties); clientProperties.setProperty("chef.identity", id); - clientProperties.setProperty("chef.credential", validatorClient.getContext().utils().encryption().toPem( - client.getPrivateKey())); + clientProperties.setProperty("chef.credential", Pems.pem(client.getPrivateKey())); clientService = createService(clientProperties); clientService.createNodeAndPopulateAutomaticAttributes(id, singleton("role[" + role + "]")); return clientService; - } catch (RuntimeException e) { + } catch (Exception e) { logger.error(e, "error creating node %s", id); - throw e; + Throwables.propagate(e); + return null; } } diff --git a/compute/src/main/java/org/jclouds/compute/internal/BaseComputeService.java b/compute/src/main/java/org/jclouds/compute/internal/BaseComputeService.java index bbd318bae9..e805e6d10d 100755 --- a/compute/src/main/java/org/jclouds/compute/internal/BaseComputeService.java +++ b/compute/src/main/java/org/jclouds/compute/internal/BaseComputeService.java @@ -26,8 +26,8 @@ package org.jclouds.compute.internal; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; import static org.jclouds.compute.util.ComputeServiceUtils.installNewCredentials; -import static org.jclouds.concurrent.ConcurrentUtils.awaitCompletion; -import static org.jclouds.concurrent.ConcurrentUtils.transformParallel; +import static org.jclouds.concurrent.FutureIterables.awaitCompletion; +import static org.jclouds.concurrent.FutureIterables.transformParallel; import java.util.Map; import java.util.Set; diff --git a/compute/src/main/java/org/jclouds/compute/internal/UtilsImpl.java b/compute/src/main/java/org/jclouds/compute/internal/UtilsImpl.java index f072d29954..1b6aed6288 100644 --- a/compute/src/main/java/org/jclouds/compute/internal/UtilsImpl.java +++ b/compute/src/main/java/org/jclouds/compute/internal/UtilsImpl.java @@ -25,8 +25,8 @@ import javax.inject.Singleton; import org.jclouds.Constants; import org.jclouds.compute.Utils; +import org.jclouds.crypto.Crypto; import org.jclouds.date.DateService; -import org.jclouds.encryption.EncryptionService; import org.jclouds.json.Json; import org.jclouds.logging.Logger.LoggerFactory; import org.jclouds.rest.HttpAsyncClient; @@ -46,7 +46,7 @@ public class UtilsImpl extends org.jclouds.rest.internal.UtilsImpl implements Ut @Inject UtilsImpl(Json json, HttpClient simpleClient, HttpAsyncClient simpleAsyncClient, - EncryptionService encryption, DateService date, + Crypto encryption, DateService date, @Named(Constants.PROPERTY_USER_THREADS) ExecutorService userThreads, @Named(Constants.PROPERTY_IO_WORKER_THREADS) ExecutorService ioThreads, LoggerFactory loggerFactory) { diff --git a/compute/src/main/java/org/jclouds/compute/util/ComputeUtils.java b/compute/src/main/java/org/jclouds/compute/util/ComputeUtils.java index cb4010ad41..fa994baa5f 100644 --- a/compute/src/main/java/org/jclouds/compute/util/ComputeUtils.java +++ b/compute/src/main/java/org/jclouds/compute/util/ComputeUtils.java @@ -22,7 +22,7 @@ import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkState; import static org.jclouds.compute.util.ComputeServiceUtils.installNewCredentials; import static org.jclouds.compute.util.ComputeServiceUtils.isKeyAuth; -import static org.jclouds.concurrent.ConcurrentUtils.awaitCompletion; +import static org.jclouds.concurrent.FutureIterables.awaitCompletion; import java.util.List; import java.util.Map; diff --git a/core/src/main/clojure/org/jclouds/core.clj b/core/src/main/clojure/org/jclouds/core.clj index 9ee386bfce..ed8d7812c7 100644 --- a/core/src/main/clojure/org/jclouds/core.clj +++ b/core/src/main/clojure/org/jclouds/core.clj @@ -34,7 +34,7 @@ :enterprise 'org.jclouds.enterprise.config.EnterpriseConfigurationModule :apachehc 'org.jclouds.http.apachehc.config.ApacheHCHttpCommandExecutorServiceModule :ning 'org.jclouds.http.ning.config.NingHttpCommandExecutorServiceModule - :bouncycastle 'org.jclouds.encryption.bouncycastle.config.BouncyCastleEncryptionServiceModule + :bouncycastle 'org.jclouds.encryption.bouncycastle.config.BouncyCastleCryptoModule :joda 'org.jclouds.date.joda.config.JodaDateServiceModule :gae 'org.jclouds.gae.config.GoogleAppEngineConfigurationModule}) diff --git a/core/src/main/java/org/jclouds/concurrent/ConcurrentUtils.java b/core/src/main/java/org/jclouds/concurrent/ConcurrentUtils.java deleted file mode 100644 index c9ea54cad8..0000000000 --- a/core/src/main/java/org/jclouds/concurrent/ConcurrentUtils.java +++ /dev/null @@ -1,561 +0,0 @@ -/** - * - * Copyright (C) 2009 Cloud Conscious, LLC. - * - * ==================================================================== - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ -package org.jclouds.concurrent; - -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.collect.Maps.newHashMap; - -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.concurrent.AbstractExecutorService; -import java.util.concurrent.CancellationException; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.Executor; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Future; -import java.util.concurrent.RejectedExecutionException; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; -import java.util.concurrent.ThreadPoolExecutor.CallerRunsPolicy; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.locks.Condition; -import java.util.concurrent.locks.Lock; -import java.util.concurrent.locks.ReentrantLock; - -import javax.annotation.Nullable; -import javax.annotation.Resource; -import javax.inject.Named; -import javax.inject.Singleton; - -import org.jclouds.Constants; -import org.jclouds.http.handlers.BackoffLimitedRetryHandler; -import org.jclouds.logging.Logger; - -import com.google.common.base.Function; -import com.google.common.base.Throwables; -import com.google.common.collect.ForwardingObject; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.Iterables; -import com.google.common.collect.Maps; -import com.google.common.util.concurrent.ExecutionList; -import com.google.common.util.concurrent.ForwardingFuture; -import com.google.common.util.concurrent.Futures; -import com.google.common.util.concurrent.ListenableFuture; -import com.google.common.util.concurrent.MoreExecutors; -import com.google.inject.Inject; - -/** - * Adapt things from Guava. - * - * @author Adrian Cole - */ -@Singleton -public class ConcurrentUtils { - @Resource - private static Logger logger = Logger.CONSOLE; - - @Inject(optional = true) - @Named(Constants.PROPERTY_MAX_RETRIES) - private static int maxRetries = 5; - - @Inject(optional = true) - private static BackoffLimitedRetryHandler retryHandler = BackoffLimitedRetryHandler.INSTANCE; - - public static Iterable transformParallel(final Iterable fromIterable, - final Function> function) { - return transformParallel(fromIterable, function, sameThreadExecutor(), null); - } - - public static Iterable transformParallel(final Iterable fromIterable, - final Function> function, ExecutorService exec, @Nullable Long maxTime) { - return transformParallel(fromIterable, function, exec, maxTime, logger, "transforming"); - } - - public static Iterable transformParallel(final Iterable fromIterable, - final Function> function, ExecutorService exec, @Nullable Long maxTime, Logger logger, - String logPrefix) { - return transformParallel(fromIterable, function, exec, maxTime, logger, logPrefix, retryHandler, maxRetries); - } - - public static Iterable transformParallel(Iterable fromIterable, - Function> function, ExecutorService exec, @Nullable Long maxTime, Logger logger, - String logPrefix, BackoffLimitedRetryHandler retryHandler, int maxRetries) { - Map exceptions = newHashMap(); - Map> responses = newHashMap(); - for (int i = 0; i < maxRetries; i++) { - - for (F from : fromIterable) { - responses.put(from, function.apply(from)); - } - exceptions = awaitCompletion(responses, exec, maxTime, logger, logPrefix); - if (exceptions.size() > 0) { - fromIterable = exceptions.keySet(); - retryHandler.imposeBackoffExponentialDelay(i + 1, String.format("error %s: %s: %s", logPrefix, - fromIterable, exceptions)); - } else { - break; - } - } - if (exceptions.size() > 0) - throw new RuntimeException(String.format("error %s: %s: %s", logPrefix, fromIterable, exceptions)); - - return unwrap(responses.values()); - } - - public static Map awaitCompletion(Map> responses, ExecutorService exec, - @Nullable Long maxTime, final Logger logger, final String logPrefix) { - if (responses.size() == 0) - return ImmutableMap.of(); - final int total = responses.size(); - final CountDownLatch doneSignal = new CountDownLatch(total); - final AtomicInteger complete = new AtomicInteger(0); - final AtomicInteger errors = new AtomicInteger(0); - final long start = System.currentTimeMillis(); - final Map errorMap = Maps.newHashMap(); - for (final java.util.Map.Entry> future : responses.entrySet()) { - makeListenable(future.getValue(), exec).addListener(new Runnable() { - public void run() { - try { - future.getValue().get(); - complete.incrementAndGet(); - } catch (Exception e) { - errors.incrementAndGet(); - logException(logger, logPrefix, total, complete.get(), errors.get(), start, e); - errorMap.put(future.getKey(), e); - } - doneSignal.countDown(); - } - }, exec); - } - try { - if (maxTime != null) - doneSignal.await(maxTime, TimeUnit.MILLISECONDS); - else - doneSignal.await(); - if (errors.get() > 0) { - String message = message(logPrefix, total, complete.get(), errors.get(), start); - RuntimeException exception = new RuntimeException(message); - logger.error(exception, message); - } - if (logger.isTraceEnabled()) { - String message = message(logPrefix, total, complete.get(), errors.get(), start); - logger.trace(message); - } - } catch (InterruptedException e) { - String message = message(logPrefix, total, complete.get(), errors.get(), start); - TimeoutException exception = new TimeoutException(message); - logger.error(exception, message); - Throwables.propagate(exception); - } - return errorMap; - } - - public static Iterable unwrap(Iterable> values) { - return Iterables.transform(values, new Function, T>() { - @Override - public T apply(Future from) { - try { - return from.get(); - } catch (InterruptedException e) { - Throwables.propagate(e); - } catch (ExecutionException e) { - Throwables.propagate(e); - } - return null; - } - }); - } - - private static void logException(Logger logger, String logPrefix, int total, int complete, int errors, long start, - Exception e) { - String message = message(logPrefix, total, complete, errors, start); - logger.error(e, message); - } - - private static String message(String prefix, int size, int complete, int errors, long start) { - return String.format("%s, completed: %d/%d, errors: %d, rate: %dms/op", prefix, complete, size, errors, - (long) ((System.currentTimeMillis() - start) / ((double) size))); - } - - protected static boolean timeOut(long start, Long maxTime) { - return maxTime != null ? System.currentTimeMillis() < start + maxTime : false; - } - - /** - * Just like {@code Futures#makeListenable} except that we pass in an executorService. - *

- * Temporary hack until http://code.google.com/p/guava-libraries/issues/detail?id=317 is fixed. - */ - public static ListenableFuture makeListenable(Future future, ExecutorService executorService) { - if (future instanceof ListenableFuture) { - return (ListenableFuture) future; - } - return ListenableFutureAdapter.create(future, executorService); - } - - /** - * Just like {@code Futures#compose} except that we check the type of the executorService before - * creating the Future. If we are single threaded, invoke the function lazy as opposed to - * chaining, so that we don't invoke get() early. - */ - public static ListenableFuture compose(Future future, final Function function, - ExecutorService executorService) { - if (future instanceof ListenableFutureAdapter) { - ListenableFutureAdapter lf = (ListenableFutureAdapter) future; - if (lf.futureListener.executor.getClass().isAnnotationPresent(SingleThreaded.class)) - return LazyListenableFutureFunctionAdapter.create(((ListenableFutureAdapter) future).futureListener, - function); - else - return Futures.compose(lf, function, executorService); - } else if (executorService.getClass().isAnnotationPresent(SingleThreaded.class)) { - return LazyListenableFutureFunctionAdapter.create(future, function, executorService); - } else { - return Futures.compose(makeListenable(future, executorService), function, executorService); - } - } - - public static class FutureListener { - private final Future future; - private final ExecutorService executor; - private final ExecutionList executionList = new ExecutionList(); - private final AtomicBoolean hasListeners = new AtomicBoolean(false); - - static FutureListener create(Future future, ExecutorService executor) { - return new FutureListener(future, executor); - } - - private FutureListener(Future future, ExecutorService executor) { - this.future = checkNotNull(future, "future"); - this.executor = checkNotNull(executor, "executor"); - } - - public void addListener(Runnable listener, Executor exec) { - - // When a listener is first added, we run a task that will wait for - // the future to finish, and when it is done will run the listeners. - if (!hasListeners.get() && hasListeners.compareAndSet(false, true)) { - executor.execute(new Runnable() { - /* @Override */ - public void run() { - try { - future.get(); - } catch (CancellationException e) { - // The task was cancelled, so it is done, run the listeners. - } catch (InterruptedException e) { - // This thread was interrupted. This should never happen, so we - // throw an IllegalStateException. - throw new IllegalStateException("Adapter thread interrupted!", e); - } catch (ExecutionException e) { - // The task caused an exception, so it is done, run the listeners. - } - executionList.run(); - } - }); - } - executionList.add(listener, exec); - } - - Future getFuture() { - return future; - } - - ExecutorService getExecutor() { - return executor; - } - } - - public static class ListenableFutureAdapter extends ForwardingFuture implements ListenableFuture { - private final FutureListener futureListener; - - static ListenableFutureAdapter create(Future future, ExecutorService executor) { - return new ListenableFutureAdapter(future, executor); - } - - private ListenableFutureAdapter(Future future, ExecutorService executor) { - this.futureListener = FutureListener.create(future, executor); - } - - @Override - protected Future delegate() { - return futureListener.getFuture(); - } - - @Override - public void addListener(Runnable listener, Executor exec) { - futureListener.addListener(listener, exec); - } - - } - - public static class LazyListenableFutureFunctionAdapter extends ForwardingObject implements - ListenableFuture { - private final FutureListener futureListener; - private final Function function; - - static LazyListenableFutureFunctionAdapter create(Future future, - Function function, ExecutorService executor) { - return new LazyListenableFutureFunctionAdapter(future, function, executor); - } - - static LazyListenableFutureFunctionAdapter create(FutureListener futureListener, - Function function) { - return new LazyListenableFutureFunctionAdapter(futureListener, function); - } - - private LazyListenableFutureFunctionAdapter(Future future, Function function, - ExecutorService executor) { - this(FutureListener.create(future, executor), function); - } - - private LazyListenableFutureFunctionAdapter(FutureListener futureListener, - Function function) { - this.futureListener = checkNotNull(futureListener, "futureListener"); - this.function = checkNotNull(function, "function"); - } - - /* - * Concurrency detail: - * - *

To preserve the idempotency of calls to this.get(*) calls to the function are only - * applied once. A lock is required to prevent multiple applications of the function. The - * calls to future.get(*) are performed outside the lock, as is required to prevent calls to - * get(long, TimeUnit) to persist beyond their timeout. - * - *

Calls to future.get(*) on every call to this.get(*) also provide the cancellation - * behavior for this. - * - *

(Consider: in thread A, call get(), in thread B call get(long, TimeUnit). Thread B may - * have to wait for Thread A to finish, which would be unacceptable.) - * - *

Note that each call to Future.get(*) results in a call to Future.get(*), but the - * function is only applied once, so Future.get(*) is assumed to be idempotent. - */ - - private final Object lock = new Object(); - private boolean set = false; - private O value = null; - - @Override - public O get() throws InterruptedException, ExecutionException { - return apply(futureListener.getFuture().get()); - } - - @Override - public O get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException { - return apply(futureListener.getFuture().get(timeout, unit)); - } - - private O apply(I raw) { - synchronized (lock) { - if (!set) { - value = function.apply(raw); - set = true; - } - return value; - } - } - - @Override - public boolean cancel(boolean mayInterruptIfRunning) { - return futureListener.getFuture().cancel(mayInterruptIfRunning); - } - - @Override - public boolean isCancelled() { - return futureListener.getFuture().isCancelled(); - } - - @Override - public boolean isDone() { - return futureListener.getFuture().isDone(); - } - - @Override - public void addListener(Runnable listener, Executor exec) { - futureListener.addListener(listener, exec); - } - - @Override - protected Object delegate() { - return futureListener.getFuture(); - } - - } - - /** - * Taken from {@link MoreExecutors#sameThreadExecutor} as it was hidden and therefore incapable - * of instanceof checks. - * - * - * - * Creates an executor service that runs each task in the thread that invokes {@code - * execute/submit}, as in {@link CallerRunsPolicy} This applies both to individually submitted - * tasks and to collections of tasks submitted via {@code invokeAll} or {@code invokeAny}. In the - * latter case, tasks will run serially on the calling thread. Tasks are run to completion before - * a {@code Future} is returned to the caller (unless the executor has been shutdown). - * - *

- * Although all tasks are immediately executed in the thread that submitted the task, this - * {@code ExecutorService} imposes a small locking overhead on each task submission in order to - * implement shutdown and termination behavior. - * - *

- * The implementation deviates from the {@code ExecutorService} specification with regards to the - * {@code shutdownNow} method. First, "best-effort" with regards to canceling running tasks is - * implemented as "no-effort". No interrupts or other attempts are made to stop threads executing - * tasks. Second, the returned list will always be empty, as any submitted task is considered to - * have started execution. This applies also to tasks given to {@code invokeAll} or {@code - * invokeAny} which are pending serial execution, even the subset of the tasks that have not yet - * started execution. It is unclear from the {@code ExecutorService} specification if these - * should be included, and it's much easier to implement the interpretation that they not be. - * Finally, a call to {@code shutdown} or {@code shutdownNow} may result in concurrent calls to - * {@code invokeAll/invokeAny} throwing RejectedExecutionException, although a subset of the - * tasks may already have been executed. - */ - public static ExecutorService sameThreadExecutor() { - return new SameThreadExecutorService(); - } - - // See sameThreadExecutor javadoc for behavioral notes. - @SingleThreaded - public static class SameThreadExecutorService extends AbstractExecutorService { - /** - * Lock used whenever accessing the state variables (runningTasks, shutdown, - * terminationCondition) of the executor - */ - private final Lock lock = new ReentrantLock(); - - /** Signaled after the executor is shutdown and running tasks are done */ - private final Condition termination = lock.newCondition(); - - private SameThreadExecutorService() { - } - - /* - * Conceptually, these two variables describe the executor being in one of three states: - - * Active: shutdown == false - Shutdown: runningTasks > 0 and shutdown == true - Terminated: - * runningTasks == 0 and shutdown == true - */ - private int runningTasks = 0; - private boolean shutdown = false; - - @Override - public void execute(Runnable command) { - startTask(); - try { - command.run(); - } finally { - endTask(); - } - } - - @Override - public boolean isShutdown() { - lock.lock(); - try { - return shutdown; - } finally { - lock.unlock(); - } - } - - @Override - public void shutdown() { - lock.lock(); - try { - shutdown = true; - } finally { - lock.unlock(); - } - } - - // See sameThreadExecutor javadoc for unusual behavior of this method. - @Override - public List shutdownNow() { - shutdown(); - return Collections.emptyList(); - } - - @Override - public boolean isTerminated() { - lock.lock(); - try { - return shutdown && runningTasks == 0; - } finally { - lock.unlock(); - } - } - - @Override - public boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException { - long nanos = unit.toNanos(timeout); - lock.lock(); - try { - for (;;) { - if (isTerminated()) { - return true; - } else if (nanos <= 0) { - return false; - } else { - nanos = termination.awaitNanos(nanos); - } - } - } finally { - lock.unlock(); - } - } - - /** - * Checks if the executor has been shut down and increments the running task count. - * - * @throws RejectedExecutionException - * if the executor has been previously shutdown - */ - private void startTask() { - lock.lock(); - try { - if (isShutdown()) { - throw new RejectedExecutionException("Executor already shutdown"); - } - runningTasks++; - } finally { - lock.unlock(); - } - } - - /** - * Decrements the running task count. - */ - private void endTask() { - lock.lock(); - try { - runningTasks--; - if (isTerminated()) { - termination.signalAll(); - } - } finally { - lock.unlock(); - } - } - } - -} \ No newline at end of file diff --git a/core/src/main/java/org/jclouds/concurrent/FutureIterables.java b/core/src/main/java/org/jclouds/concurrent/FutureIterables.java new file mode 100644 index 0000000000..25f078b936 --- /dev/null +++ b/core/src/main/java/org/jclouds/concurrent/FutureIterables.java @@ -0,0 +1,185 @@ +/** + * + * Copyright (C) 2009 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ==================================================================== + */ +package org.jclouds.concurrent; + +import static com.google.common.collect.Maps.newHashMap; + +import java.util.Map; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import java.util.concurrent.atomic.AtomicInteger; + +import javax.annotation.Nullable; +import javax.annotation.Resource; +import javax.inject.Named; + +import org.jclouds.Constants; +import org.jclouds.http.handlers.BackoffLimitedRetryHandler; +import org.jclouds.logging.Logger; + +import com.google.common.annotations.Beta; +import com.google.common.base.Function; +import com.google.common.base.Throwables; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Iterables; +import com.google.common.collect.Maps; +import com.google.inject.Inject; + +/** + * functions related to or replacing those in {@link com.google.common.collect.Iterables} dealing with Futures + * + * @author Adrian Cole + */ +@Beta +public class FutureIterables { + @Resource + private static Logger logger = Logger.CONSOLE; + + @Inject(optional = true) + @Named(Constants.PROPERTY_MAX_RETRIES) + private static int maxRetries = 5; + + @Inject(optional = true) + private static BackoffLimitedRetryHandler retryHandler = BackoffLimitedRetryHandler.INSTANCE; + + public static Iterable transformParallel(final Iterable fromIterable, + final Function> function) { + return transformParallel(fromIterable, function, org.jclouds.concurrent.MoreExecutors.sameThreadExecutor(), null); + } + + public static Iterable transformParallel(final Iterable fromIterable, + final Function> function, ExecutorService exec, @Nullable Long maxTime) { + return transformParallel(fromIterable, function, exec, maxTime, logger, "transforming"); + } + + public static Iterable transformParallel(final Iterable fromIterable, + final Function> function, ExecutorService exec, @Nullable Long maxTime, Logger logger, + String logPrefix) { + return transformParallel(fromIterable, function, exec, maxTime, logger, logPrefix, retryHandler, maxRetries); + } + + public static Iterable transformParallel(Iterable fromIterable, + Function> function, ExecutorService exec, @Nullable Long maxTime, Logger logger, + String logPrefix, BackoffLimitedRetryHandler retryHandler, int maxRetries) { + Map exceptions = newHashMap(); + Map> responses = newHashMap(); + for (int i = 0; i < maxRetries; i++) { + + for (F from : fromIterable) { + responses.put(from, function.apply(from)); + } + exceptions = awaitCompletion(responses, exec, maxTime, logger, logPrefix); + if (exceptions.size() > 0) { + fromIterable = exceptions.keySet(); + retryHandler.imposeBackoffExponentialDelay(i + 1, String.format("error %s: %s: %s", logPrefix, + fromIterable, exceptions)); + } else { + break; + } + } + if (exceptions.size() > 0) + throw new RuntimeException(String.format("error %s: %s: %s", logPrefix, fromIterable, exceptions)); + + return unwrap(responses.values()); + } + + public static Map awaitCompletion(Map> responses, ExecutorService exec, + @Nullable Long maxTime, final Logger logger, final String logPrefix) { + if (responses.size() == 0) + return ImmutableMap.of(); + final int total = responses.size(); + final CountDownLatch doneSignal = new CountDownLatch(total); + final AtomicInteger complete = new AtomicInteger(0); + final AtomicInteger errors = new AtomicInteger(0); + final long start = System.currentTimeMillis(); + final Map errorMap = Maps.newHashMap(); + for (final java.util.Map.Entry> future : responses.entrySet()) { + Futures.makeListenable(future.getValue(), exec).addListener(new Runnable() { + public void run() { + try { + future.getValue().get(); + complete.incrementAndGet(); + } catch (Exception e) { + errors.incrementAndGet(); + logException(logger, logPrefix, total, complete.get(), errors.get(), start, e); + errorMap.put(future.getKey(), e); + } + doneSignal.countDown(); + } + }, exec); + } + try { + if (maxTime != null) + doneSignal.await(maxTime, TimeUnit.MILLISECONDS); + else + doneSignal.await(); + if (errors.get() > 0) { + String message = message(logPrefix, total, complete.get(), errors.get(), start); + RuntimeException exception = new RuntimeException(message); + logger.error(exception, message); + } + if (logger.isTraceEnabled()) { + String message = message(logPrefix, total, complete.get(), errors.get(), start); + logger.trace(message); + } + } catch (InterruptedException e) { + String message = message(logPrefix, total, complete.get(), errors.get(), start); + TimeoutException exception = new TimeoutException(message); + logger.error(exception, message); + Throwables.propagate(exception); + } + return errorMap; + } + + public static Iterable unwrap(Iterable> values) { + return Iterables.transform(values, new Function, T>() { + @Override + public T apply(Future from) { + try { + return from.get(); + } catch (InterruptedException e) { + Throwables.propagate(e); + } catch (ExecutionException e) { + Throwables.propagate(e); + } + return null; + } + }); + } + + private static void logException(Logger logger, String logPrefix, int total, int complete, int errors, long start, + Exception e) { + String message = message(logPrefix, total, complete, errors, start); + logger.error(e, message); + } + + private static String message(String prefix, int size, int complete, int errors, long start) { + return String.format("%s, completed: %d/%d, errors: %d, rate: %dms/op", prefix, complete, size, errors, + (long) ((System.currentTimeMillis() - start) / ((double) size))); + } + + protected static boolean timeOut(long start, Long maxTime) { + return maxTime != null ? System.currentTimeMillis() < start + maxTime : false; + } + +} \ No newline at end of file diff --git a/core/src/main/java/org/jclouds/concurrent/Futures.java b/core/src/main/java/org/jclouds/concurrent/Futures.java new file mode 100644 index 0000000000..2f2f3d93fd --- /dev/null +++ b/core/src/main/java/org/jclouds/concurrent/Futures.java @@ -0,0 +1,248 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ==================================================================== + */ +package org.jclouds.concurrent; + +import static com.google.common.base.Preconditions.checkNotNull; + +import java.util.concurrent.CancellationException; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Executor; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import java.util.concurrent.atomic.AtomicBoolean; + +import com.google.common.annotations.Beta; +import com.google.common.base.Function; +import com.google.common.collect.ForwardingObject; +import com.google.common.util.concurrent.ExecutionList; +import com.google.common.util.concurrent.ForwardingFuture; +import com.google.common.util.concurrent.ListenableFuture; + +/** + * functions related to or replacing those in {@link com.google.common.util.concurrent.Futures} + * + * @author Adrian Cole + */ +@Beta +public class Futures { + + public static class FutureListener { + private final Future future; + final ExecutorService executor; + private final ExecutionList executionList = new ExecutionList(); + private final AtomicBoolean hasListeners = new AtomicBoolean(false); + + static FutureListener create(Future future, ExecutorService executor) { + return new FutureListener(future, executor); + } + + private FutureListener(Future future, ExecutorService executor) { + this.future = checkNotNull(future, "future"); + this.executor = checkNotNull(executor, "executor"); + } + + public void addListener(Runnable listener, Executor exec) { + + // When a listener is first added, we run a task that will wait for + // the future to finish, and when it is done will run the listeners. + if (!hasListeners.get() && hasListeners.compareAndSet(false, true)) { + executor.execute(new Runnable() { + /* @Override */ + public void run() { + try { + future.get(); + } catch (CancellationException e) { + // The task was cancelled, so it is done, run the listeners. + } catch (InterruptedException e) { + // This thread was interrupted. This should never happen, so we + // throw an IllegalStateException. + throw new IllegalStateException("Adapter thread interrupted!", e); + } catch (ExecutionException e) { + // The task caused an exception, so it is done, run the listeners. + } + executionList.run(); + } + }); + } + executionList.add(listener, exec); + } + + Future getFuture() { + return future; + } + + ExecutorService getExecutor() { + return executor; + } + } + + public static class ListenableFutureAdapter extends ForwardingFuture implements ListenableFuture { + final FutureListener futureListener; + + static ListenableFutureAdapter create(Future future, ExecutorService executor) { + return new ListenableFutureAdapter(future, executor); + } + + private ListenableFutureAdapter(Future future, ExecutorService executor) { + this.futureListener = FutureListener.create(future, executor); + } + + @Override + protected Future delegate() { + return futureListener.getFuture(); + } + + @Override + public void addListener(Runnable listener, Executor exec) { + futureListener.addListener(listener, exec); + } + + } + + public static class LazyListenableFutureFunctionAdapter extends ForwardingObject implements + ListenableFuture { + private final FutureListener futureListener; + private final Function function; + + static LazyListenableFutureFunctionAdapter create(Future future, + Function function, ExecutorService executor) { + return new LazyListenableFutureFunctionAdapter(future, function, executor); + } + + static LazyListenableFutureFunctionAdapter create(FutureListener futureListener, + Function function) { + return new LazyListenableFutureFunctionAdapter(futureListener, function); + } + + private LazyListenableFutureFunctionAdapter(Future future, Function function, + ExecutorService executor) { + this(FutureListener.create(future, executor), function); + } + + private LazyListenableFutureFunctionAdapter(FutureListener futureListener, + Function function) { + this.futureListener = checkNotNull(futureListener, "futureListener"); + this.function = checkNotNull(function, "function"); + } + + /* + * Concurrency detail: + * + *

To preserve the idempotency of calls to this.get(*) calls to the function are only + * applied once. A lock is required to prevent multiple applications of the function. The + * calls to future.get(*) are performed outside the lock, as is required to prevent calls to + * get(long, TimeUnit) to persist beyond their timeout. + * + *

Calls to future.get(*) on every call to this.get(*) also provide the cancellation + * behavior for this. + * + *

(Consider: in thread A, call get(), in thread B call get(long, TimeUnit). Thread B may + * have to wait for Thread A to finish, which would be unacceptable.) + * + *

Note that each call to Future.get(*) results in a call to Future.get(*), but the + * function is only applied once, so Future.get(*) is assumed to be idempotent. + */ + + private final Object lock = new Object(); + private boolean set = false; + private O value = null; + + @Override + public O get() throws InterruptedException, ExecutionException { + return apply(futureListener.getFuture().get()); + } + + @Override + public O get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException { + return apply(futureListener.getFuture().get(timeout, unit)); + } + + private O apply(I raw) { + synchronized (lock) { + if (!set) { + value = function.apply(raw); + set = true; + } + return value; + } + } + + @Override + public boolean cancel(boolean mayInterruptIfRunning) { + return futureListener.getFuture().cancel(mayInterruptIfRunning); + } + + @Override + public boolean isCancelled() { + return futureListener.getFuture().isCancelled(); + } + + @Override + public boolean isDone() { + return futureListener.getFuture().isDone(); + } + + @Override + public void addListener(Runnable listener, Executor exec) { + futureListener.addListener(listener, exec); + } + + @Override + protected Object delegate() { + return futureListener.getFuture(); + } + + } + + /** + * Just like {@code Futures#compose} except that we check the type of the executorService before + * creating the Future. If we are single threaded, invoke the function lazy as opposed to + * chaining, so that we don't invoke get() early. + */ + public static ListenableFuture compose(Future future, final Function function, + ExecutorService executorService) { + if (future instanceof Futures.ListenableFutureAdapter) { + Futures.ListenableFutureAdapter lf = (ListenableFutureAdapter) future; + if (lf.futureListener.executor.getClass().isAnnotationPresent(SingleThreaded.class)) + return Futures.LazyListenableFutureFunctionAdapter.create( + ((org.jclouds.concurrent.Futures.ListenableFutureAdapter) future).futureListener, function); + else + return com.google.common.util.concurrent.Futures.compose(lf, function, executorService); + } else if (executorService.getClass().isAnnotationPresent(SingleThreaded.class)) { + return Futures.LazyListenableFutureFunctionAdapter.create(future, function, executorService); + } else { + return com.google.common.util.concurrent.Futures.compose(Futures.makeListenable(future, executorService), function, executorService); + } + } + + /** + * Just like {@code Futures#makeListenable} except that we pass in an executorService. + *

+ * Temporary hack until http://code.google.com/p/guava-libraries/issues/detail?id=317 is fixed. + */ + public static ListenableFuture makeListenable(Future future, ExecutorService executorService) { + if (future instanceof ListenableFuture) { + return (ListenableFuture) future; + } + return ListenableFutureAdapter.create(future, executorService); + } + +} diff --git a/core/src/main/java/org/jclouds/concurrent/MoreExecutors.java b/core/src/main/java/org/jclouds/concurrent/MoreExecutors.java new file mode 100644 index 0000000000..0a4fea5214 --- /dev/null +++ b/core/src/main/java/org/jclouds/concurrent/MoreExecutors.java @@ -0,0 +1,199 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ==================================================================== + */ +package org.jclouds.concurrent; + +import java.util.Collections; +import java.util.List; +import java.util.concurrent.AbstractExecutorService; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.RejectedExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.ThreadPoolExecutor.CallerRunsPolicy; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + +import com.google.common.annotations.Beta; + +/** + * functions related to or replacing those in + * {@link com.google.common.util.concurrent.MoreExecutors} + * + * @author Adrian Cole + */ +@Beta +public class MoreExecutors { + + /** + * Taken from @link com.google.common.util.concurrent.MoreExecutors} as it was hidden and + * therefore incapable of instanceof checks. + * + * + * Creates an executor service that runs each task in the thread that invokes {@code + * execute/submit}, as in {@link CallerRunsPolicy} This applies both to individually submitted + * tasks and to collections of tasks submitted via {@code invokeAll} or {@code invokeAny}. In the + * latter case, tasks will run serially on the calling thread. Tasks are run to completion before + * a {@code Future} is returned to the caller (unless the executor has been shutdown). + * + *

+ * Although all tasks are immediately executed in the thread that submitted the task, this + * {@code ExecutorService} imposes a small locking overhead on each task submission in order to + * implement shutdown and termination behavior. + * + *

+ * The implementation deviates from the {@code ExecutorService} specification with regards to the + * {@code shutdownNow} method. First, "best-effort" with regards to canceling running tasks is + * implemented as "no-effort". No interrupts or other attempts are made to stop threads executing + * tasks. Second, the returned list will always be empty, as any submitted task is considered to + * have started execution. This applies also to tasks given to {@code invokeAll} or {@code + * invokeAny} which are pending serial execution, even the subset of the tasks that have not yet + * started execution. It is unclear from the {@code ExecutorService} specification if these + * should be included, and it's much easier to implement the interpretation that they not be. + * Finally, a call to {@code shutdown} or {@code shutdownNow} may result in concurrent calls to + * {@code invokeAll/invokeAny} throwing RejectedExecutionException, although a subset of the + * tasks may already have been executed. + */ + public static ExecutorService sameThreadExecutor() { + return new SameThreadExecutorService(); + } + + // See sameThreadExecutor javadoc for behavioral notes. + @SingleThreaded + public static class SameThreadExecutorService extends AbstractExecutorService { + /** + * Lock used whenever accessing the state variables (runningTasks, shutdown, + * terminationCondition) of the executor + */ + private final Lock lock = new ReentrantLock(); + + /** Signaled after the executor is shutdown and running tasks are done */ + private final Condition termination = lock.newCondition(); + + private SameThreadExecutorService() { + } + + /* + * Conceptually, these two variables describe the executor being in one of three states: - + * Active: shutdown == false - Shutdown: runningTasks > 0 and shutdown == true - Terminated: + * runningTasks == 0 and shutdown == true + */ + private int runningTasks = 0; + private boolean shutdown = false; + + @Override + public void execute(Runnable command) { + startTask(); + try { + command.run(); + } finally { + endTask(); + } + } + + @Override + public boolean isShutdown() { + lock.lock(); + try { + return shutdown; + } finally { + lock.unlock(); + } + } + + @Override + public void shutdown() { + lock.lock(); + try { + shutdown = true; + } finally { + lock.unlock(); + } + } + + // See sameThreadExecutor javadoc for unusual behavior of this method. + @Override + public List shutdownNow() { + shutdown(); + return Collections.emptyList(); + } + + @Override + public boolean isTerminated() { + lock.lock(); + try { + return shutdown && runningTasks == 0; + } finally { + lock.unlock(); + } + } + + @Override + public boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException { + long nanos = unit.toNanos(timeout); + lock.lock(); + try { + for (;;) { + if (isTerminated()) { + return true; + } else if (nanos <= 0) { + return false; + } else { + nanos = termination.awaitNanos(nanos); + } + } + } finally { + lock.unlock(); + } + } + + /** + * Checks if the executor has been shut down and increments the running task count. + * + * @throws RejectedExecutionException + * if the executor has been previously shutdown + */ + private void startTask() { + lock.lock(); + try { + if (isShutdown()) { + throw new RejectedExecutionException("Executor already shutdown"); + } + runningTasks++; + } finally { + lock.unlock(); + } + } + + /** + * Decrements the running task count. + */ + private void endTask() { + lock.lock(); + try { + runningTasks--; + if (isTerminated()) { + termination.signalAll(); + } + } finally { + lock.unlock(); + } + } + } + +} diff --git a/core/src/main/java/org/jclouds/concurrent/config/ExecutorServiceModule.java b/core/src/main/java/org/jclouds/concurrent/config/ExecutorServiceModule.java index 6a7decf723..aafc234d2a 100644 --- a/core/src/main/java/org/jclouds/concurrent/config/ExecutorServiceModule.java +++ b/core/src/main/java/org/jclouds/concurrent/config/ExecutorServiceModule.java @@ -32,7 +32,7 @@ import javax.inject.Named; import javax.inject.Singleton; import org.jclouds.Constants; -import static org.jclouds.concurrent.ConcurrentUtils.*; +import org.jclouds.concurrent.MoreExecutors; import org.jclouds.concurrent.SingleThreaded; import org.jclouds.lifecycle.Closer; import org.jclouds.logging.Logger; @@ -87,8 +87,8 @@ public class ExecutorServiceModule extends AbstractModule { && executor.getClass().getSimpleName().indexOf("SameThread") != -1) { Logger.CONSOLE.warn( "please switch from %s to %s or annotate your same threaded executor with @SingleThreaded", executor - .getClass().getName(), SameThreadExecutorService.class.getName()); - return sameThreadExecutor(); + .getClass().getName(), MoreExecutors.SameThreadExecutorService.class.getName()); + return MoreExecutors.sameThreadExecutor(); } return executor; } diff --git a/core/src/main/java/org/jclouds/crypto/Crypto.java b/core/src/main/java/org/jclouds/crypto/Crypto.java new file mode 100644 index 0000000000..8ef3fffea1 --- /dev/null +++ b/core/src/main/java/org/jclouds/crypto/Crypto.java @@ -0,0 +1,60 @@ +/** + * + * Copyright (C) 2009 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ==================================================================== + */ +package org.jclouds.crypto; + +import java.security.InvalidKeyException; +import java.security.KeyFactory; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.security.cert.CertificateFactory; + +import javax.crypto.Mac; + +import org.jclouds.encryption.internal.JCECrypto; + +import com.google.inject.ImplementedBy; + +/** + * Allows you to access cryptographic objects and factories without adding a provider to the JCE + * runtime. + * + * @author Adrian Cole + */ +@ImplementedBy(JCECrypto.class) +public interface Crypto { + + KeyFactory rsaKeyFactory(); + + CertificateFactory certFactory(); + + Mac hmac(String algorithm, byte[] key) throws NoSuchAlgorithmException, InvalidKeyException; + + Mac hmacSHA256(byte[] key) throws InvalidKeyException; + + Mac hmacSHA1(byte[] key) throws InvalidKeyException; + + MessageDigest digest(String algorithm) throws NoSuchAlgorithmException; + + MessageDigest md5(); + + MessageDigest sha1(); + + MessageDigest sha256(); + +} \ No newline at end of file diff --git a/core/src/main/java/org/jclouds/crypto/CryptoStreams.java b/core/src/main/java/org/jclouds/crypto/CryptoStreams.java new file mode 100644 index 0000000000..36d4361847 --- /dev/null +++ b/core/src/main/java/org/jclouds/crypto/CryptoStreams.java @@ -0,0 +1,318 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ==================================================================== + */ +package org.jclouds.crypto; + +import static com.google.common.base.Preconditions.checkNotNull; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.UnsupportedEncodingException; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.Arrays; + +import javax.crypto.Mac; + +import org.jclouds.encryption.internal.Base64; +import org.jclouds.io.InputSuppliers; + +import com.google.common.annotations.Beta; +import com.google.common.base.Charsets; +import com.google.common.base.Throwables; +import com.google.common.io.ByteProcessor; +import com.google.common.io.ByteStreams; +import com.google.common.io.InputSupplier; + +/** + * functions related to but not in {@link com.google.common.io.ByteStreams} + * + * @author Adrian Cole + */ +@Beta +public class CryptoStreams { + + public static String hex(byte[] in) { + byte[] hex = new byte[2 * in.length]; + int index = 0; + + for (byte b : in) { + int v = b & 0xFF; + hex[index++] = HEX_CHAR_TABLE[v >>> 4]; + hex[index++] = HEX_CHAR_TABLE[v & 0xF]; + } + try { + return new String(hex, "ASCII"); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException(e); + } + } + + public static byte[] hex(String s) { + int len = s.length(); + byte[] data = new byte[len / 2]; + for (int i = 0; i < len; i += 2) { + data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) + Character.digit(s.charAt(i + 1), 16)); + } + return data; + } + + public static String base64(byte[] in) { + return Base64.encodeBytes(in, Base64.DONT_BREAK_LINES); + } + + public static byte[] base64(String in) { + return Base64.decode(in); + } + + /** + * @see #md5 + * @see #hex + */ + public static String md5Hex(InputSupplier supplier) throws IOException { + return hex(md5(supplier)); + } + + /** + * @see #md5 + * @see #base64 + */ + public static String md5Base64(InputSupplier supplier) throws IOException { + return base64(md5(supplier)); + } + + /** + * Computes and returns the MAC value for a supplied input stream. The mac object is reset when + * this method returns successfully. + * + * @param supplier + * the input stream factory + * @param mac + * the mac object + * @return the result of {@link Mac#doFinal()} after updating the mac object with all of the + * bytes in the stream and encoding in Base64 + * @throws IOException + * if an I/O error occurs + */ + public static String macBase64(InputSupplier supplier, final Mac mac) throws IOException { + return base64(mac(supplier, mac)); + } + + /** + * Computes and returns the Digest value for a supplied input stream. The digest object is reset + * when this method returns successfully. + * + * @param supplier + * the input stream factory + * @param md + * the digest object + * @return the result of {@link MessageDigest#digest()} after updating the digest object with all + * of the bytes in the stream + * @throws IOException + * if an I/O error occurs + */ + public static byte[] digest(InputSupplier supplier, final MessageDigest md) + throws IOException { + return com.google.common.io.ByteStreams.readBytes(supplier, new ByteProcessor() { + public boolean processBytes(byte[] buf, int off, int len) { + md.update(buf, off, len); + return true; + } + + public byte[] getResult() { + return md.digest(); + } + }); + } + + /** + * Computes and returns the MD5 value for a supplied input stream. A digest object is created and + * disposed of at runtime, consider using {@link #digest} to be more efficient. + * + * @param supplier + * the input stream factory + * + * @return the result of {@link MessageDigest#digest()} after updating the md5 object with all of + * the bytes in the stream + * @throws IOException + * if an I/O error occurs + */ + public static byte[] md5(InputSupplier supplier) throws IOException { + try { + return digest(supplier, MessageDigest.getInstance("MD5")); + } catch (NoSuchAlgorithmException e) { + Throwables.propagate(e); + return null; + } + } + + public static byte[] md5(byte[] in) throws IOException { + return md5(ByteStreams.newInputStreamSupplier(in)); + } + + /** + * Computes and returns the MAC value for a supplied input stream. The mac object is reset when + * this method returns successfully. + * + * @param supplier + * the input stream factory + * @param mac + * the mac object + * @return the result of {@link Mac#doFinal()} after updating the mac object with all of the + * bytes in the stream + * @throws IOException + * if an I/O error occurs + */ + public static byte[] mac(InputSupplier supplier, final Mac mac) throws IOException { + return com.google.common.io.ByteStreams.readBytes(checkNotNull(supplier, "supplier"), + new ByteProcessor() { + public boolean processBytes(byte[] buf, int off, int len) { + mac.update(buf, off, len); + return true; + } + + public byte[] getResult() { + return mac.doFinal(); + } + }); + } + + /** + * Computes and returns the base64 value for a supplied input stream. + * + * @param supplier + * the input stream factory + * + * @return the result of base 64 encoding all of the bytes in the stream + * @throws IOException + * if an I/O error occurs + */ + public static String base64Encode(InputSupplier supplier) throws IOException { + final ByteArrayOutputStream out = new ByteArrayOutputStream(); + return com.google.common.io.ByteStreams.readBytes(InputSuppliers.base64Encoder(supplier), + new ByteProcessor() { + public boolean processBytes(byte[] buf, int off, int len) { + out.write(buf, off, len); + return true; + } + + public String getResult() { + return new String(out.toByteArray(), Charsets.UTF_8); + } + }); + } + + /** + * Computes and returns the unencoded value for an input stream which is encoded in Base64. + * + * @param supplier + * the input stream factory + * + * @return the result of base 64 decoding all of the bytes in the stream + * @throws IOException + * if an I/O error occurs + */ + public static byte[] base64Decode(InputSupplier supplier) throws IOException { + final ByteArrayOutputStream out = new ByteArrayOutputStream(); + return com.google.common.io.ByteStreams.readBytes(InputSuppliers.base64Decoder(supplier), + new ByteProcessor() { + public boolean processBytes(byte[] buf, int off, int len) { + out.write(buf, off, len); + return true; + } + + public byte[] getResult() { + return out.toByteArray(); + } + }); + } + + final static byte[] HEX_CHAR_TABLE = { (byte) '0', (byte) '1', (byte) '2', (byte) '3', (byte) '4', (byte) '5', + (byte) '6', (byte) '7', (byte) '8', (byte) '9', (byte) 'a', (byte) 'b', (byte) 'c', (byte) 'd', (byte) 'e', + (byte) 'f' }; + + /** + * Computes and returns the hex value for a supplied input stream. + * + * @param supplier + * the input stream factory + * + * @return the result of hex encoding all of the bytes in the stream + * @throws IOException + * if an I/O error occurs + */ + public static String hexEncode(InputSupplier supplier) throws IOException { + final StringBuilder out = new StringBuilder(); + return com.google.common.io.ByteStreams.readBytes(supplier, new ByteProcessor() { + public boolean processBytes(byte[] buf, int off, int len) { + char[] hex = new char[2 * len]; + int index = 0; + + for (int i = off; i < off + len; i++) { + byte b = buf[i]; + int v = b & 0xFF; + hex[index++] = (char) HEX_CHAR_TABLE[v >>> 4]; + hex[index++] = (char) HEX_CHAR_TABLE[v & 0xF]; + } + out.append(hex); + return true; + } + + public String getResult() { + return out.toString(); + } + }); + } + + /** + * Computes and returns the unencoded value for an input stream which is encoded in hex. + * + * @param supplier + * the input stream factory + * + * @return the result of hex decoding all of the bytes in the stream + * @throws IOException + * if an I/O error occurs + */ + public static byte[] hexDecode(InputSupplier supplier) throws IOException { + final ByteArrayOutputStream out = new ByteArrayOutputStream(); + return com.google.common.io.ByteStreams.readBytes(supplier, new ByteProcessor() { + int currentPos = 0; + + public boolean processBytes(byte[] buf, int off, int len) { + try { + if (currentPos == 0 && new String(Arrays.copyOfRange(buf, off, 2), "ASCII").equals("0x")) { + off += 2; + } + byte[] decoded = hex(new String(Arrays.copyOfRange(buf, off, len), "ASCII")); + out.write(decoded, 0, decoded.length); + currentPos += len; + } catch (UnsupportedEncodingException e) { + throw new IllegalStateException("ASCII must be supported"); + } + return true; + } + + public byte[] getResult() { + return out.toByteArray(); + } + }); + } + +} diff --git a/core/src/main/java/org/jclouds/crypto/Pems.java b/core/src/main/java/org/jclouds/crypto/Pems.java new file mode 100644 index 0000000000..1f21140fba --- /dev/null +++ b/core/src/main/java/org/jclouds/crypto/Pems.java @@ -0,0 +1,252 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ==================================================================== + */ +package org.jclouds.crypto; + +import static com.google.common.base.Preconditions.checkNotNull; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.cert.CertificateEncodingException; +import java.security.cert.CertificateException; +import java.security.cert.CertificateFactory; +import java.security.cert.X509Certificate; +import java.security.spec.KeySpec; +import java.security.spec.PKCS8EncodedKeySpec; +import java.security.spec.RSAPrivateKeySpec; +import java.security.spec.X509EncodedKeySpec; +import java.util.Map; + +import javax.annotation.Nullable; + +import net.oauth.signature.pem.PEMReader; +import net.oauth.signature.pem.PKCS1EncodedKeySpec; + +import org.jclouds.crypto.Pems.PemProcessor.ResultParser; + +import com.google.common.annotations.Beta; +import com.google.common.collect.ImmutableMap; +import com.google.common.io.ByteProcessor; +import com.google.common.io.ByteStreams; +import com.google.common.io.InputSupplier; + +/** + * Reads and writes PEM encoded Strings and Streams + * + * @author Adrian Cole + */ +@Beta +public class Pems { + + public static class PemProcessor implements com.google.common.io.ByteProcessor { + public interface ResultParser { + T parseResult(byte[] bytes) throws IOException; + } + + private final ByteArrayOutputStream out = new ByteArrayOutputStream(); + private final Map> parsers; + + public PemProcessor(Map> parsers) { + this.parsers = checkNotNull(parsers, "parsers"); + } + + public boolean processBytes(byte[] buf, int off, int len) { + out.write(buf, off, len); + return true; + } + + public T getResult() { + try { + PEMReader reader = new PEMReader(out.toByteArray()); + byte[] bytes = reader.getDerBytes(); + if (parsers.containsKey(reader.getBeginMarker())) { + return parsers.get(reader.getBeginMarker()).parseResult(bytes); + } else { + throw new IOException(String.format("Invalid PEM file: no parsers for marker %s in %s", reader + .getBeginMarker(), parsers.keySet())); + } + } catch (IOException e) { + throw new RuntimeException(e); + } + } + } + + /** + * Returns the object of generic type {@code T} that is pem encoded in the supplier. + * + * @param supplier + * the input stream factory + * @param marker + * header that begins the PEM block + * @param processor + * how to parser the object from a byte array + * @return the object of generic type {@code T} which was PEM encoded in the stream + * @throws IOException + * if an I/O error occurs + */ + public static T fromPem(InputSupplier supplier, PemProcessor processor) + throws IOException { + try { + return com.google.common.io.ByteStreams.readBytes(supplier, processor); + } catch (RuntimeException e) { + if (e.getCause() != null && e.getCause() instanceof IOException) { + throw (IOException) e.getCause(); + } + throw e; + } + } + + /** + * Returns the {@link RSAPrivateKeySpec} that is pem encoded in the supplier. + * + * @param supplier + * the input stream factory + * + * @return the {@link RSAPrivateKeySpec} which was PEM encoded in the stream + * @throws IOException + * if an I/O error occurs + */ + public static KeySpec privateKeySpec(InputSupplier supplier) throws IOException { + return fromPem(supplier, new PemProcessor(ImmutableMap.> of( + PEMReader.PRIVATE_PKCS1_MARKER, new ResultParser() { + + public KeySpec parseResult(byte[] bytes) throws IOException { + return (new PKCS1EncodedKeySpec(bytes)).getKeySpec(); + } + + }, PEMReader.PRIVATE_PKCS8_MARKER, new ResultParser() { + + public KeySpec parseResult(byte[] bytes) throws IOException { + return new PKCS8EncodedKeySpec(bytes); + } + + }))); + } + + /** + * Returns the {@link X509EncodedKeySpec} that is pem encoded in the supplier. + * + * @param supplier + * the input stream factory + * + * @return the {@link X509EncodedKeySpec} which was PEM encoded in the stream + * @throws IOException + * if an I/O error occurs + */ + public static X509EncodedKeySpec publicKeySpec(InputSupplier supplier) throws IOException { + return fromPem(supplier, new PemProcessor(ImmutableMap + .> of(PEMReader.PUBLIC_X509_MARKER, + new ResultParser() { + + public X509EncodedKeySpec parseResult(byte[] bytes) throws IOException { + return new X509EncodedKeySpec(bytes); + } + + }))); + } + + /** + * Returns the {@link X509EncodedKeySpec} that is pem encoded in the supplier. + * + * @param supplier + * the input stream factory + * @param certFactory + * or null to use default + * + * @return the {@link X509EncodedKeySpec} which was PEM encoded in the stream + * @throws IOException + * if an I/O error occurs + * @throws CertificateException + */ + public static X509Certificate x509Certificate(InputSupplier supplier, + @Nullable CertificateFactory certFactory) throws IOException, CertificateException { + final CertificateFactory finalCertFactory = certFactory != null ? certFactory : CertificateFactory + .getInstance("X.509"); + try { + return fromPem(supplier, new PemProcessor(ImmutableMap + .> of(PEMReader.CERTIFICATE_X509_MARKER, + new ResultParser() { + + public X509Certificate parseResult(byte[] bytes) throws IOException { + try { + return (X509Certificate) finalCertFactory + .generateCertificate(new ByteArrayInputStream(bytes)); + } catch (CertificateException e) { + throw new RuntimeException(e); + } + } + + }))); + } catch (RuntimeException e) { + if (e.getCause() != null && e.getCause() instanceof CertificateException) { + throw (CertificateException) e.getCause(); + } + throw e; + } + } + + /** + * encodes the {@link X509Certificate} to PEM format. + * + * @param cert + * what to encode + * @return the PEM encoded certificate + * @throws IOException + * @throws CertificateEncodingException + */ + public static String pem(X509Certificate cert) throws IOException, CertificateEncodingException { + return new StringBuilder("-----BEGIN CERTIFICATE-----\n").append( + CryptoStreams.base64Encode(ByteStreams.newInputStreamSupplier(cert.getEncoded()))).append( + "\n-----END CERTIFICATE-----\n").toString(); + } + + /** + * encodes the {@link PublicKey} to PEM format. + * + * @param cert + * what to encode + * @return the PEM encoded public key + * @throws IOException + * @throws CertificateEncodingException + */ + public static String pem(PublicKey key) throws IOException { + return new StringBuilder("-----BEGIN PUBLIC KEY-----\n").append( + CryptoStreams.base64Encode(ByteStreams.newInputStreamSupplier(key.getEncoded()))).append( + "\n-----END PUBLIC KEY-----\n").toString(); + } + + /** + * encodes the {@link PrivateKey} to PEM format. Note + * + * @param cert + * what to encode + * @return the PEM encoded private key + * @throws IOException + * @throws CertificateEncodingException + */ + public static String pem(PrivateKey key) throws IOException { + return new StringBuilder("-----BEGIN PRIVATE KEY-----\n").append( + CryptoStreams.base64Encode(ByteStreams.newInputStreamSupplier(key.getEncoded()))).append( + "\n-----END PRIVATE KEY-----\n").toString(); + } + +} diff --git a/core/src/main/java/org/jclouds/encryption/EncryptionService.java b/core/src/main/java/org/jclouds/encryption/EncryptionService.java deleted file mode 100644 index 8dbb2d9742..0000000000 --- a/core/src/main/java/org/jclouds/encryption/EncryptionService.java +++ /dev/null @@ -1,102 +0,0 @@ -/** - * - * Copyright (C) 2009 Cloud Conscious, LLC. - * - * ==================================================================== - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ -package org.jclouds.encryption; - -import java.io.FilterOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.security.Key; -import java.security.PrivateKey; -import java.security.PublicKey; -import java.security.cert.X509Certificate; - -import org.jclouds.encryption.internal.JCEEncryptionService; -import org.jclouds.http.PayloadEnclosing; -import org.jclouds.io.Payload; -import org.jclouds.io.payloads.ByteArrayPayload; - -import com.google.inject.ImplementedBy; - -/** - * - * @author Adrian Cole - */ -@ImplementedBy(JCEEncryptionService.class) -public interface EncryptionService { - String base64(byte[] toEncode); - - byte[] fromBase64(String encoded); - - String hex(byte[] toEncode); - - byte[] fromHex(String encoded); - - byte[] rsaEncrypt(Payload payload, Key key); - - byte[] hmacSha256(String toEncode, byte[] key); - - byte[] hmacSha1(String toEncode, byte[] key); - - byte[] sha1(InputStream toEncode); - - byte[] sha256(InputStream toEncode); - - 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. - * - * @throws IOException - */ - T generateMD5BufferingIfNotRepeatable(T payloadEnclosing); - - Payload generateMD5BufferingIfNotRepeatable(Payload in); - - ByteArrayPayload generatePayloadWithMD5For(InputStream toEncode); - - MD5OutputStream md5OutputStream(OutputStream out); - - PrivateKey privateKeyFromPEM(byte[] pem); - - public static abstract class MD5OutputStream extends FilterOutputStream { - public MD5OutputStream(OutputStream out) { - super(out); - } - - public abstract byte[] getMD5(); - } - - PublicKey publicKeyFromPEM(byte[] pem); - - X509Certificate x509CertificateFromPEM(byte[] pem); - - byte[] rsaDecrypt(Payload payload, Key key); - - String toPem(X509Certificate cert); - - String toPem(PublicKey key); - - String toPem(PrivateKey key); - -} \ No newline at end of file diff --git a/core/src/main/java/org/jclouds/encryption/internal/BaseEncryptionService.java b/core/src/main/java/org/jclouds/encryption/internal/BaseEncryptionService.java deleted file mode 100755 index 9493f67363..0000000000 --- a/core/src/main/java/org/jclouds/encryption/internal/BaseEncryptionService.java +++ /dev/null @@ -1,299 +0,0 @@ -/** - * - * Copyright (C) 2009 Cloud Conscious, LLC. - * - * ==================================================================== - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ -package org.jclouds.encryption.internal; - -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.base.Preconditions.checkState; -import static com.google.common.base.Throwables.propagate; -import static com.google.common.io.Closeables.closeQuietly; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.UnsupportedEncodingException; -import java.security.InvalidKeyException; -import java.security.Key; -import java.security.KeyFactory; -import java.security.NoSuchAlgorithmException; -import java.security.PrivateKey; -import java.security.PublicKey; -import java.security.cert.CertificateEncodingException; -import java.security.cert.CertificateFactory; -import java.security.cert.X509Certificate; -import java.security.spec.KeySpec; -import java.security.spec.PKCS8EncodedKeySpec; -import java.security.spec.X509EncodedKeySpec; -import java.util.Arrays; - -import javax.annotation.Resource; -import javax.crypto.BadPaddingException; -import javax.crypto.Cipher; -import javax.crypto.IllegalBlockSizeException; -import javax.crypto.NoSuchPaddingException; -import javax.crypto.ShortBufferException; - -import net.oauth.signature.pem.PEMReader; -import net.oauth.signature.pem.PKCS1EncodedKeySpec; - -import org.jclouds.encryption.EncryptionService; -import org.jclouds.http.PayloadEnclosing; -import org.jclouds.io.Payload; -import org.jclouds.logging.Logger; - -import com.google.common.base.Throwables; - -/** - * - * @author Adrian Cole - */ -public abstract class BaseEncryptionService implements EncryptionService { - - @Resource - protected Logger logger = Logger.NULL; - - protected static final int BUF_SIZE = 0x2000; // 8 - - final byte[] HEX_CHAR_TABLE = { (byte) '0', (byte) '1', (byte) '2', (byte) '3', (byte) '4', (byte) '5', (byte) '6', - (byte) '7', (byte) '8', (byte) '9', (byte) 'a', (byte) 'b', (byte) 'c', (byte) 'd', (byte) 'e', (byte) 'f' }; - - private final KeyFactory rsaKeyFactory; - private final CertificateFactory certFactory; - - public BaseEncryptionService(KeyFactory rsaKeyFactory, CertificateFactory certFactory) { - this.rsaKeyFactory = rsaKeyFactory; - this.certFactory = certFactory; - } - - @Override - public String hex(byte[] raw) { - byte[] hex = new byte[2 * raw.length]; - int index = 0; - - for (byte b : raw) { - int v = b & 0xFF; - hex[index++] = HEX_CHAR_TABLE[v >>> 4]; - hex[index++] = HEX_CHAR_TABLE[v & 0xF]; - } - try { - return new String(hex, "ASCII"); - } catch (UnsupportedEncodingException e) { - throw new RuntimeException(e); - } - } - - @Override - public byte[] fromHex(String hex) { - if (hex.startsWith("0x")) - hex = hex.substring(2); - byte[] bytes = new byte[hex.length() / 2]; - for (int i = 0; i < bytes.length; i++) { - bytes[i] = (byte) Integer.parseInt(hex.substring(2 * i, 2 * i + 2), 16); - } - return bytes; - } - - @Override - public Payload generateMD5BufferingIfNotRepeatable(Payload payload) { - checkNotNull(payload, "payload"); - if (!payload.isRepeatable()) { - String oldContentType = payload.getContentType(); - payload = generatePayloadWithMD5For(payload.getInput()); - payload.setContentType(oldContentType); - } else { - payload.setContentMD5(md5(payload.getInput())); - } - 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; - } - - /** - * {@inheritDoc} - */ - @Override - public PrivateKey privateKeyFromPEM(byte[] pem) { - PEMReader reader; - try { - reader = new PEMReader(pem); - - byte[] bytes = reader.getDerBytes(); - KeySpec keySpec; - - if (PEMReader.PRIVATE_PKCS1_MARKER.equals(reader.getBeginMarker())) { - keySpec = (new PKCS1EncodedKeySpec(bytes)).getKeySpec(); - } else if (PEMReader.PRIVATE_PKCS8_MARKER.equals(reader.getBeginMarker())) { - keySpec = new PKCS8EncodedKeySpec(bytes); - } else { - throw new IOException("Invalid PEM file: Unknown marker for private key " + reader.getBeginMarker()); - } - return rsaKeyFactory.generatePrivate(keySpec); - } catch (Exception e) { - Throwables.propagate(e); - return null; - } - } - - /** - * {@inheritDoc} - */ - @Override - public PublicKey publicKeyFromPEM(byte[] pem) { - PEMReader reader; - try { - reader = new PEMReader(pem); - - byte[] bytes = reader.getDerBytes(); - KeySpec keySpec; - - if (PEMReader.PUBLIC_X509_MARKER.equals(reader.getBeginMarker())) { - keySpec = new X509EncodedKeySpec(bytes); - } else { - throw new IOException("Invalid PEM file: Unknown marker for public key " + reader.getBeginMarker()); - } - return rsaKeyFactory.generatePublic(keySpec); - } catch (Exception e) { - Throwables.propagate(e); - return null; - } - } - - /** - * {@inheritDoc} - */ - @Override - public X509Certificate x509CertificateFromPEM(byte[] pem) { - PEMReader reader; - try { - reader = new PEMReader(pem); - - byte[] bytes = reader.getDerBytes(); - - if (PEMReader.CERTIFICATE_X509_MARKER.equals(reader.getBeginMarker())) { - return (X509Certificate) certFactory.generateCertificate(new ByteArrayInputStream(bytes)); - } else { - throw new IOException("Invalid PEM file: Unknown marker for public key " + reader.getBeginMarker()); - } - - } catch (Exception e) { - Throwables.propagate(e); - return null; - } - } - - @Override - public byte[] rsaEncrypt(Payload payload, Key key) { - // TODO convert this to BC code - Cipher cipher = null; - try { - cipher = Cipher.getInstance("RSA"); - cipher.init(Cipher.ENCRYPT_MODE, key); - } catch (NoSuchAlgorithmException e) { - Throwables.propagate(e); - } catch (NoSuchPaddingException e) { - Throwables.propagate(e); - } catch (InvalidKeyException e) { - Throwables.propagate(e); - } - return cipherPayload(cipher, payload); - } - - @Override - public byte[] rsaDecrypt(Payload payload, Key key) { - // TODO convert this to BC code - Cipher cipher = null; - try { - cipher = Cipher.getInstance("RSA"); - cipher.init(Cipher.DECRYPT_MODE, key); - } catch (NoSuchAlgorithmException e) { - Throwables.propagate(e); - } catch (NoSuchPaddingException e) { - Throwables.propagate(e); - } catch (InvalidKeyException e) { - Throwables.propagate(e); - } - return cipherPayload(cipher, payload); - } - - private byte[] cipherPayload(Cipher cipher, Payload payload) { - byte[] resBuf = new byte[cipher.getOutputSize(payload.getContentLength().intValue())]; - byte[] buffer = new byte[BUF_SIZE]; - long length = 0; - int numRead = -1; - InputStream plainBytes = payload.getInput(); - try { - do { - numRead = plainBytes.read(buffer); - if (numRead > 0) { - length += numRead; - cipher.update(buffer, 0, numRead); - } - } while (numRead != -1); - } catch (IOException e) { - propagate(e); - } finally { - closeQuietly(plainBytes); - } - try { - int size = cipher.doFinal(resBuf, 0); - return Arrays.copyOfRange(resBuf, 0, size); - } catch (IllegalBlockSizeException e) { - Throwables.propagate(e); - } catch (ShortBufferException e) { - Throwables.propagate(e); - } catch (BadPaddingException e) { - Throwables.propagate(e); - } - assert false; - return null; - } - - @Override - public String toPem(X509Certificate cert) { - try { - return new StringBuilder("-----BEGIN CERTIFICATE-----\n").append(base64(cert.getEncoded())).append( - "\n-----END CERTIFICATE-----\n").toString(); - } catch (CertificateEncodingException e) { - Throwables.propagate(e); - return null; - } - } - - @Override - public String toPem(PublicKey key) { - return new StringBuilder("-----BEGIN PUBLIC KEY-----\n").append(base64(key.getEncoded())).append( - "\n-----END PUBLIC KEY-----\n").toString(); - } - - @Override - public String toPem(PrivateKey key) { - return new StringBuilder("-----BEGIN PRIVATE KEY-----\n").append(base64(key.getEncoded())).append( - "\n-----END PRIVATE KEY-----\n").toString(); - } -} diff --git a/core/src/main/java/org/jclouds/encryption/internal/JCECrypto.java b/core/src/main/java/org/jclouds/encryption/internal/JCECrypto.java new file mode 100755 index 0000000000..11169b5c9e --- /dev/null +++ b/core/src/main/java/org/jclouds/encryption/internal/JCECrypto.java @@ -0,0 +1,135 @@ +/** + * + * Copyright (C) 2009 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ==================================================================== + */ +package org.jclouds.encryption.internal; + +import java.security.InvalidKeyException; +import java.security.KeyFactory; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.security.Provider; +import java.security.cert.CertificateException; +import java.security.cert.CertificateFactory; + +import javax.annotation.Nullable; +import javax.crypto.Mac; +import javax.crypto.spec.SecretKeySpec; +import javax.inject.Inject; +import javax.inject.Singleton; + +import org.jclouds.crypto.Crypto; + +/** + * + * @author Adrian Cole + */ +@Singleton +public class JCECrypto implements Crypto { + + private final KeyFactory rsaKeyFactory; + private final CertificateFactory certFactory; + private final Provider provider; + + @Inject + public JCECrypto() throws NoSuchAlgorithmException, CertificateException { + this(null); + } + + public JCECrypto(@Nullable Provider provider) throws NoSuchAlgorithmException, CertificateException { + this.rsaKeyFactory = provider == null ? KeyFactory.getInstance("RSA") : KeyFactory.getInstance("RSA", provider); + this.certFactory = provider == null ? CertificateFactory.getInstance("X.509") : CertificateFactory.getInstance( + "X.509", provider); + this.provider = provider; + } + + @Override + public Mac hmac(String algorithm, byte[] key) throws NoSuchAlgorithmException, InvalidKeyException { + Mac mac = provider == null ? Mac.getInstance(algorithm) : Mac.getInstance(algorithm, provider); + SecretKeySpec signingKey = new SecretKeySpec(key, algorithm); + mac.init(signingKey); + return mac; + + } + + @Override + public MessageDigest digest(String algorithm) throws NoSuchAlgorithmException { + return provider == null ? MessageDigest.getInstance(algorithm) : MessageDigest.getInstance(algorithm, provider); + } + + public final static String MD5 = "MD5"; + public final static String SHA1 = "SHA1"; + public final static String SHA256 = "SHA256"; + + @Override + public MessageDigest md5() { + try { + return digest(MD5); + } catch (NoSuchAlgorithmException e) { + throw new IllegalStateException("MD5 must be supported", e); + } + } + + @Override + public MessageDigest sha1() { + try { + return digest(SHA1); + } catch (NoSuchAlgorithmException e) { + throw new IllegalStateException("MD5 must be supported", e); + } + } + + @Override + public MessageDigest sha256() { + try { + return digest(SHA256); + } catch (NoSuchAlgorithmException e) { + throw new IllegalStateException("SHA256 must be supported", e); + } + } + + public final static String HmacSHA256 = "HmacSHA256"; + public final static String HmacSHA1 = "HmacSHA1"; + + @Override + public Mac hmacSHA1(byte[] key) throws InvalidKeyException { + try { + return hmac(HmacSHA1, key); + } catch (NoSuchAlgorithmException e) { + throw new IllegalStateException("HmacSHA1 must be supported", e); + } + } + + @Override + public Mac hmacSHA256(byte[] key) throws InvalidKeyException { + try { + return hmac(HmacSHA256, key); + } catch (NoSuchAlgorithmException e) { + throw new IllegalStateException("HmacSHA256 must be supported", e); + } + } + + @Override + public CertificateFactory certFactory() { + return certFactory; + } + + @Override + public KeyFactory rsaKeyFactory() { + return rsaKeyFactory; + } +} diff --git a/core/src/main/java/org/jclouds/encryption/internal/JCEEncryptionService.java b/core/src/main/java/org/jclouds/encryption/internal/JCEEncryptionService.java deleted file mode 100644 index 6862ed7b1e..0000000000 --- a/core/src/main/java/org/jclouds/encryption/internal/JCEEncryptionService.java +++ /dev/null @@ -1,202 +0,0 @@ -/** - * - * Copyright (C) 2009 Cloud Conscious, LLC. - * - * ==================================================================== - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ -package org.jclouds.encryption.internal; - -import static com.google.common.base.Throwables.propagate; -import static com.google.common.io.Closeables.closeQuietly; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.security.DigestOutputStream; -import java.security.InvalidKeyException; -import java.security.KeyFactory; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.security.cert.CertificateException; -import java.security.cert.CertificateFactory; - -import javax.crypto.Mac; -import javax.crypto.spec.SecretKeySpec; - -import org.jclouds.io.payloads.ByteArrayPayload; - -/** - * - * @author Adrian Cole - */ -public class JCEEncryptionService extends BaseEncryptionService { - - public JCEEncryptionService(KeyFactory rsaKeyFactory, CertificateFactory certFactory) { - super(rsaKeyFactory, certFactory); - } - - public JCEEncryptionService() throws NoSuchAlgorithmException, CertificateException { - this(KeyFactory.getInstance("RSA"), CertificateFactory.getInstance("X.509")); - } - - @Override - public byte[] hmacSha256(String toEncode, byte[] key) { - return hmac(toEncode, key, "HmacSHA256"); - } - - @Override - public byte[] hmacSha1(String toEncode, byte[] key) { - return hmac(toEncode, key, "HmacSHA1"); - } - - public byte[] hmac(String toEncode, byte[] key, String algorithm) { - SecretKeySpec signingKey = new SecretKeySpec(key, algorithm); - - Mac mac = null; - try { - mac = Mac.getInstance(algorithm); - } catch (NoSuchAlgorithmException e) { - throw new RuntimeException("Could not find the " + algorithm + " algorithm", e); - } - try { - mac.init(signingKey); - } catch (InvalidKeyException e) { - throw new RuntimeException("Could not initialize the " + algorithm + " algorithm", e); - } - return mac.doFinal(toEncode.getBytes()); - } - - @Override - public byte[] md5(InputStream toEncode) { - MessageDigest eTag = getDigest(); - byte[] buffer = new byte[BUF_SIZE]; - int numRead = -1; - try { - do { - numRead = toEncode.read(buffer); - if (numRead > 0) { - eTag.update(buffer, 0, numRead); - } - } while (numRead != -1); - } catch (IOException e) { - propagate(e); - } finally { - closeQuietly(toEncode); - } - return eTag.digest(); - } - - @Override - public String base64(byte[] resBuf) { - return Base64.encodeBytes(resBuf, Base64.DONT_BREAK_LINES); - } - - @Override - public byte[] fromBase64(String encoded) { - return Base64.decode(encoded); - } - - @Override - public ByteArrayPayload generatePayloadWithMD5For(InputStream toEncode) { - MessageDigest eTag = getDigest(); - byte[] buffer = new byte[BUF_SIZE]; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - long length = 0; - int numRead = -1; - try { - do { - numRead = toEncode.read(buffer); - if (numRead > 0) { - length += numRead; - eTag.update(buffer, 0, numRead); - out.write(buffer, 0, numRead); - } - } while (numRead != -1); - } catch (IOException e) { - propagate(e); - } finally { - closeQuietly(out); - closeQuietly(toEncode); - } - return new ByteArrayPayload(out.toByteArray(), eTag.digest()); - } - - private static MessageDigest getDigest() { - MessageDigest eTag; - try { - eTag = MessageDigest.getInstance("MD5"); - } catch (NoSuchAlgorithmException e) { - throw new RuntimeException("Could not find the MD5 algorithm", e); - } - return eTag; - } - - @Override - public MD5OutputStream md5OutputStream(OutputStream out) { - return new JCEMD5OutputStream(out); - } - - private static class JCEMD5OutputStream extends MD5OutputStream { - public JCEMD5OutputStream(OutputStream out) { - super(new DigestOutputStream(out, getDigest())); - } - - @Override - public byte[] getMD5() { - MessageDigest digest = ((DigestOutputStream) out).getMessageDigest(); - return digest.digest(); - } - } - - @Override - public byte[] sha1(InputStream plainBytes) { - return digest(plainBytes, "SHA1"); - } - - @Override - public byte[] sha256(InputStream plainBytes) { - return digest(plainBytes, "SHA256"); - } - - private byte[] digest(InputStream plainBytes, String algorithm) { - MessageDigest digest; - try { - digest = MessageDigest.getInstance(algorithm); - } catch (NoSuchAlgorithmException e1) { - propagate(e1); - return null; - } - byte[] buffer = new byte[BUF_SIZE]; - long length = 0; - int numRead = -1; - try { - do { - numRead = plainBytes.read(buffer); - if (numRead > 0) { - length += numRead; - digest.update(buffer, 0, numRead); - } - } while (numRead != -1); - } catch (IOException e) { - propagate(e); - } finally { - closeQuietly(plainBytes); - } - - return digest.digest(); - } - -} diff --git a/core/src/main/java/org/jclouds/http/HttpUtils.java b/core/src/main/java/org/jclouds/http/HttpUtils.java index 11b1e376cb..a2315aa189 100644 --- a/core/src/main/java/org/jclouds/http/HttpUtils.java +++ b/core/src/main/java/org/jclouds/http/HttpUtils.java @@ -67,8 +67,10 @@ import javax.ws.rs.core.HttpHeaders; import javax.ws.rs.core.UriBuilder; import org.jclouds.Constants; -import org.jclouds.encryption.EncryptionService; +import org.jclouds.crypto.CryptoStreams; +import org.jclouds.io.InputSuppliers; import org.jclouds.io.Payload; +import org.jclouds.io.PayloadEnclosing; import org.jclouds.io.Payloads; import org.jclouds.logging.Logger; import org.jclouds.logging.internal.Wire; @@ -96,13 +98,12 @@ public class HttpUtils { @Inject(optional = true) @Named(Constants.PROPERTY_PROXY_SYSTEM) private boolean systemProxies = System.getProperty("java.net.useSystemProxies") != null ? Boolean - .parseBoolean(System.getProperty("java.net.useSystemProxies")) : false; + .parseBoolean(System.getProperty("java.net.useSystemProxies")) : false; private final int globalMaxConnections; private final int globalMaxConnectionsPerHost; private final int connectionTimeout; private final int soTimeout; - private final EncryptionService encryptionService; @Inject(optional = true) @Named(Constants.PROPERTY_PROXY_HOST) private String proxyHost; @@ -117,12 +118,10 @@ public class HttpUtils { private String proxyPassword; @Inject - public HttpUtils(EncryptionService encryptionService, - @Named(Constants.PROPERTY_CONNECTION_TIMEOUT) int connectionTimeout, - @Named(Constants.PROPERTY_SO_TIMEOUT) int soTimeout, - @Named(Constants.PROPERTY_MAX_CONNECTIONS_PER_CONTEXT) int globalMaxConnections, - @Named(Constants.PROPERTY_MAX_CONNECTIONS_PER_HOST) int globalMaxConnectionsPerHost) { - this.encryptionService = encryptionService; + public HttpUtils(@Named(Constants.PROPERTY_CONNECTION_TIMEOUT) int connectionTimeout, + @Named(Constants.PROPERTY_SO_TIMEOUT) int soTimeout, + @Named(Constants.PROPERTY_MAX_CONNECTIONS_PER_CONTEXT) int globalMaxConnections, + @Named(Constants.PROPERTY_MAX_CONNECTIONS_PER_HOST) int globalMaxConnectionsPerHost) { this.soTimeout = soTimeout; this.connectionTimeout = connectionTimeout; this.globalMaxConnections = globalMaxConnections; @@ -182,8 +181,8 @@ public class HttpUtils { } /** - * keys to the map are only used for socket information, not path. In this - * case, you should remove any path or query details from the URI. + * keys to the map are only used for socket information, not path. In this case, you should + * remove any path or query details from the URI. */ public static URI createBaseEndpointFor(URI endpoint) { if (endpoint.getPort() == -1) { @@ -194,8 +193,7 @@ public class HttpUtils { } /** - * Web browsers do not always handle '+' characters well, use the - * well-supported '%20' instead. + * Web browsers do not always handle '+' characters well, use the well-supported '%20' instead. */ public static String urlEncode(String in, char... skipEncode) { if (isUrlEncoded(in)) @@ -241,8 +239,7 @@ public class HttpUtils { } /** - * Content stream may need to be read. However, we should always close the - * http stream. + * Content stream may need to be read. However, we should always close the http stream. * * @throws IOException */ @@ -262,11 +259,11 @@ public class HttpUtils { String scheme = redirectURI.getScheme(); checkState(redirectURI.getScheme().startsWith("http"), String.format( - "header %s didn't parse an http scheme: [%s]", hostHeader, scheme)); + "header %s didn't parse an http scheme: [%s]", hostHeader, scheme)); int port = redirectURI.getPort() > 0 ? redirectURI.getPort() : redirectURI.getScheme().equals("https") ? 443 : 80; String host = redirectURI.getHost(); checkState(host.indexOf('/') == -1, String.format("header %s didn't parse an http host correctly: [%s]", - hostHeader, host)); + hostHeader, host)); URI endPoint = URI.create(String.format("%s://%s:%d", scheme, host, port)); return endPoint; } @@ -276,11 +273,10 @@ public class HttpUtils { } /** - * Used to extract the URI and authentication data from a String. Note that - * the java URI class breaks, if there are special characters like '/' - * present. Otherwise, we wouldn't need this class, and we could simply use - * URI.create("uri").getUserData(); Also, URI breaks if there are curly - * braces. + * Used to extract the URI and authentication data from a String. Note that the java URI class + * breaks, if there are special characters like '/' present. Otherwise, we wouldn't need this + * class, and we could simply use URI.create("uri").getUserData(); Also, URI breaks if there are + * curly braces. * */ public static URI createUri(String uriPath) { @@ -339,8 +335,12 @@ public class HttpUtils { if (message.getPayload().getContentLength() != null) logger.debug("%s %s: %s", prefix, HttpHeaders.CONTENT_LENGTH, message.getPayload().getContentLength()); if (message.getPayload().getContentMD5() != null) - logger.debug("%s %s: %s", prefix, "Content-MD5", encryptionService.base64(message.getPayload() - .getContentMD5())); + try { + logger.debug("%s %s: %s", prefix, "Content-MD5", CryptoStreams.base64Encode(InputSuppliers.of(message + .getPayload().getContentMD5()))); + } catch (IOException e) { + logger.warn(e, " error getting md5 for %s", message); + } } } @@ -363,13 +363,12 @@ public class HttpUtils { } /** - * change the destination of the current http command. typically used in - * handling redirects. + * change the destination of the current http command. typically used in handling redirects. * * @param string */ public static void changeSchemeHostAndPortTo(HttpRequest request, String scheme, String host, int port, - UriBuilder builder) { + UriBuilder builder) { builder.uri(request.getEndpoint()); builder.scheme(scheme); builder.host(host); @@ -403,7 +402,7 @@ public class HttpUtils { } public static void addQueryParamTo(HttpRequest request, String key, Iterable values, UriBuilder builder, - char... skips) { + char... skips) { builder.uri(request.getEndpoint()); Multimap map = parseQueryToMap(request.getEndpoint().getQuery()); for (Object o : values) @@ -460,16 +459,16 @@ public class HttpUtils { } public static SortedSet> sortEntries(Collection> in, - Comparator> sorter) { + Comparator> sorter) { SortedSet> entries = newTreeSet(sorter); entries.addAll(in); return entries; } public static String makeQueryLine(Multimap params, - @Nullable Comparator> sorter, char... skips) { + @Nullable Comparator> sorter, char... skips) { Iterator> pairs = ((sorter == null) ? params.entries() : sortEntries(params.entries(), - sorter)).iterator(); + sorter)).iterator(); StringBuilder formBuilder = new StringBuilder(); while (pairs.hasNext()) { Map.Entry pair = pairs.next(); @@ -499,7 +498,7 @@ public class HttpUtils { payload.setContentLength(new Long(header.getValue())); } else if ("Content-MD5".equalsIgnoreCase(header.getKey())) { if (payload != null) - payload.setContentMD5(encryptionService.fromBase64(header.getValue())); + payload.setContentMD5(CryptoStreams.base64(header.getValue())); } else if (CONTENT_TYPE.equalsIgnoreCase(header.getKey())) { if (payload != null) payload.setContentType(header.getValue()); @@ -510,20 +509,20 @@ public class HttpUtils { if (message instanceof HttpRequest) { checkArgument( - message.getPayload() == null || message.getFirstHeaderOrNull(CONTENT_TYPE) == null, - "configuration error please use request.getPayload().setContentType(value) as opposed to adding a content type header: " - + message); + message.getPayload() == null || message.getFirstHeaderOrNull(CONTENT_TYPE) == null, + "configuration error please use request.getPayload().setContentType(value) as opposed to adding a content type header: " + + message); checkArgument( - message.getPayload() == null || message.getFirstHeaderOrNull(CONTENT_LENGTH) == null, - "configuration error please use request.getPayload().setContentLength(value) as opposed to adding a content length header: " - + message); + message.getPayload() == null || message.getFirstHeaderOrNull(CONTENT_LENGTH) == null, + "configuration error please use request.getPayload().setContentLength(value) as opposed to adding a content length header: " + + message); checkArgument(message.getPayload() == null || message.getPayload().getContentLength() != null - || "chunked".equalsIgnoreCase(message.getFirstHeaderOrNull("Transfer-Encoding")), - "either chunked encoding must be set on the http request or contentlength set on the payload: " - + message); + || "chunked".equalsIgnoreCase(message.getFirstHeaderOrNull("Transfer-Encoding")), + "either chunked encoding must be set on the http request or contentlength set on the payload: " + + message); checkArgument(message.getPayload() == null || message.getFirstHeaderOrNull("Content-MD5") == null, - "configuration error please use request.getPayload().setContentMD5(value) as opposed to adding a content md5 header: " - + message); + "configuration error please use request.getPayload().setContentMD5(value) as opposed to adding a content md5 header: " + + message); } } @@ -537,7 +536,7 @@ public class HttpUtils { } public String valueOrEmpty(byte[] md5) { - return md5 != null ? encryptionService.base64(md5) : ""; + return md5 != null ? CryptoStreams.base64(md5) : ""; } public String valueOrEmpty(Collection collection) { @@ -563,14 +562,14 @@ public class HttpUtils { if (request.getPayload() != null && wire.enabled()) { wire.output(request); checkRequestHasContentLengthOrChunkedEncoding(request, - "After wiring, the request has neither chunked encoding nor content length: " + request); + "After wiring, the request has neither chunked encoding nor content length: " + request); } } public static T returnValueOnCodeOrNull(Exception from, T value, Predicate codePredicate) { Iterable throwables = filter(getCausalChain(from), HttpResponseException.class); if (size(throwables) >= 1 && get(throwables, 0).getResponse() != null - && codePredicate.apply(get(throwables, 0).getResponse().getStatusCode())) { + && codePredicate.apply(get(throwables, 0).getResponse().getStatusCode())) { return value; } return null; diff --git a/core/src/main/java/org/jclouds/http/TransformingHttpCommandExecutorServiceImpl.java b/core/src/main/java/org/jclouds/http/TransformingHttpCommandExecutorServiceImpl.java index 59daebb1d7..73dec11373 100644 --- a/core/src/main/java/org/jclouds/http/TransformingHttpCommandExecutorServiceImpl.java +++ b/core/src/main/java/org/jclouds/http/TransformingHttpCommandExecutorServiceImpl.java @@ -24,7 +24,7 @@ import javax.inject.Inject; import javax.inject.Named; import org.jclouds.Constants; -import static org.jclouds.concurrent.ConcurrentUtils.*; +import org.jclouds.concurrent.Futures; import com.google.common.base.Function; import com.google.common.util.concurrent.ListenableFuture; @@ -50,7 +50,7 @@ public class TransformingHttpCommandExecutorServiceImpl implements TransformingH * {@inheritDoc} */ public ListenableFuture submit(HttpCommand command, Function responseTransformer) { - return compose(client.submit(command), responseTransformer, userThreads); + return Futures.compose(client.submit(command), responseTransformer, userThreads); } } diff --git a/core/src/main/java/org/jclouds/http/filters/BasicAuthentication.java b/core/src/main/java/org/jclouds/http/filters/BasicAuthentication.java index 2cc8397003..124223396d 100644 --- a/core/src/main/java/org/jclouds/http/filters/BasicAuthentication.java +++ b/core/src/main/java/org/jclouds/http/filters/BasicAuthentication.java @@ -30,7 +30,8 @@ import javax.inject.Named; import javax.inject.Singleton; import javax.ws.rs.core.HttpHeaders; -import org.jclouds.encryption.EncryptionService; +import org.jclouds.crypto.Crypto; +import org.jclouds.crypto.CryptoStreams; import org.jclouds.http.HttpException; import org.jclouds.http.HttpRequest; import org.jclouds.http.HttpRequestFilter; @@ -50,11 +51,10 @@ public class BasicAuthentication implements HttpRequestFilter { private final Set credentialList; @Inject - BasicAuthentication(@Named(PROPERTY_IDENTITY) String user, - @Named(PROPERTY_CREDENTIAL) String password, EncryptionService encryptionService) + BasicAuthentication(@Named(PROPERTY_IDENTITY) String user, @Named(PROPERTY_CREDENTIAL) String password, Crypto crypto) throws UnsupportedEncodingException { this.credentialList = ImmutableSet.of("Basic " - + encryptionService.base64(String.format("%s:%s", checkNotNull(user, "user"), + + CryptoStreams.base64(String.format("%s:%s", checkNotNull(user, "user"), checkNotNull(password, "password")).getBytes("UTF-8"))); } diff --git a/core/src/main/java/org/jclouds/http/internal/BaseHttpCommandExecutorService.java b/core/src/main/java/org/jclouds/http/internal/BaseHttpCommandExecutorService.java index 785c241beb..e13a95212f 100644 --- a/core/src/main/java/org/jclouds/http/internal/BaseHttpCommandExecutorService.java +++ b/core/src/main/java/org/jclouds/http/internal/BaseHttpCommandExecutorService.java @@ -18,6 +18,7 @@ */ package org.jclouds.http.internal; +import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.io.ByteStreams.copy; import static org.jclouds.http.HttpUtils.checkRequestHasContentLengthOrChunkedEncoding; import static org.jclouds.http.HttpUtils.wirePayloadIfEnabled; @@ -35,7 +36,6 @@ import javax.inject.Inject; import javax.inject.Named; import org.jclouds.Constants; -import org.jclouds.encryption.EncryptionService; import org.jclouds.http.HttpCommand; import org.jclouds.http.HttpCommandExecutorService; import org.jclouds.http.HttpRequest; @@ -56,7 +56,6 @@ import com.google.common.io.NullOutputStream; */ public abstract class BaseHttpCommandExecutorService implements HttpCommandExecutorService { protected final HttpUtils utils; - protected final EncryptionService encryptionService; private final DelegatingRetryHandler retryHandler; private final IOExceptionRetryHandler ioRetryHandler; @@ -72,17 +71,16 @@ public abstract class BaseHttpCommandExecutorService implements HttpCommandEx protected final HttpWire wire; @Inject - protected BaseHttpCommandExecutorService(HttpUtils utils, EncryptionService encryptionService, + protected BaseHttpCommandExecutorService(HttpUtils utils, @Named(Constants.PROPERTY_IO_WORKER_THREADS) ExecutorService ioWorkerExecutor, DelegatingRetryHandler retryHandler, IOExceptionRetryHandler ioRetryHandler, DelegatingErrorHandler errorHandler, HttpWire wire) { - this.utils = utils; - this.encryptionService = encryptionService; - this.retryHandler = retryHandler; - this.ioRetryHandler = ioRetryHandler; - this.errorHandler = errorHandler; - this.ioWorkerExecutor = ioWorkerExecutor; - this.wire = wire; + this.utils = checkNotNull(utils, "utils"); + this.retryHandler = checkNotNull(retryHandler, "retryHandler"); + this.ioRetryHandler = checkNotNull(ioRetryHandler, "ioRetryHandler"); + this.errorHandler = checkNotNull(errorHandler, "errorHandler"); + this.ioWorkerExecutor = checkNotNull(ioWorkerExecutor, "ioWorkerExecutor"); + this.wire = checkNotNull(wire, "wire"); } public static InputStream consumeOnClose(InputStream in) { diff --git a/core/src/main/java/org/jclouds/http/internal/JavaUrlHttpCommandExecutorService.java b/core/src/main/java/org/jclouds/http/internal/JavaUrlHttpCommandExecutorService.java index 067409fa44..dda4ff2a0e 100644 --- a/core/src/main/java/org/jclouds/http/internal/JavaUrlHttpCommandExecutorService.java +++ b/core/src/main/java/org/jclouds/http/internal/JavaUrlHttpCommandExecutorService.java @@ -47,7 +47,7 @@ import javax.net.ssl.HttpsURLConnection; import javax.ws.rs.core.HttpHeaders; import org.jclouds.Constants; -import org.jclouds.encryption.EncryptionService; +import org.jclouds.crypto.CryptoStreams; import org.jclouds.http.HttpCommandExecutorService; import org.jclouds.http.HttpRequest; import org.jclouds.http.HttpResponse; @@ -68,8 +68,7 @@ import com.google.common.collect.Multimap; * @author Adrian Cole */ @Singleton -public class JavaUrlHttpCommandExecutorService extends - BaseHttpCommandExecutorService { +public class JavaUrlHttpCommandExecutorService extends BaseHttpCommandExecutorService { public static final String USER_AGENT = "jclouds/1.0 java/" + System.getProperty("java.version"); @Resource @@ -80,18 +79,15 @@ public class JavaUrlHttpCommandExecutorService extends public JavaUrlHttpCommandExecutorService(HttpUtils utils, @Named(Constants.PROPERTY_IO_WORKER_THREADS) ExecutorService ioWorkerExecutor, DelegatingRetryHandler retryHandler, IOExceptionRetryHandler ioRetryHandler, - DelegatingErrorHandler errorHandler, HttpWire wire, HostnameVerifier verifier, - EncryptionService encryptionService) { - super(utils, encryptionService, ioWorkerExecutor, retryHandler, ioRetryHandler, errorHandler, - wire); + DelegatingErrorHandler errorHandler, HttpWire wire, HostnameVerifier verifier) { + super(utils, ioWorkerExecutor, retryHandler, ioRetryHandler, errorHandler, wire); if (utils.getMaxConnections() > 0) - System.setProperty("http.maxConnections", String.valueOf(utils.getMaxConnections())); - this.verifier = verifier; + System.setProperty("http.maxConnections", String.valueOf(checkNotNull(utils, "utils").getMaxConnections())); + this.verifier = checkNotNull(verifier, "verifier"); } @Override - protected HttpResponse invoke(HttpURLConnection connection) throws IOException, - InterruptedException { + protected HttpResponse invoke(HttpURLConnection connection) throws IOException, InterruptedException { InputStream in = null; try { in = consumeOnClose(connection.getInputStream()); @@ -109,8 +105,7 @@ public class JavaUrlHttpCommandExecutorService extends } Payload payload = in != null ? Payloads.newInputStreamPayload(in) : null; - HttpResponse response = new HttpResponse(connection.getResponseCode(), connection - .getResponseMessage(), payload); + HttpResponse response = new HttpResponse(connection.getResponseCode(), connection.getResponseMessage(), payload); Multimap headers = LinkedHashMultimap.create(); for (String header : connection.getHeaderFields().keySet()) { headers.putAll(header, connection.getHeaderFields().get(header)); @@ -133,8 +128,7 @@ public class JavaUrlHttpCommandExecutorService extends } @Override - protected HttpURLConnection convert(HttpRequest request) throws IOException, - InterruptedException { + protected HttpURLConnection convert(HttpRequest request) throws IOException, InterruptedException { boolean chunked = "chunked".equals(request.getFirstHeaderOrNull("Transfer-Encoding")); URL url = request.getEndpoint().toURL(); @@ -150,8 +144,7 @@ public class JavaUrlHttpCommandExecutorService extends Proxy proxy = new Proxy(Proxy.Type.HTTP, addr); Authenticator authenticator = new Authenticator() { public PasswordAuthentication getPasswordAuthentication() { - return (new PasswordAuthentication(utils.getProxyUser(), utils.getProxyPassword() - .toCharArray())); + return (new PasswordAuthentication(utils.getProxyUser(), utils.getProxyPassword().toCharArray())); } }; Authenticator.setDefault(authenticator); @@ -182,16 +175,13 @@ public class JavaUrlHttpCommandExecutorService extends OutputStream out = null; try { if (request.getPayload().getContentMD5() != null) - connection.setRequestProperty("Content-MD5", encryptionService.base64(request - .getPayload().getContentMD5())); + connection.setRequestProperty("Content-MD5", CryptoStreams.base64(request.getPayload().getContentMD5())); if (request.getPayload().getContentType() != null) - connection.setRequestProperty(HttpHeaders.CONTENT_TYPE, request.getPayload() - .getContentType()); + connection.setRequestProperty(HttpHeaders.CONTENT_TYPE, request.getPayload().getContentType()); if (chunked) { connection.setChunkedStreamingMode(8196); } else { - Long length = checkNotNull(request.getPayload().getContentLength(), - "payload.getContentLength"); + Long length = checkNotNull(request.getPayload().getContentLength(), "payload.getContentLength"); connection.setRequestProperty(HttpHeaders.CONTENT_LENGTH, length.toString()); connection.setFixedLengthStreamingMode(length.intValue()); } 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 76936bbadb..fce583edc7 100644 --- a/core/src/main/java/org/jclouds/http/internal/PayloadEnclosingImpl.java +++ b/core/src/main/java/org/jclouds/http/internal/PayloadEnclosingImpl.java @@ -26,8 +26,8 @@ import java.io.InputStream; import javax.annotation.Nullable; -import org.jclouds.http.PayloadEnclosing; import org.jclouds.io.Payload; +import org.jclouds.io.PayloadEnclosing; /** * diff --git a/core/src/main/java/org/jclouds/io/InputSuppliers.java b/core/src/main/java/org/jclouds/io/InputSuppliers.java new file mode 100644 index 0000000000..6e7b9b8dc1 --- /dev/null +++ b/core/src/main/java/org/jclouds/io/InputSuppliers.java @@ -0,0 +1,74 @@ +package org.jclouds.io; + +import static com.google.common.base.Preconditions.checkNotNull; + +import java.io.IOException; +import java.io.InputStream; + +import org.jclouds.encryption.internal.Base64; + +import com.google.common.annotations.Beta; +import com.google.common.annotations.VisibleForTesting; +import com.google.common.base.Charsets; +import com.google.common.io.ByteStreams; +import com.google.common.io.InputSupplier; + +/** + * functions related to or replacing those in {@link com.google.common.io.InputSupplier} + * + * @author Adrian Cole + */ +@Beta +public class InputSuppliers { + /** + * base64 encodes bytes from the supplied supplier as they are read. + */ + public static Base64InputSupplier base64Encoder(InputSupplier supplier) throws IOException { + return new Base64InputSupplier(supplier, Base64.ENCODE + Base64.DONT_BREAK_LINES); + } + + /** + * base64 decodes bytes from the supplied supplier as they are read. + */ + public static Base64InputSupplier base64Decoder(InputSupplier supplier) throws IOException { + return new Base64InputSupplier(supplier, Base64.DECODE); + } + + @VisibleForTesting + static class Base64InputSupplier implements InputSupplier { + + private final InputSupplier delegate; + private final int mode; + + Base64InputSupplier(InputSupplier inputSupplier, int mode) { + this.delegate = checkNotNull(inputSupplier, "delegate"); + this.mode = mode; + } + + @Override + public InputStream getInput() throws IOException { + return new Base64.InputStream(delegate.getInput(), mode); + } + + } + + public static InputSupplier of(final InputStream in) { + checkNotNull(in, "in"); + return new InputSupplier() { + + @Override + public InputStream getInput() throws IOException { + return in; + } + + }; + } + + public static InputSupplier of(byte[] in) { + return ByteStreams.newInputStreamSupplier(checkNotNull(in, "in")); + } + + public static InputSupplier of(String in) { + return of(checkNotNull(in, "in").getBytes(Charsets.UTF_8)); + } +} diff --git a/core/src/main/java/org/jclouds/http/PayloadEnclosing.java b/core/src/main/java/org/jclouds/io/PayloadEnclosing.java similarity index 96% rename from core/src/main/java/org/jclouds/http/PayloadEnclosing.java rename to core/src/main/java/org/jclouds/io/PayloadEnclosing.java index 3cd4edfa72..94d38480f8 100644 --- a/core/src/main/java/org/jclouds/http/PayloadEnclosing.java +++ b/core/src/main/java/org/jclouds/io/PayloadEnclosing.java @@ -16,12 +16,11 @@ * limitations under the License. * ==================================================================== */ -package org.jclouds.http; +package org.jclouds.io; import java.io.File; import java.io.InputStream; -import org.jclouds.io.Payload; /** * diff --git a/core/src/main/java/org/jclouds/io/Payloads.java b/core/src/main/java/org/jclouds/io/Payloads.java index 3ad6721517..97c0b40212 100644 --- a/core/src/main/java/org/jclouds/io/Payloads.java +++ b/core/src/main/java/org/jclouds/io/Payloads.java @@ -19,20 +19,27 @@ package org.jclouds.io; import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.base.Preconditions.checkState; +import static com.google.common.io.ByteStreams.toByteArray; import java.io.File; +import java.io.IOException; import java.io.InputStream; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; import java.util.Comparator; import java.util.Map; import javax.annotation.Nullable; +import org.jclouds.crypto.CryptoStreams; import org.jclouds.io.payloads.ByteArrayPayload; import org.jclouds.io.payloads.FilePayload; import org.jclouds.io.payloads.InputStreamPayload; import org.jclouds.io.payloads.StringPayload; import org.jclouds.io.payloads.UrlEncodedFormPayload; +import com.google.common.base.Throwables; import com.google.common.collect.Multimap; /** @@ -40,6 +47,8 @@ import com.google.common.collect.Multimap; * @author Adrian Cole */ public class Payloads { + private Payloads() { + } public static Payload newPayload(Object data) { checkNotNull(data, "data"); @@ -74,14 +83,84 @@ public class Payloads { return new FilePayload(checkNotNull(data, "data")); } - public static UrlEncodedFormPayload newUrlEncodedFormPayload( - Multimap formParams, char... skips) { + public static UrlEncodedFormPayload newUrlEncodedFormPayload(Multimap formParams, char... skips) { return new UrlEncodedFormPayload(formParams, skips); } - public static UrlEncodedFormPayload newUrlEncodedFormPayload( - Multimap formParams, + public static UrlEncodedFormPayload newUrlEncodedFormPayload(Multimap formParams, @Nullable Comparator> sorter, char... skips) { return new UrlEncodedFormPayload(formParams, sorter, skips); } + + /** + * Calculates and sets {@link Payload#setContentMD5} on the payload. + * + *

+ * note that this will rebuffer in memory if the payload is not repeatable. + * + * @param payload + * payload to calculate + * @param md5 + * digester to calculate payloads with. + * @return new Payload with md5 set. + * @throws IOException + */ + public static Payload calculateMD5(Payload payload, MessageDigest md5) throws IOException { + checkNotNull(payload, "payload"); + if (!payload.isRepeatable()) { + String oldContentType = payload.getContentType(); + Payload oldPayload = payload; + try { + payload = newByteArrayPayload(toByteArray(payload)); + } finally { + oldPayload.release(); + } + payload.setContentType(oldContentType); + } + payload.setContentMD5(CryptoStreams.digest(payload, md5)); + return payload; + } + + /** + * Uses default md5 generator. + * + * @see #calculateMD5(Payload, MessageDigest) + */ + public static Payload calculateMD5(Payload payload) throws IOException { + try { + return calculateMD5(payload, MessageDigest.getInstance("MD5")); + } catch (NoSuchAlgorithmException e) { + Throwables.propagate(e); + return null; + } + } + + /** + * Calculates the md5 on a payload, replacing as necessary. + * + * @see #calculateMD5(Payload, MessageDigest) + */ + public static T calculateMD5(T payloadEnclosing, MessageDigest md5) throws IOException { + checkState(payloadEnclosing != null, "payloadEnclosing"); + Payload newPayload = calculateMD5(payloadEnclosing.getPayload(), md5); + if (newPayload != payloadEnclosing.getPayload()) + payloadEnclosing.setPayload(newPayload); + return payloadEnclosing; + } + + /** + * Calculates the md5 on a payload, replacing as necessary. + *

+ * uses default md5 generator. + * + * @see #calculateMD5(Payload, MessageDigest) + */ + public static T calculateMD5(T payloadEnclosing) throws IOException { + try { + return calculateMD5(payloadEnclosing, MessageDigest.getInstance("MD5")); + } catch (NoSuchAlgorithmException e) { + Throwables.propagate(e); + return null; + } + } } diff --git a/core/src/main/java/org/jclouds/io/payloads/BaseCipherPayload.java b/core/src/main/java/org/jclouds/io/payloads/BaseCipherPayload.java new file mode 100644 index 0000000000..45d6792ac8 --- /dev/null +++ b/core/src/main/java/org/jclouds/io/payloads/BaseCipherPayload.java @@ -0,0 +1,57 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ==================================================================== + */ +package org.jclouds.io.payloads; + +import static com.google.common.base.Preconditions.checkNotNull; + +import java.io.IOException; +import java.io.OutputStream; +import java.security.Key; + +import javax.crypto.Cipher; +import javax.crypto.CipherInputStream; +import javax.crypto.CipherOutputStream; + +import org.jclouds.io.Payload; + +/** + * + * @author Adrian Cole + */ +public abstract class BaseCipherPayload extends DelegatingPayload { + + private final Key key; + + public BaseCipherPayload(Payload delegate, Key key) { + super(delegate); + this.key = checkNotNull(key, "key"); + } + + public abstract Cipher initializeCipher(Key key); + + @Override + public CipherInputStream getInput() { + return new CipherInputStream(super.getInput(), initializeCipher(key)); + } + + @Override + public void writeTo(OutputStream outstream) throws IOException { + super.writeTo(new CipherOutputStream(outstream, initializeCipher(key))); + } +} diff --git a/core/src/main/java/org/jclouds/io/payloads/RSADecryptingPayload.java b/core/src/main/java/org/jclouds/io/payloads/RSADecryptingPayload.java new file mode 100644 index 0000000000..d9fca34120 --- /dev/null +++ b/core/src/main/java/org/jclouds/io/payloads/RSADecryptingPayload.java @@ -0,0 +1,58 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ==================================================================== + */ +package org.jclouds.io.payloads; + +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.NoSuchAlgorithmException; + +import javax.crypto.Cipher; +import javax.crypto.NoSuchPaddingException; + +import org.jclouds.io.Payload; + +import com.google.common.base.Throwables; + +/** + * + * @author Adrian Cole + */ +public class RSADecryptingPayload extends BaseCipherPayload { + + public RSADecryptingPayload(Payload delegate, Key key) { + super(delegate, key); + } + + @Override + public Cipher initializeCipher(Key key) { + Cipher cipher = null; + try { + cipher = Cipher.getInstance("RSA"); + cipher.init(Cipher.DECRYPT_MODE, key); + } catch (NoSuchAlgorithmException e) { + Throwables.propagate(e); + } catch (NoSuchPaddingException e) { + Throwables.propagate(e); + } catch (InvalidKeyException e) { + Throwables.propagate(e); + } + return cipher; + } + +} diff --git a/core/src/main/java/org/jclouds/io/payloads/RSAEncryptingPayload.java b/core/src/main/java/org/jclouds/io/payloads/RSAEncryptingPayload.java new file mode 100644 index 0000000000..7d803d96df --- /dev/null +++ b/core/src/main/java/org/jclouds/io/payloads/RSAEncryptingPayload.java @@ -0,0 +1,58 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ==================================================================== + */ +package org.jclouds.io.payloads; + +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.NoSuchAlgorithmException; + +import javax.crypto.Cipher; +import javax.crypto.NoSuchPaddingException; + +import org.jclouds.io.Payload; + +import com.google.common.base.Throwables; + +/** + * + * @author Adrian Cole + */ +public class RSAEncryptingPayload extends BaseCipherPayload { + + public RSAEncryptingPayload(Payload delegate, Key key) { + super(delegate, key); + } + + @Override + public Cipher initializeCipher(Key key) { + Cipher cipher = null; + try { + cipher = Cipher.getInstance("RSA"); + cipher.init(Cipher.ENCRYPT_MODE, key); + } catch (NoSuchAlgorithmException e) { + Throwables.propagate(e); + } catch (NoSuchPaddingException e) { + Throwables.propagate(e); + } catch (InvalidKeyException e) { + Throwables.propagate(e); + } + return cipher; + } + +} diff --git a/core/src/main/java/org/jclouds/json/config/GsonModule.java b/core/src/main/java/org/jclouds/json/config/GsonModule.java index 023a93015e..a9bec1c63c 100644 --- a/core/src/main/java/org/jclouds/json/config/GsonModule.java +++ b/core/src/main/java/org/jclouds/json/config/GsonModule.java @@ -28,9 +28,9 @@ import javax.inject.Inject; import javax.inject.Singleton; import org.jclouds.Constants; +import org.jclouds.crypto.CryptoStreams; import org.jclouds.date.DateService; import org.jclouds.domain.JsonBall; -import org.jclouds.encryption.EncryptionService; import org.jclouds.json.Json; import org.jclouds.json.internal.GsonWrapper; @@ -63,8 +63,8 @@ public class GsonModule extends AbstractModule { @Provides @Singleton Gson provideGson(JsonBallAdapter jsonObjectAdapter, DateAdapter adapter, ByteListAdapter byteListAdapter, - ByteArrayAdapter byteArrayAdapter, JsonAdapterBindings bindings) throws SecurityException, - NoSuchFieldException, IllegalArgumentException, IllegalAccessException { + ByteArrayAdapter byteArrayAdapter, JsonAdapterBindings bindings) throws SecurityException, + NoSuchFieldException, IllegalArgumentException, IllegalAccessException { GsonBuilder builder = new GsonBuilder(); builder.registerTypeAdapter(JsonBall.class, jsonObjectAdapter); builder.registerTypeAdapter(Date.class, adapter); @@ -101,44 +101,32 @@ public class GsonModule extends AbstractModule { @Singleton public static class HexByteListAdapter implements ByteListAdapter { - private final EncryptionService encryptionService; - - @Inject - HexByteListAdapter(EncryptionService encryptionService) { - this.encryptionService = encryptionService; - } @Override public List deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) - throws JsonParseException { - return Bytes.asList(encryptionService.fromHex(json.getAsString())); + throws JsonParseException { + return Bytes.asList(CryptoStreams.hex(json.getAsString())); } @Override public JsonElement serialize(List src, Type typeOfSrc, JsonSerializationContext context) { - return new JsonPrimitive(encryptionService.hex(Bytes.toArray(src))); + return new JsonPrimitive(CryptoStreams.hex(Bytes.toArray(src))); } } @Singleton public static class HexByteArrayAdapter implements ByteArrayAdapter { - private final EncryptionService encryptionService; - - @Inject - HexByteArrayAdapter(EncryptionService encryptionService) { - this.encryptionService = encryptionService; - } @Override public byte[] deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) - throws JsonParseException { - return encryptionService.fromHex(json.getAsString()); + throws JsonParseException { + return CryptoStreams.hex(json.getAsString()); } @Override public JsonElement serialize(byte[] src, Type typeOfSrc, JsonSerializationContext context) { - return new JsonPrimitive(encryptionService.hex(src)); + return new JsonPrimitive(CryptoStreams.hex(src)); } } @@ -156,7 +144,7 @@ public class GsonModule extends AbstractModule { } public Date deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) - throws JsonParseException { + throws JsonParseException { String toParse = json.getAsJsonPrimitive().getAsString(); try { return dateService.iso8601DateParse(toParse); @@ -181,7 +169,7 @@ public class GsonModule extends AbstractModule { } public Date deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) - throws JsonParseException { + throws JsonParseException { String toParse = json.getAsJsonPrimitive().getAsString(); Date toReturn = dateService.cDateParse(toParse); return toReturn; @@ -202,7 +190,7 @@ public class GsonModule extends AbstractModule { } public JsonBall deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) - throws JsonParseException { + throws JsonParseException { return new JsonBall(json.toString()); } @@ -216,7 +204,7 @@ public class GsonModule extends AbstractModule { } public Date deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) - throws JsonParseException { + throws JsonParseException { long toParse = json.getAsJsonPrimitive().getAsLong(); if (toParse == -1) return null; diff --git a/core/src/main/java/org/jclouds/logging/internal/Wire.java b/core/src/main/java/org/jclouds/logging/internal/Wire.java index 3cf622f0a3..477b7881d1 100644 --- a/core/src/main/java/org/jclouds/logging/internal/Wire.java +++ b/core/src/main/java/org/jclouds/logging/internal/Wire.java @@ -29,8 +29,8 @@ import java.io.InputStream; import javax.annotation.Resource; -import org.jclouds.http.PayloadEnclosing; import org.jclouds.io.Payload; +import org.jclouds.io.PayloadEnclosing; import org.jclouds.io.Payloads; import org.jclouds.logging.Logger; diff --git a/core/src/main/java/org/jclouds/rest/RestContextBuilder.java b/core/src/main/java/org/jclouds/rest/RestContextBuilder.java index eaaec6fc50..40ff00cf36 100755 --- a/core/src/main/java/org/jclouds/rest/RestContextBuilder.java +++ b/core/src/main/java/org/jclouds/rest/RestContextBuilder.java @@ -19,7 +19,6 @@ package org.jclouds.rest; import static com.google.common.base.Preconditions.checkNotNull; -import static org.jclouds.concurrent.ConcurrentUtils.sameThreadExecutor; import static org.jclouds.Constants.PROPERTY_API; import static org.jclouds.Constants.PROPERTY_API_VERSION; import static org.jclouds.Constants.PROPERTY_CREDENTIAL; @@ -34,6 +33,7 @@ import java.util.Properties; import javax.inject.Inject; +import org.jclouds.concurrent.MoreExecutors; import org.jclouds.concurrent.SingleThreaded; import org.jclouds.concurrent.config.ConfiguresExecutorService; import org.jclouds.concurrent.config.ExecutorServiceModule; @@ -244,7 +244,7 @@ public class RestContextBuilder { return input.getClass().isAnnotationPresent(SingleThreaded.class); } })) { - modules.add(new ExecutorServiceModule(sameThreadExecutor(), sameThreadExecutor())); + modules.add(new ExecutorServiceModule(MoreExecutors.sameThreadExecutor(), MoreExecutors.sameThreadExecutor())); } else { modules.add(new ExecutorServiceModule()); } diff --git a/core/src/main/java/org/jclouds/rest/Utils.java b/core/src/main/java/org/jclouds/rest/Utils.java index 5c5e453795..55db58835c 100644 --- a/core/src/main/java/org/jclouds/rest/Utils.java +++ b/core/src/main/java/org/jclouds/rest/Utils.java @@ -20,8 +20,8 @@ package org.jclouds.rest; import java.util.concurrent.ExecutorService; +import org.jclouds.crypto.Crypto; import org.jclouds.date.DateService; -import org.jclouds.encryption.EncryptionService; import org.jclouds.json.Json; import org.jclouds.logging.Logger.LoggerFactory; import org.jclouds.rest.internal.UtilsImpl; @@ -58,12 +58,12 @@ public interface Utils { */ HttpClient http(); - EncryptionService getEncryptionService(); + Crypto getCrypto(); /** - * #see #getEncryptionService + * #see #getCrypto */ - EncryptionService encryption(); + Crypto crypto(); DateService getDateService(); diff --git a/core/src/main/java/org/jclouds/rest/internal/RestAnnotationProcessor.java b/core/src/main/java/org/jclouds/rest/internal/RestAnnotationProcessor.java index 56d1c59868..88d5797bba 100755 --- a/core/src/main/java/org/jclouds/rest/internal/RestAnnotationProcessor.java +++ b/core/src/main/java/org/jclouds/rest/internal/RestAnnotationProcessor.java @@ -75,7 +75,6 @@ import org.jclouds.http.HttpRequest; import org.jclouds.http.HttpRequestFilter; import org.jclouds.http.HttpResponse; import org.jclouds.http.HttpUtils; -import org.jclouds.http.PayloadEnclosing; import org.jclouds.http.functions.ParseJson; import org.jclouds.http.functions.ParseSax; import org.jclouds.http.functions.ParseURIFromListOrLocationHeaderIf20x; @@ -88,6 +87,7 @@ import org.jclouds.http.functions.ParseSax.HandlerWithResult; import org.jclouds.http.options.HttpRequestOptions; import org.jclouds.internal.ClassMethodArgs; import org.jclouds.io.Payload; +import org.jclouds.io.PayloadEnclosing; import org.jclouds.io.Payloads; import org.jclouds.io.payloads.MultipartForm; import org.jclouds.io.payloads.Part; diff --git a/core/src/main/java/org/jclouds/rest/internal/UtilsImpl.java b/core/src/main/java/org/jclouds/rest/internal/UtilsImpl.java index 3344273e1c..8a82d7f196 100644 --- a/core/src/main/java/org/jclouds/rest/internal/UtilsImpl.java +++ b/core/src/main/java/org/jclouds/rest/internal/UtilsImpl.java @@ -24,8 +24,8 @@ import javax.inject.Inject; import javax.inject.Named; import org.jclouds.Constants; +import org.jclouds.crypto.Crypto; import org.jclouds.date.DateService; -import org.jclouds.encryption.EncryptionService; import org.jclouds.json.Json; import org.jclouds.logging.Logger.LoggerFactory; import org.jclouds.rest.HttpAsyncClient; @@ -43,7 +43,7 @@ public class UtilsImpl implements Utils { private final Json json; private final HttpClient simpleClient; private final HttpAsyncClient simpleAsyncClient; - private final EncryptionService encryption; + private final Crypto encryption; private final DateService date; private final ExecutorService userExecutor; private final ExecutorService ioExecutor; @@ -51,7 +51,7 @@ public class UtilsImpl implements Utils { @Inject protected UtilsImpl(Json json, HttpClient simpleClient, HttpAsyncClient simpleAsyncClient, - EncryptionService encryption, DateService date, + Crypto encryption, DateService date, @Named(Constants.PROPERTY_USER_THREADS) ExecutorService userThreads, @Named(Constants.PROPERTY_IO_WORKER_THREADS) ExecutorService ioThreads, LoggerFactory loggerFactory) { this.json = json; @@ -75,7 +75,7 @@ public class UtilsImpl implements Utils { } @Override - public EncryptionService encryption() { + public Crypto crypto() { return encryption; } @@ -85,7 +85,7 @@ public class UtilsImpl implements Utils { } @Override - public EncryptionService getEncryptionService() { + public Crypto getCrypto() { return encryption; } diff --git a/core/src/test/java/org/jclouds/concurrent/FutureExceptionParserTest.java b/core/src/test/java/org/jclouds/concurrent/FutureExceptionParserTest.java index 95200190ac..6d86db3b3c 100755 --- a/core/src/test/java/org/jclouds/concurrent/FutureExceptionParserTest.java +++ b/core/src/test/java/org/jclouds/concurrent/FutureExceptionParserTest.java @@ -18,8 +18,6 @@ */ package org.jclouds.concurrent; -import static org.jclouds.concurrent.ConcurrentUtils.makeListenable; -import static org.jclouds.concurrent.ConcurrentUtils.sameThreadExecutor; import static org.jclouds.util.Utils.propagateOrNull; import static org.testng.Assert.assertEquals; @@ -44,7 +42,7 @@ import com.google.common.util.concurrent.ListenableFuture; */ @Test(groups = "unit", testName = "concurrent.FutureExceptionParserTest") public class FutureExceptionParserTest { - ExecutorService executorService = sameThreadExecutor(); + ExecutorService executorService = MoreExecutors.sameThreadExecutor(); @Test public void testGet() throws InterruptedException, ExecutionException { @@ -72,7 +70,7 @@ public class FutureExceptionParserTest { @SuppressWarnings("unchecked") private Future createFuture(final Exception exception) { - ListenableFuture future = makeListenable(executorService.submit(new Callable() { + ListenableFuture future = Futures.makeListenable(executorService.submit(new Callable() { public String call() throws Exception { throw exception; diff --git a/core/src/test/java/org/jclouds/concurrent/ConcurrentUtilsTest.java b/core/src/test/java/org/jclouds/concurrent/FutureIterablesTest.java similarity index 87% rename from core/src/test/java/org/jclouds/concurrent/ConcurrentUtilsTest.java rename to core/src/test/java/org/jclouds/concurrent/FutureIterablesTest.java index bda6166be1..5fed948bc3 100644 --- a/core/src/test/java/org/jclouds/concurrent/ConcurrentUtilsTest.java +++ b/core/src/test/java/org/jclouds/concurrent/FutureIterablesTest.java @@ -18,9 +18,8 @@ */ package org.jclouds.concurrent; -import static org.jclouds.concurrent.ConcurrentUtils.sameThreadExecutor; import static java.util.concurrent.Executors.newCachedThreadPool; -import static org.jclouds.concurrent.ConcurrentUtils.awaitCompletion; +import static org.jclouds.concurrent.FutureIterables.awaitCompletion; import static org.jclouds.concurrent.FuturesTestingUtils.CALLABLE_DURATION; import static org.jclouds.concurrent.FuturesTestingUtils.COUNT; import static org.jclouds.concurrent.FuturesTestingUtils.FUDGE; @@ -31,19 +30,18 @@ import static org.testng.Assert.assertEquals; import java.util.Map; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; +import java.util.concurrent.Future; import org.jclouds.logging.Logger; import org.testng.annotations.Test; -import java.util.concurrent.Future; - /** - * Tests behavior of ConcurrentUtils + * Tests behavior of FutureIterables * * @author Adrian Cole */ -@Test(groups = "unit", sequential = true, testName = "concurrent.ConcurrentUtilsTest") -public class ConcurrentUtilsTest { +@Test(groups = "unit", sequential = true, testName = "concurrent.FutureIterablesTest") +public class FutureIterablesTest { public void testMakeListenableDoesntSerializeFutures() throws InterruptedException, ExecutionException { long expectedMax = CALLABLE_DURATION; @@ -51,7 +49,7 @@ public class ConcurrentUtilsTest { long expectedOverhead = COUNT + FUDGE; ExecutorService callableExecutor = newCachedThreadPool(); - ExecutorService chainExecutor = sameThreadExecutor(); + ExecutorService chainExecutor = MoreExecutors.sameThreadExecutor(); long start = System.currentTimeMillis(); Map> responses = runCallables(callableExecutor, chainExecutor); @@ -65,11 +63,11 @@ public class ConcurrentUtilsTest { long expectedOverhead = COUNT + FUDGE; ExecutorService callableExecutor = newCachedThreadPool(); - ExecutorService chainExecutor = sameThreadExecutor(); + ExecutorService chainExecutor = MoreExecutors.sameThreadExecutor(); long start = System.currentTimeMillis(); Map> responses = runCallables(callableExecutor, chainExecutor); - Map exceptions = awaitCompletion(responses, sameThreadExecutor(), null, Logger.CONSOLE, + Map exceptions = awaitCompletion(responses, MoreExecutors.sameThreadExecutor(), null, Logger.CONSOLE, "test same thread"); assertEquals(exceptions.size(), 0); checkTimeThresholds(expectedMin, expectedMax, expectedOverhead, start, responses); diff --git a/core/src/test/java/org/jclouds/concurrent/FuturesComposePerformanceTest.java b/core/src/test/java/org/jclouds/concurrent/FuturesComposePerformanceTest.java index 0efef0dba0..cf0fbd3938 100644 --- a/core/src/test/java/org/jclouds/concurrent/FuturesComposePerformanceTest.java +++ b/core/src/test/java/org/jclouds/concurrent/FuturesComposePerformanceTest.java @@ -19,7 +19,6 @@ package org.jclouds.concurrent; import static java.util.concurrent.Executors.newCachedThreadPool; -import static org.jclouds.concurrent.ConcurrentUtils.sameThreadExecutor; import static org.jclouds.concurrent.FuturesTestingUtils.CALLABLE_DURATION; import static org.jclouds.concurrent.FuturesTestingUtils.COUNT; import static org.jclouds.concurrent.FuturesTestingUtils.FUDGE; @@ -93,7 +92,7 @@ public class FuturesComposePerformanceTest { ExecutorService userthreads = newCachedThreadPool(); try { ExecutorService chainExecutor = userthreads; - ExecutorService listenerExecutor = sameThreadExecutor(); + ExecutorService listenerExecutor = MoreExecutors.sameThreadExecutor(); checkThresholdsUsingFuturesCompose(expectedMin, expectedMax, expectedOverhead, callableExecutor, chainExecutor, listenerExecutor); @@ -110,7 +109,7 @@ public class FuturesComposePerformanceTest { ExecutorService userthreads = newCachedThreadPool(); try { - ExecutorService chainExecutor = sameThreadExecutor(); + ExecutorService chainExecutor = MoreExecutors.sameThreadExecutor(); ExecutorService listenerExecutor = userthreads; checkThresholdsUsingFuturesCompose(expectedMin, expectedMax, expectedOverhead, callableExecutor, @@ -129,8 +128,8 @@ public class FuturesComposePerformanceTest { ExecutorService userthreads = newCachedThreadPool(); try { - ExecutorService chainExecutor = sameThreadExecutor(); - ExecutorService listenerExecutor = sameThreadExecutor(); + ExecutorService chainExecutor = MoreExecutors.sameThreadExecutor(); + ExecutorService listenerExecutor = MoreExecutors.sameThreadExecutor(); checkThresholdsUsingFuturesCompose(expectedMin, expectedMax, expectedOverhead, callableExecutor, chainExecutor, listenerExecutor); @@ -166,7 +165,7 @@ public class FuturesComposePerformanceTest { ExecutorService userthreads = newCachedThreadPool(); try { ExecutorService chainExecutor = userthreads; - ExecutorService listenerExecutor = sameThreadExecutor(); + ExecutorService listenerExecutor = MoreExecutors.sameThreadExecutor(); checkThresholdsUsingConcurrentUtilsCompose(expectedMin, expectedMax, expectedOverhead, callableExecutor, chainExecutor, listenerExecutor); @@ -183,7 +182,7 @@ public class FuturesComposePerformanceTest { ExecutorService userthreads = newCachedThreadPool(); try { - ExecutorService chainExecutor = sameThreadExecutor(); + ExecutorService chainExecutor = MoreExecutors.sameThreadExecutor(); ExecutorService listenerExecutor = userthreads; checkThresholdsUsingConcurrentUtilsCompose(expectedMin, expectedMax, expectedOverhead, callableExecutor, @@ -202,8 +201,8 @@ public class FuturesComposePerformanceTest { ExecutorService userthreads = newCachedThreadPool(); try { - ExecutorService chainExecutor = sameThreadExecutor(); - ExecutorService listenerExecutor = sameThreadExecutor(); + ExecutorService chainExecutor = MoreExecutors.sameThreadExecutor(); + ExecutorService listenerExecutor = MoreExecutors.sameThreadExecutor(); checkThresholdsUsingConcurrentUtilsCompose(expectedMin, expectedMax, expectedOverhead, callableExecutor, chainExecutor, listenerExecutor); diff --git a/core/src/test/java/org/jclouds/concurrent/FuturesTestingUtils.java b/core/src/test/java/org/jclouds/concurrent/FuturesTestingUtils.java index a4d29968ec..10cfdb3b57 100644 --- a/core/src/test/java/org/jclouds/concurrent/FuturesTestingUtils.java +++ b/core/src/test/java/org/jclouds/concurrent/FuturesTestingUtils.java @@ -20,8 +20,6 @@ package org.jclouds.concurrent; import static com.google.common.base.Throwables.propagate; import static com.google.common.collect.Maps.newHashMap; -import static org.jclouds.concurrent.ConcurrentUtils.compose; -import static org.jclouds.concurrent.ConcurrentUtils.makeListenable; import java.util.Collections; import java.util.Map; @@ -75,7 +73,7 @@ public class FuturesTestingUtils { long start = System.currentTimeMillis(); Map> responses = newHashMap(); for (int i = 0; i < COUNT; i++) - responses.put(i + "", compose(createFuture(callableExecutor, chainExecutor), new Function() { + responses.put(i + "", org.jclouds.concurrent.Futures.compose(createFuture(callableExecutor, chainExecutor), new Function() { @Override public Long apply(Long from) { @@ -99,7 +97,7 @@ public class FuturesTestingUtils { } private static ListenableFuture createFuture(ExecutorService callableExecutor, ExecutorService chainExecutor) { - return makeListenable(callableExecutor.submit(new Callable() { + return org.jclouds.concurrent.Futures.makeListenable(callableExecutor.submit(new Callable() { @Override public Long call() throws Exception { diff --git a/core/src/test/java/org/jclouds/concurrent/RetryOnTimeOutExceptionSupplierTest.java b/core/src/test/java/org/jclouds/concurrent/RetryOnTimeOutExceptionSupplierTest.java index 9fdf78dca6..36618dfaf8 100644 --- a/core/src/test/java/org/jclouds/concurrent/RetryOnTimeOutExceptionSupplierTest.java +++ b/core/src/test/java/org/jclouds/concurrent/RetryOnTimeOutExceptionSupplierTest.java @@ -18,7 +18,6 @@ */ package org.jclouds.concurrent; -import static org.jclouds.concurrent.ConcurrentUtils.sameThreadExecutor; import static org.easymock.EasyMock.expect; import static org.easymock.classextension.EasyMock.createMock; import static org.easymock.classextension.EasyMock.replay; @@ -41,7 +40,7 @@ import com.google.common.base.Supplier; */ @Test(groups = "unit", testName = "concurrent.RetryOnTimeOutExceptionSupplierTest") public class RetryOnTimeOutExceptionSupplierTest { - ExecutorService executorService = sameThreadExecutor(); + ExecutorService executorService = MoreExecutors.sameThreadExecutor(); @SuppressWarnings("unchecked") @Test diff --git a/core/src/test/java/org/jclouds/concurrent/internal/SyncProxyTest.java b/core/src/test/java/org/jclouds/concurrent/internal/SyncProxyTest.java index 2f8c75594c..79b2c2485a 100644 --- a/core/src/test/java/org/jclouds/concurrent/internal/SyncProxyTest.java +++ b/core/src/test/java/org/jclouds/concurrent/internal/SyncProxyTest.java @@ -29,7 +29,7 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; -import static org.jclouds.concurrent.ConcurrentUtils.*; +import org.jclouds.concurrent.Futures; import org.jclouds.concurrent.Timeout; import org.jclouds.internal.ClassMethodArgs; import org.testng.annotations.BeforeTest; @@ -78,7 +78,7 @@ public class SyncProxyTest { } public ListenableFuture getString() { - return makeListenable(executorService.submit(new Callable() { + return Futures.makeListenable(executorService.submit(new Callable() { public String call() throws Exception { return "foo"; @@ -88,7 +88,7 @@ public class SyncProxyTest { } public ListenableFuture getRuntimeException() { - return makeListenable(executorService.submit(new Callable() { + return Futures.makeListenable(executorService.submit(new Callable() { public String call() throws Exception { throw new RuntimeException(); @@ -98,7 +98,7 @@ public class SyncProxyTest { } public ListenableFuture getTypedException() throws FileNotFoundException { - return makeListenable(executorService.submit(new Callable() { + return Futures.makeListenable(executorService.submit(new Callable() { public String call() throws FileNotFoundException { throw new FileNotFoundException(); @@ -112,7 +112,7 @@ public class SyncProxyTest { } public ListenableFuture take20Milliseconds() { - return makeListenable(executorService.submit(new Callable() { + return Futures.makeListenable(executorService.submit(new Callable() { public String call() { try { @@ -127,7 +127,7 @@ public class SyncProxyTest { } public ListenableFuture take100MillisecondsAndTimeout() { - return makeListenable(executorService.submit(new Callable() { + return Futures.makeListenable(executorService.submit(new Callable() { public String call() { try { diff --git a/core/src/test/java/org/jclouds/crypto/CryptoStreamsTest.java b/core/src/test/java/org/jclouds/crypto/CryptoStreamsTest.java new file mode 100644 index 0000000000..f142e687e0 --- /dev/null +++ b/core/src/test/java/org/jclouds/crypto/CryptoStreamsTest.java @@ -0,0 +1,65 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ==================================================================== + */ +package org.jclouds.crypto; + +import static org.testng.Assert.assertEquals; + +import java.io.IOException; + +import org.jclouds.io.Payloads; +import org.testng.annotations.Test; + +import com.google.common.base.Charsets; + +/** + * + * @author Adrian Cole + */ +@Test(groups = "unit", sequential = true, testName = "jclouds.CryptoStreamsTest") +public class CryptoStreamsTest { + + @Test + public void testBase64Encode() throws IOException { + + String encoded = CryptoStreams.base64Encode(Payloads.newStringPayload("hello world")); + assertEquals(encoded, "aGVsbG8gd29ybGQ="); + } + + @Test + public void testBase64Decode() throws IOException { + + byte[] decoded = CryptoStreams.base64Decode(Payloads.newStringPayload("aGVsbG8gd29ybGQ=")); + assertEquals(new String(decoded, Charsets.UTF_8), "hello world"); + } + + @Test + public void testHexEncode() throws IOException { + + String encoded = CryptoStreams.hexEncode(Payloads.newStringPayload("hello world")); + assertEquals(encoded, "68656c6c6f20776f726c64"); + } + + @Test + public void testHexDecode() throws IOException { + + byte[] decoded = CryptoStreams.hexDecode(Payloads.newStringPayload("68656c6c6f20776f726c64")); + assertEquals(new String(decoded, Charsets.UTF_8), "hello world"); + } + +} diff --git a/core/src/test/java/org/jclouds/crypto/PemsTest.java b/core/src/test/java/org/jclouds/crypto/PemsTest.java new file mode 100644 index 0000000000..c74615e034 --- /dev/null +++ b/core/src/test/java/org/jclouds/crypto/PemsTest.java @@ -0,0 +1,91 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ==================================================================== + */ +package org.jclouds.crypto; + +import static org.testng.Assert.assertEquals; + +import java.io.IOException; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.cert.CertificateException; +import java.security.cert.CertificateFactory; +import java.security.spec.InvalidKeySpecException; + +import org.jclouds.io.Payloads; +import org.testng.annotations.Test; + +/** + * + * @author Adrian Cole + */ +@Test(groups = "unit", sequential = true, testName = "jclouds.PemsTest") +public class PemsTest { + + public static final String PRIVATE_KEY = "-----BEGIN RSA PRIVATE KEY-----\nMIIEpQIBAAKCAQEAyb2ZJJqGm0KKR+8nfQJNsSd+F9tXNMV7CfOcW6jsqs8EZgiV\nR09hD1IYOj4YqM0qJONlgyg4xRWewdSG7QTPj1lJpVAida9sXy2+kzyagZA1Am0O\nZcbqb5hoeIDgcX+eDa79s0u0DomjcfO9EKhvHLBz+zM+3QqPRkPV8nYTbfs+HjVz\nzOU6D1B0XR3+IPZZl2AnWs2d0qhnStHcDUvnRVQ0P482YwN9VgceOZtpPz0DCKEJ\n5Tx5STub8k0/zt/VAMHQafLSuQMLd2s4ZLuOZptN//uAsTmxireqd37z+8ZTdBbJ\n8LEpJ+iCXuSfm5aUh7iw6oxvToY2AL53+jK2UQIDAQABAoIBAQDA88B3i/xWn0vX\nBVxFamCYoecuNjGwXXkSyZew616A+EOCu47bh4aTurdFbYL0YFaAtaWvzlaN2eHg\nDb+HDuTefE29+WkcGk6SshPmiz5T0XOCAICWw6wSVDkHmGwS4jZvbAFm7W8nwGk9\nYhxgxFiRngswJZFopOLoF5WXs2td8guIYNslMpo7tu50iFnBHwKO2ZsPAk8t9nnS\nxlDavKruymEmqHCr3+dtio5eaenJcp3fjoXBQOKUk3ipII29XRB8NqeCVV/7Kxwq\nckqOBEbRwBclckyIbD+RiAgKvOelORjEiE9R42vuqvxRA6k9kd9o7utlX0AUtpEn\n3gZc6LepAoGBAP9ael5Y75+sK2JJUNOOhO8ae45cdsilp2yI0X+UBaSuQs2+dyPp\nkpEHAxd4pmmSvn/8c9TlEZhr+qYbABXVPlDncxpIuw2Ajbk7s/S4XaSKsRqpXL57\nzj/QOqLkRk8+OVV9q6lMeQNqLtEj1u6JPviX70Ro+FQtRttNOYbfdP/fAoGBAMpA\nXjR5woV5sUb+REg9vEuYo8RSyOarxqKFCIXVUNsLOx+22+AK4+CQpbueWN7jotrl\nYD6uT6svWi3AAC7kiY0UI/fjVPRCUi8tVoQUE0TaU5VLITaYOB+W/bBaDE4M9560\n1NuDWO90baA5dfU44iuzva02rGJXK9+nS3o8nk/PAoGBALOL6djnDe4mwAaG6Jco\ncd4xr8jkyPzCRZuyBCSBbwphIUXLc7hDprPky064ncJD1UDmwIdkXd/fpMkg2QmA\n/CUk6LEFjMisqHojOaCL9gQZJPhLN5QUN2x1PJWGjs1vQh8Tkx0iUUCOa8bQPXNR\n+34OTsW6TUna4CSZAycLfhffAoGBAIggVsefBCvuQkF0NeUhmDCRZfhnd8y55RHR\n1HCvqKIlpv+rhcX/zmyBLuteopYyRJRsOiE2FW00i8+rIPRu4Z3Q5nybx7w3PzV9\noHN5R5baE9OyI4KpZWztpYYitZF67NcnAvVULHHOvVJQGnKYfLHJYmrJF7GA1ojM\nAuMdFbjFAoGAPxUhxwFy8gaqBahKUEZn4F81HFP5ihGhkT4QL6AFPO2e+JhIGjuR\n27+85hcFqQ+HHVtFsm81b/a+R7P4UuCRgc8eCjxQMoJ1Xl4n7VbjPbHMnIN0Ryvd\nO4ZpWDWYnCO021JTOUUOJ4J/y0416Bvkw0z59y7sNX7wDBBHHbK/XCc=\n-----END RSA PRIVATE KEY-----\n"; + + public static final String PUBLIC_KEY = "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyb2ZJJqGm0KKR+8nfQJNsSd+F9tXNMV7CfOcW6jsqs8EZgiVR09hD1IYOj4YqM0qJONlgyg4xRWewdSG7QTPj1lJpVAida9sXy2+kzyagZA1Am0OZcbqb5hoeIDgcX+eDa79s0u0DomjcfO9EKhvHLBz+zM+3QqPRkPV8nYTbfs+HjVzzOU6D1B0XR3+IPZZl2AnWs2d0qhnStHcDUvnRVQ0P482YwN9VgceOZtpPz0DCKEJ5Tx5STub8k0/zt/VAMHQafLSuQMLd2s4ZLuOZptN//uAsTmxireqd37z+8ZTdBbJ8LEpJ+iCXuSfm5aUh7iw6oxvToY2AL53+jK2UQIDAQAB\n-----END PUBLIC KEY-----\n"; + + private static final String CERTIFICATE = "-----BEGIN CERTIFICATE-----\nMIIClzCCAgCgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBnjELMAkGA1UEBhMCVVMx\nEzARBgNVBAgMCldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUxFjAUBgNVBAoM\nDU9wc2NvZGUsIEluYy4xHDAaBgNVBAsME0NlcnRpZmljYXRlIFNlcnZpY2UxMjAw\nBgNVBAMMKW9wc2NvZGUuY29tL2VtYWlsQWRkcmVzcz1hdXRoQG9wc2NvZGUuY29t\nMB4XDTEwMDczMDIwNDEzMFoXDTIwMDcyNzIwNDEzMFowADCCASIwDQYJKoZIhvcN\nAQEBBQADggEPADCCAQoCggEBAMm9mSSahptCikfvJ30CTbEnfhfbVzTFewnznFuo\n7KrPBGYIlUdPYQ9SGDo+GKjNKiTjZYMoOMUVnsHUhu0Ez49ZSaVQInWvbF8tvpM8\nmoGQNQJtDmXG6m+YaHiA4HF/ng2u/bNLtA6Jo3HzvRCobxywc/szPt0Kj0ZD1fJ2\nE237Ph41c8zlOg9QdF0d/iD2WZdgJ1rNndKoZ0rR3A1L50VUND+PNmMDfVYHHjmb\naT89AwihCeU8eUk7m/JNP87f1QDB0Gny0rkDC3drOGS7jmabTf/7gLE5sYq3qnd+\n8/vGU3QWyfCxKSfogl7kn5uWlIe4sOqMb06GNgC+d/oytlECAwEAATANBgkqhkiG\n9w0BAQUFAAOBgQBftzSZxstWw60GqRTDNN/F2GnrdtnKBoXzHww3r6jtGEylYq20\n5KfKpEx+sPX0gyZuYJiXC2CkEjImAluWKcdN9ZF6VD541sheAjbiaU7q7ZsztTxF\nWUH2tCvHeDXYKPKek3QzL7bYpUhLnCN/XxEv6ibeMDwtI7f5qpk2Aspzcw==\n-----END CERTIFICATE-----\n"; + + @Test + public void testPrivateKeySpecFromPem() throws IOException { + Pems.privateKeySpec(Payloads.newStringPayload(PRIVATE_KEY)); + } + + @Test + public void testPublicKeySpecFromPem() throws IOException { + Pems.publicKeySpec(Payloads.newStringPayload(PUBLIC_KEY)); + } + + @Test + public void testX509CertificateFromPemDefault() throws IOException, CertificateException { + Pems.x509Certificate(Payloads.newStringPayload(CERTIFICATE), null); + } + + @Test + public void testX509CertificateFromPemSuppliedCertFactory() throws IOException, CertificateException { + Pems.x509Certificate(Payloads.newStringPayload(CERTIFICATE), CertificateFactory.getInstance("X.509")); + } + + @Test(enabled = false) + // TODO figure out how to write back in the same format + public void testPrivateKeySpecPem() throws IOException, InvalidKeySpecException, NoSuchAlgorithmException { + String encoded = Pems.pem(KeyFactory.getInstance("RSA").generatePrivate( + Pems.privateKeySpec(Payloads.newStringPayload(PRIVATE_KEY)))); + assertEquals(encoded, PRIVATE_KEY.replaceAll("\n", "").replaceAll("Y-----", "Y-----\n").replaceAll("-----E", + "\n-----E")); + } + + @Test + public void testPublicKeySpecPem() throws IOException, InvalidKeySpecException, NoSuchAlgorithmException { + String encoded = Pems.pem(KeyFactory.getInstance("RSA").generatePublic( + Pems.publicKeySpec(Payloads.newStringPayload(PUBLIC_KEY)))); + assertEquals(encoded, PUBLIC_KEY.replaceAll("\n", "").replaceAll("Y-----", "Y-----\n").replaceAll("-----E", + "\n-----E")); + } + + @Test + public void testX509CertificatePem() throws IOException, CertificateException { + String encoded = Pems.pem(Pems.x509Certificate(Payloads.newStringPayload(CERTIFICATE), CertificateFactory + .getInstance("X.509"))); + assertEquals(encoded, CERTIFICATE.replaceAll("\n", "").replaceAll("E-----", "E-----\n").replaceAll("-----E", + "\n-----E")); + } + +} diff --git a/core/src/test/java/org/jclouds/http/BaseHttpCommandExecutorServiceIntegrationTest.java b/core/src/test/java/org/jclouds/http/BaseHttpCommandExecutorServiceIntegrationTest.java index 52fde6a4e2..a06868f4b1 100644 --- a/core/src/test/java/org/jclouds/http/BaseHttpCommandExecutorServiceIntegrationTest.java +++ b/core/src/test/java/org/jclouds/http/BaseHttpCommandExecutorServiceIntegrationTest.java @@ -35,7 +35,9 @@ import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicInteger; +import org.jclouds.crypto.CryptoStreams; import org.jclouds.http.options.GetOptions; +import org.jclouds.io.InputSuppliers; import org.jclouds.util.Utils; import org.testng.annotations.BeforeTest; import org.testng.annotations.DataProvider; @@ -54,62 +56,59 @@ import com.google.common.io.Closeables; public abstract class BaseHttpCommandExecutorServiceIntegrationTest extends BaseJettyTest { @Test(invocationCount = 25, timeOut = 5000) - public void testRequestFilter() throws MalformedURLException, ExecutionException, - InterruptedException, TimeoutException { + public void testRequestFilter() throws MalformedURLException, ExecutionException, InterruptedException, + TimeoutException { assertEquals(client.downloadFilter("", "filterme").trim(), "test"); } // TODO: filtering redirect test @Test(invocationCount = 25, timeOut = 5000) - public void testGetStringWithHeader() throws MalformedURLException, ExecutionException, - InterruptedException, TimeoutException { + public void testGetStringWithHeader() throws MalformedURLException, ExecutionException, InterruptedException, + TimeoutException { assertEquals(client.download("", "test").trim(), "test"); } @Test(invocationCount = 25, timeOut = 5000) - public void testGetString() throws MalformedURLException, ExecutionException, - InterruptedException, TimeoutException { + public void testGetString() throws MalformedURLException, ExecutionException, InterruptedException, TimeoutException { assertEquals(client.download("").trim(), XML); } @DataProvider(name = "gets") public Object[][] createData() { - return new Object[][] { { "object" }, { "/path" }, { "sp ace" }, { "unic₪de" }, - { "qu?stion" } }; + return new Object[][] { { "object" }, { "/path" }, { "sp ace" }, { "unic₪de" }, { "qu?stion" } }; } @Test(invocationCount = 25, timeOut = 5000, dataProvider = "gets") - public void testGetStringSynch(String uri) throws MalformedURLException, ExecutionException, - InterruptedException, TimeoutException { + public void testGetStringSynch(String uri) throws MalformedURLException, ExecutionException, InterruptedException, + TimeoutException { // TODO why need trim? assertEquals(client.synch(uri).trim(), XML); } @Test(invocationCount = 25, timeOut = 5000) - public void testGetException() throws MalformedURLException, ExecutionException, - InterruptedException, TimeoutException { + public void testGetException() throws MalformedURLException, ExecutionException, InterruptedException, + TimeoutException { assertEquals(client.downloadException("", GetOptions.Builder.tail(1)).trim(), "foo"); } @Test(invocationCount = 25, timeOut = 5000) - public void testGetSynchException() throws MalformedURLException, ExecutionException, - InterruptedException, TimeoutException { + public void testGetSynchException() throws MalformedURLException, ExecutionException, InterruptedException, + TimeoutException { assertEquals(client.synchException("", "").trim(), "foo"); } @Test(invocationCount = 25, timeOut = 5000) - public void testGetStringRedirect() throws MalformedURLException, ExecutionException, - InterruptedException, TimeoutException { + public void testGetStringRedirect() throws MalformedURLException, ExecutionException, InterruptedException, + TimeoutException { assertEquals(client.download("redirect").trim(), XML2); } @Test(invocationCount = 100, timeOut = 5000) - public void testGetBigFile() throws ExecutionException, InterruptedException, TimeoutException, - IOException { + public void testGetBigFile() throws ExecutionException, InterruptedException, TimeoutException, IOException { InputStream input = getConsitution(); try { - assertEquals(encryptionService.base64(encryptionService.md5(input)), md5); + assertEquals(CryptoStreams.md5Base64(InputSuppliers.of(input)), md5); } catch (RuntimeException e) { Closeables.closeQuietly(input); // since we are parsing client side, and not through a response handler, the user @@ -117,7 +116,7 @@ public abstract class BaseHttpCommandExecutorServiceIntegrationTest extends Base // twice in the same spot. if (Utils.getFirstThrowableOfType(e, IOException.class) != null) { input = getConsitution(); - assertEquals(encryptionService.base64(encryptionService.md5(input)), md5); + assertEquals(CryptoStreams.md5Base64(InputSuppliers.of(input)), md5); } } } @@ -129,8 +128,8 @@ public abstract class BaseHttpCommandExecutorServiceIntegrationTest extends Base } @Test(enabled = false, invocationCount = 25, timeOut = 5000) - public void testGetStringPermanentRedirect() throws MalformedURLException, ExecutionException, - InterruptedException, TimeoutException { + public void testGetStringPermanentRedirect() throws MalformedURLException, ExecutionException, InterruptedException, + TimeoutException { // GetString get = factory.createGetString("permanentredirect"); // assert get != null; // client.submit(get); @@ -140,14 +139,13 @@ public abstract class BaseHttpCommandExecutorServiceIntegrationTest extends Base } @Test(invocationCount = 25, timeOut = 5000) - public void testPost() throws MalformedURLException, ExecutionException, InterruptedException, - TimeoutException { + public void testPost() throws MalformedURLException, ExecutionException, InterruptedException, TimeoutException { assertEquals(client.post("", "foo").trim(), "fooPOST"); } @Test(invocationCount = 25, timeOut = 10000) - public void testPostAsInputStream() throws MalformedURLException, ExecutionException, - InterruptedException, TimeoutException { + public void testPostAsInputStream() throws MalformedURLException, ExecutionException, InterruptedException, + TimeoutException { try { assertEquals(client.postAsInputStream("", "foo").trim(), "fooPOST"); } catch (Exception e) { @@ -193,9 +191,8 @@ public abstract class BaseHttpCommandExecutorServiceIntegrationTest extends Base } // upload and verify the response - assertEquals(client.postWithMd5("fileso", this.encryptionService.base64(eTag.digest()), f) + assertEquals(client.postWithMd5("fileso", CryptoStreams.base64Encode(InputSuppliers.of(eTag.digest())), f) .trim(), "created"); - } finally { if (os != null) os.close(); @@ -218,39 +215,36 @@ public abstract class BaseHttpCommandExecutorServiceIntegrationTest extends Base } @Test(invocationCount = 25, timeOut = 5000) - public void testPostBinder() throws MalformedURLException, ExecutionException, - InterruptedException, TimeoutException { + public void testPostBinder() throws MalformedURLException, ExecutionException, InterruptedException, + TimeoutException { assertEquals(client.postJson("", "foo").trim(), "{\"key\":\"foo\"}POST"); } @Test(invocationCount = 25, timeOut = 5000) - public void testPut() throws MalformedURLException, ExecutionException, InterruptedException, - TimeoutException { + public void testPut() throws MalformedURLException, ExecutionException, InterruptedException, TimeoutException { assertEquals(client.upload("", "foo").trim(), "fooPUT"); } @Test(invocationCount = 25, timeOut = 5000) - public void testPutRedirect() throws MalformedURLException, ExecutionException, - InterruptedException, TimeoutException { + public void testPutRedirect() throws MalformedURLException, ExecutionException, InterruptedException, + TimeoutException { assertEquals(client.upload("redirect", "foo").trim(), "fooPUTREDIRECT"); } @Test(invocationCount = 25, timeOut = 5000) - public void testKillRobotSlowly() throws MalformedURLException, ExecutionException, - InterruptedException, TimeoutException { - assertEquals(client.action("robot", "kill", ImmutableMap.of("death", "slow")).trim(), - "robot->kill:{death=slow}"); + public void testKillRobotSlowly() throws MalformedURLException, ExecutionException, InterruptedException, + TimeoutException { + assertEquals(client.action("robot", "kill", ImmutableMap.of("death", "slow")).trim(), "robot->kill:{death=slow}"); } @Test(invocationCount = 25, timeOut = 5000) - public void testHead() throws MalformedURLException, ExecutionException, InterruptedException, - TimeoutException { + public void testHead() throws MalformedURLException, ExecutionException, InterruptedException, TimeoutException { assert client.exists(""); } @Test(invocationCount = 25, timeOut = 5000) - public void testGetAndParseSax() throws MalformedURLException, ExecutionException, - InterruptedException, TimeoutException { + public void testGetAndParseSax() throws MalformedURLException, ExecutionException, InterruptedException, + TimeoutException { assertEquals(client.downloadAndParse(""), "whoppers"); } } diff --git a/core/src/test/java/org/jclouds/http/BaseJettyTest.java b/core/src/test/java/org/jclouds/http/BaseJettyTest.java index 2a57046f6a..7d11af34f6 100644 --- a/core/src/test/java/org/jclouds/http/BaseJettyTest.java +++ b/core/src/test/java/org/jclouds/http/BaseJettyTest.java @@ -18,8 +18,16 @@ */ package org.jclouds.http; +import static com.google.common.base.Throwables.propagate; +import static com.google.common.collect.Maps.newHashMap; +import static com.google.common.io.ByteStreams.copy; +import static com.google.common.io.ByteStreams.join; +import static com.google.common.io.ByteStreams.newInputStreamSupplier; +import static com.google.common.io.ByteStreams.toByteArray; +import static javax.ws.rs.core.HttpHeaders.CONTENT_LENGTH; import static org.jclouds.rest.RestContextFactory.contextSpec; import static org.jclouds.rest.RestContextFactory.createContextBuilder; +import static org.jclouds.util.Utils.toStringAndClose; import java.io.ByteArrayInputStream; import java.io.IOException; @@ -34,14 +42,12 @@ import java.util.zip.GZIPInputStream; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import javax.ws.rs.core.HttpHeaders; -import org.jclouds.encryption.EncryptionService; -import org.jclouds.encryption.internal.Base64; +import org.jclouds.crypto.CryptoStreams; +import org.jclouds.io.InputSuppliers; import org.jclouds.rest.RestContext; import org.jclouds.rest.RestContextBuilder; import org.jclouds.rest.RestContextFactory.ContextSpec; -import org.jclouds.util.Utils; import org.mortbay.jetty.Handler; import org.mortbay.jetty.Request; import org.mortbay.jetty.Server; @@ -51,12 +57,8 @@ import org.testng.annotations.BeforeTest; import org.testng.annotations.Optional; import org.testng.annotations.Parameters; -import com.google.common.base.Throwables; import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Maps; -import com.google.common.io.ByteStreams; import com.google.common.io.InputSupplier; -import com.google.inject.Guice; import com.google.inject.Injector; import com.google.inject.Module; @@ -72,7 +74,6 @@ public abstract class BaseJettyTest { private Server server2; protected RestContext context; protected int testPort; - protected EncryptionService encryptionService; protected String md5; static final Pattern actionPattern = Pattern.compile("/objects/(.*)/action/([a-z]*);?(.*)"); @@ -83,9 +84,7 @@ public abstract class BaseJettyTest { final InputSupplier oneHundredOneConstitutions = getTestDataSupplier(); - encryptionService = Guice.createInjector().getInstance(EncryptionService.class); - - md5 = encryptionService.base64(encryptionService.md5(oneHundredOneConstitutions.getInput())); + md5 = CryptoStreams.md5Base64(oneHundredOneConstitutions); Handler server1Handler = new AbstractHandler() { public void handle(String target, HttpServletRequest request, HttpServletResponse response, int dispatch) @@ -96,7 +95,7 @@ public abstract class BaseJettyTest { try { Thread.sleep(100); } catch (InterruptedException e) { - Throwables.propagate(e); + propagate(e); } response.setContentType("text/xml"); response.setStatus(HttpServletResponse.SC_OK); @@ -106,11 +105,11 @@ public abstract class BaseJettyTest { response.setContentType("text/plain"); response.setHeader("Content-MD5", md5); response.setStatus(HttpServletResponse.SC_OK); - ByteStreams.copy(oneHundredOneConstitutions.getInput(), response.getOutputStream()); + copy(oneHundredOneConstitutions.getInput(), response.getOutputStream()); } else if (request.getMethod().equals("PUT")) { if (request.getContentLength() > 0) { response.setStatus(HttpServletResponse.SC_OK); - response.getWriter().println(Utils.toStringAndClose(request.getInputStream()) + "PUT"); + response.getWriter().println(toStringAndClose(request.getInputStream()) + "PUT"); } else { response.sendError(500, "no content"); } @@ -122,7 +121,7 @@ public abstract class BaseJettyTest { if (request.getContentLength() > 0) { if (request.getHeader("Content-MD5") != null) { String expectedMd5 = request.getHeader("Content-MD5"); - String realMd5FromRequest = Base64.encodeBytes(encryptionService.md5(request.getInputStream())); + String realMd5FromRequest = CryptoStreams.md5Base64(InputSuppliers.of(request.getInputStream())); boolean matched = expectedMd5.equals(realMd5FromRequest); if (matched) { response.setContentType("text/xml"); @@ -131,7 +130,7 @@ public abstract class BaseJettyTest { } } else { response.setStatus(HttpServletResponse.SC_OK); - response.getWriter().println(Utils.toStringAndClose(request.getInputStream()) + "POST"); + response.getWriter().println(toStringAndClose(request.getInputStream()) + "POST"); } } else { handleAction(request, response); @@ -170,14 +169,14 @@ public abstract class BaseJettyTest { if (request.getMethod().equals("PUT")) { if (request.getContentLength() > 0) { response.setStatus(HttpServletResponse.SC_OK); - response.getWriter().println(Utils.toStringAndClose(request.getInputStream()) + "PUTREDIRECT"); + response.getWriter().println(toStringAndClose(request.getInputStream()) + "PUTREDIRECT"); } } else if (request.getMethod().equals("POST")) { if (request.getContentLength() > 0) { if (request.getHeader("Content-MD5") != null) { String expectedMd5 = request.getHeader("Content-MD5"); String realMd5FromRequest; - realMd5FromRequest = Base64.encodeBytes(encryptionService.md5(request.getInputStream())); + realMd5FromRequest = CryptoStreams.md5Base64(InputSuppliers.of(request.getInputStream())); boolean matched = expectedMd5.equals(realMd5FromRequest); if (matched) { response.setContentType("text/xml"); @@ -186,7 +185,7 @@ public abstract class BaseJettyTest { } } else { response.setStatus(HttpServletResponse.SC_OK); - response.getWriter().println(Utils.toStringAndClose(request.getInputStream()) + "POST"); + response.getWriter().println(toStringAndClose(request.getInputStream()) + "POST"); } } else { handleAction(request, response); @@ -221,14 +220,13 @@ public abstract class BaseJettyTest { @SuppressWarnings("unchecked") public static InputSupplier getTestDataSupplier() throws IOException { - byte[] oneConstitution = ByteStreams.toByteArray(new GZIPInputStream(BaseJettyTest.class - .getResourceAsStream("/const.txt.gz"))); - InputSupplier constitutionSupplier = ByteStreams.newInputStreamSupplier(oneConstitution); + byte[] oneConstitution = toByteArray(new GZIPInputStream(BaseJettyTest.class.getResourceAsStream("/const.txt.gz"))); + InputSupplier constitutionSupplier = newInputStreamSupplier(oneConstitution); - InputSupplier temp = ByteStreams.join(constitutionSupplier); + InputSupplier temp = join(constitutionSupplier); for (int i = 0; i < 100; i++) { - temp = ByteStreams.join(temp, constitutionSupplier); + temp = join(temp, constitutionSupplier); } return temp; } @@ -282,7 +280,7 @@ public abstract class BaseJettyTest { } protected boolean failIfNoContentLength(HttpServletRequest request, HttpServletResponse response) throws IOException { - if (request.getHeader(HttpHeaders.CONTENT_LENGTH) == null) { + if (request.getHeader(CONTENT_LENGTH) == null) { response.sendError(500); ((Request) request).setHandled(true); return true; @@ -296,7 +294,7 @@ public abstract class BaseJettyTest { if (matchFound) { String objectId = matcher.group(1); String action = matcher.group(2); - Map options = Maps.newHashMap(); + Map options = newHashMap(); if (matcher.groupCount() == 3) { String optionsGroup = matcher.group(3); for (String entry : optionsGroup.split(";")) { diff --git a/core/src/test/java/org/jclouds/http/filters/BasicAuthenticationTest.java b/core/src/test/java/org/jclouds/http/filters/BasicAuthenticationTest.java index 23a6fa8274..2ce3dd7418 100755 --- a/core/src/test/java/org/jclouds/http/filters/BasicAuthenticationTest.java +++ b/core/src/test/java/org/jclouds/http/filters/BasicAuthenticationTest.java @@ -27,7 +27,7 @@ import java.security.cert.CertificateException; import javax.ws.rs.core.HttpHeaders; -import org.jclouds.encryption.internal.JCEEncryptionService; +import org.jclouds.encryption.internal.JCECrypto; import org.jclouds.http.HttpRequest; import org.testng.annotations.Test; @@ -42,7 +42,7 @@ public class BasicAuthenticationTest { private static final String PASSWORD = "open sesame"; public void testAuth() throws UnsupportedEncodingException, NoSuchAlgorithmException, CertificateException { - BasicAuthentication filter = new BasicAuthentication(USER, PASSWORD, new JCEEncryptionService()); + BasicAuthentication filter = new BasicAuthentication(USER, PASSWORD, new JCECrypto(null)); HttpRequest request = new HttpRequest("GET", URI.create("http://localhost")); filter.filter(request); assertEquals(request.getFirstHeaderOrNull(HttpHeaders.AUTHORIZATION), "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ=="); diff --git a/core/src/test/java/org/jclouds/http/handlers/BackoffLimitedRetryHandlerTest.java b/core/src/test/java/org/jclouds/http/handlers/BackoffLimitedRetryHandlerTest.java index 89fbf8331f..7c4b094438 100644 --- a/core/src/test/java/org/jclouds/http/handlers/BackoffLimitedRetryHandlerTest.java +++ b/core/src/test/java/org/jclouds/http/handlers/BackoffLimitedRetryHandlerTest.java @@ -29,11 +29,11 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import javax.inject.Provider; +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.SSLSession; import javax.ws.rs.core.UriBuilder; import org.jboss.resteasy.specimpl.UriBuilderImpl; -import org.jclouds.encryption.EncryptionService; -import org.jclouds.encryption.internal.JCEEncryptionService; import org.jclouds.http.BaseJettyTest; import org.jclouds.http.HttpCommand; import org.jclouds.http.HttpResponse; @@ -107,12 +107,16 @@ public class BackoffLimitedRetryHandlerTest { void setupExecutorService() throws Exception { ExecutorService execService = Executors.newCachedThreadPool(); BackoffLimitedRetryHandler backoff = new BackoffLimitedRetryHandler(); - EncryptionService encService = new JCEEncryptionService(); - utils = new HttpUtils(encService, 0, 500, 1, 1); + utils = new HttpUtils(0, 500, 1, 1); RedirectionRetryHandler retry = new RedirectionRetryHandler(uriBuilderProvider, backoff); JavaUrlHttpCommandExecutorService httpService = new JavaUrlHttpCommandExecutorService(utils, execService, new DelegatingRetryHandler(backoff, retry), new BackoffLimitedRetryHandler(), - new DelegatingErrorHandler(), new HttpWire(), null, encService); + new DelegatingErrorHandler(), new HttpWire(), new HostnameVerifier(){ + + @Override + public boolean verify(String hostname, SSLSession session) { + return false; + }}); executorService = new TransformingHttpCommandExecutorServiceImpl(httpService, execService); } diff --git a/core/src/test/java/org/jclouds/http/internal/WireLiveTest.java b/core/src/test/java/org/jclouds/http/internal/WireLiveTest.java index d65b4ac475..702e144210 100644 --- a/core/src/test/java/org/jclouds/http/internal/WireLiveTest.java +++ b/core/src/test/java/org/jclouds/http/internal/WireLiveTest.java @@ -19,28 +19,23 @@ package org.jclouds.http.internal; import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.io.ByteStreams.copy; import static java.util.concurrent.Executors.newCachedThreadPool; import static org.testng.Assert.assertEquals; -import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.net.URL; import java.net.URLConnection; -import java.security.NoSuchAlgorithmException; -import java.security.cert.CertificateException; import java.util.concurrent.Callable; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; -import org.jclouds.encryption.EncryptionService; -import org.jclouds.encryption.internal.JCEEncryptionService; +import org.jclouds.crypto.CryptoStreams; +import org.jclouds.io.InputSuppliers; import org.jclouds.logging.Logger; import org.testng.annotations.Test; -import com.google.common.base.Throwables; -import com.google.common.io.ByteStreams; - /** * * @author Adrian Cole @@ -51,20 +46,6 @@ public class WireLiveTest { private static final String sysHttpStreamUrl = System.getProperty("jclouds.wire.httpstream.url"); private static final String sysHttpStreamMd5 = System.getProperty("jclouds.wire.httpstream.md5"); - private static EncryptionService encryptionService; - - static { - try { - encryptionService = new JCEEncryptionService(); - } catch (NoSuchAlgorithmException e) { - Throwables.propagate(e); - encryptionService = null; - } catch (CertificateException e) { - Throwables.propagate(e); - encryptionService = null; - } - } - private static class ConnectionTester implements Callable { private final InputStream fromServer; @@ -76,10 +57,10 @@ public class WireLiveTest { HttpWire wire = setUp(); InputStream in = wire.input(fromServer); ByteArrayOutputStream out = new ByteArrayOutputStream();// TODO - ByteStreams.copy(in, out); - byte[] compare = encryptionService.md5(new ByteArrayInputStream(out.toByteArray())); + copy(in, out); + byte[] compare = CryptoStreams.md5(out.toByteArray()); Thread.sleep(100); - assertEquals(encryptionService.hex(compare), checkNotNull(sysHttpStreamMd5, sysHttpStreamMd5)); + assertEquals(CryptoStreams.hex(compare), checkNotNull(sysHttpStreamMd5, sysHttpStreamMd5)); assertEquals(((BufferLogger) wire.getWireLog()).buff.toString().getBytes().length, 3331484); return null; } @@ -155,10 +136,10 @@ public class WireLiveTest { URL url = new URL(checkNotNull(sysHttpStreamUrl, "sysHttpStreamUrl")); URLConnection connection = url.openConnection(); HttpWire wire = setUp(); - InputStream in = wire.input(connection.getInputStream()); - byte[] compare = encryptionService.md5(in); + final InputStream in = wire.input(connection.getInputStream()); + byte[] compare = CryptoStreams.md5(InputSuppliers.of(in)); Thread.sleep(100); - assertEquals(encryptionService.hex(compare), checkNotNull(sysHttpStreamMd5, sysHttpStreamMd5)); + assertEquals(CryptoStreams.hex(compare), checkNotNull(sysHttpStreamMd5, sysHttpStreamMd5)); assertEquals(((BufferLogger) wire.getWireLog()).buff.toString().getBytes().length, 3331484); } @@ -176,10 +157,10 @@ public class WireLiveTest { URL url = new URL(checkNotNull(sysHttpStreamUrl, "sysHttpStreamUrl")); URLConnection connection = url.openConnection(); HttpWire wire = setUpSynch(); - InputStream in = wire.input(connection.getInputStream()); - byte[] compare = encryptionService.md5(in); + final InputStream in = wire.input(connection.getInputStream()); + byte[] compare = CryptoStreams.md5(InputSuppliers.of(in)); Thread.sleep(100); - assertEquals(encryptionService.hex(compare), checkNotNull(sysHttpStreamMd5, sysHttpStreamMd5)); + assertEquals(CryptoStreams.hex(compare), checkNotNull(sysHttpStreamMd5, sysHttpStreamMd5)); assertEquals(((BufferLogger) wire.getWireLog()).buff.toString().getBytes().length, 3331484); } diff --git a/core/src/test/java/org/jclouds/encryption/EncryptionServiceTest.java b/core/src/test/java/org/jclouds/io/CryptoTest.java similarity index 61% rename from core/src/test/java/org/jclouds/encryption/EncryptionServiceTest.java rename to core/src/test/java/org/jclouds/io/CryptoTest.java index 91be1b7183..d1a5084a87 100644 --- a/core/src/test/java/org/jclouds/encryption/EncryptionServiceTest.java +++ b/core/src/test/java/org/jclouds/io/CryptoTest.java @@ -16,14 +16,11 @@ * limitations under the License. * ==================================================================== */ -package org.jclouds.encryption; +package org.jclouds.io; import static org.testng.Assert.assertEquals; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; import java.io.IOException; -import java.io.UnsupportedEncodingException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; @@ -33,13 +30,13 @@ import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorCompletionService; import org.jclouds.PerformanceTest; -import org.jclouds.encryption.EncryptionService.MD5OutputStream; +import org.jclouds.crypto.Crypto; +import org.jclouds.crypto.CryptoStreams; import org.jclouds.encryption.internal.Base64; import org.testng.annotations.BeforeTest; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; -import com.google.common.io.ByteStreams; import com.google.inject.Guice; import com.google.inject.Injector; @@ -48,29 +45,25 @@ import com.google.inject.Injector; * * @author Adrian Cole */ -@Test(groups = "performance", sequential = true, testName = "jclouds.encryptionService") -public class EncryptionServiceTest extends PerformanceTest { +@Test(groups = "performance", sequential = true, testName = "jclouds.CryptoTest") +public class CryptoTest extends PerformanceTest { - protected EncryptionService encryptionService; + protected Crypto crypto; @BeforeTest - protected void createEncryptionService() { + protected void createCrypto() { Injector i = Guice.createInjector(); - encryptionService = i.getInstance(EncryptionService.class); + crypto = i.getInstance(Crypto.class); } public final static Object[][] base64KeyMessageDigest = { - { Base64.decode("CwsLCwsLCwsLCwsLCwsLCwsLCws="), "Hi There", - "thcxhlUFcmTii8C2+zeMjvFGvgA=" }, - { Base64.decode("SmVmZQ=="), "what do ya want for nothing?", - "7/zfauXrL6LSdBbV8YTfnCWafHk=" }, - { Base64.decode("DAwMDAwMDAwMDAwMDAwMDAwMDAw="), "Test With Truncation", - "TBoDQktV4H/n8nvh1Yu5MkqaWgQ=" }, + { Base64.decode("CwsLCwsLCwsLCwsLCwsLCwsLCws="), "Hi There", "thcxhlUFcmTii8C2+zeMjvFGvgA=" }, + { Base64.decode("SmVmZQ=="), "what do ya want for nothing?", "7/zfauXrL6LSdBbV8YTfnCWafHk=" }, + { Base64.decode("DAwMDAwMDAwMDAwMDAwMDAwMDAw="), "Test With Truncation", "TBoDQktV4H/n8nvh1Yu5MkqaWgQ=" }, { Base64 .decode("qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqo="), - "Test Using Larger Than Block-Size Key - Hash Key First", - "qkrl4VJy0A6VcFY3zoo7Ve1AIRI=" }, + "Test Using Larger Than Block-Size Key - Hash Key First", "qkrl4VJy0A6VcFY3zoo7Ve1AIRI=" }, { Base64 .decode("qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqo="), @@ -83,23 +76,23 @@ public class EncryptionServiceTest extends PerformanceTest { } @Test(dataProvider = "hmacsha1") - public void testHmacSha1Base64(byte[] key, String message, String base64Digest) - throws NoSuchProviderException, NoSuchAlgorithmException, InvalidKeyException { - String b64 = encryptionService.base64(encryptionService.hmacSha1(message, key)); + public void testHmacSha1Base64(byte[] key, String message, String base64Digest) throws NoSuchProviderException, + NoSuchAlgorithmException, InvalidKeyException, IOException { + String b64 = CryptoStreams.macBase64(InputSuppliers.of(message), crypto.hmacSHA1(key)); assertEquals(b64, base64Digest); } @Test(dataProvider = "hmacsha1") - void testDigestSerialResponseTime(byte[] key, String message, String base64Digest) - throws NoSuchProviderException, NoSuchAlgorithmException, InvalidKeyException { + void testDigestSerialResponseTime(byte[] key, String message, String base64Digest) throws NoSuchProviderException, + NoSuchAlgorithmException, InvalidKeyException, IOException { for (int i = 0; i < 10000; i++) testHmacSha1Base64(key, message, base64Digest); } @Test(dataProvider = "hmacsha1") - void testDigestParallelResponseTime(final byte[] key, final String message, - final String base64Digest) throws NoSuchProviderException, NoSuchAlgorithmException, - InvalidKeyException, InterruptedException, ExecutionException { + void testDigestParallelResponseTime(final byte[] key, final String message, final String base64Digest) + throws NoSuchProviderException, NoSuchAlgorithmException, InvalidKeyException, InterruptedException, + ExecutionException { CompletionService completer = new ExecutorCompletionService(exec); for (int i = 0; i < 10000; i++) completer.submit(new Callable() { @@ -117,40 +110,15 @@ public class EncryptionServiceTest extends PerformanceTest { return hexMD5MessageDigest; } - public final static Object[][] hexMD5MessageDigest = { - { "apple", "1f3870be274f6c49b3e31a0c6728957f" }, - { "bear", "893b56e3cfe153fb770a120b83bac20c" }, - { "candy", "c48ba993d35c3abe0380f91738fe2a34" }, - { "dogma", "95eb470e4faee302e9cd3063b1923dab" }, - { "emma", "00a809937eddc44521da9521269e75c6" } }; + public final static Object[][] hexMD5MessageDigest = { { "apple", "1f3870be274f6c49b3e31a0c6728957f" }, + { "bear", "893b56e3cfe153fb770a120b83bac20c" }, { "candy", "c48ba993d35c3abe0380f91738fe2a34" }, + { "dogma", "95eb470e4faee302e9cd3063b1923dab" }, { "emma", "00a809937eddc44521da9521269e75c6" } }; @Test(dataProvider = "eTag") public void testMD5Digest(String message, String hexMD5Digest) throws NoSuchProviderException, NoSuchAlgorithmException, InvalidKeyException, IOException { - String b64 = encryptionService.hex(encryptionService.md5(new ByteArrayInputStream(message - .getBytes()))); + String b64 = CryptoStreams.md5Hex(InputSuppliers.of(message)); assertEquals(hexMD5Digest, b64); - - MD5OutputStream outputStream = encryptionService.md5OutputStream(new ByteArrayOutputStream()); - ByteStreams.copy(ByteStreams.newInputStreamSupplier(message.getBytes()).getInput(), - outputStream); - - assertEquals(encryptionService.fromHex(hexMD5Digest), outputStream.getMD5()); - } - byte[] bytes = { 0, 1, 2, 4, 8, 16, 32, 64 }; - String hex = "0001020408102040"; - - public void testHexStringEncode() throws UnsupportedEncodingException { - assertEquals(encryptionService.hex(bytes), hex); - } - - public void testHexStringDecode() throws UnsupportedEncodingException { - assertEquals(encryptionService.fromHex(hex), bytes); - } - - public void testHexStringDecodeOx() throws UnsupportedEncodingException { - assertEquals(encryptionService.fromHex("0x" + hex), bytes); - } } diff --git a/core/src/test/java/org/jclouds/rest/BaseRestClientTest.java b/core/src/test/java/org/jclouds/rest/BaseRestClientTest.java index 0855417611..e1f47b79bf 100644 --- a/core/src/test/java/org/jclouds/rest/BaseRestClientTest.java +++ b/core/src/test/java/org/jclouds/rest/BaseRestClientTest.java @@ -18,36 +18,39 @@ */ package org.jclouds.rest; -import static org.jclouds.concurrent.ConcurrentUtils.sameThreadExecutor; +import static com.google.common.base.Throwables.propagate; import static org.easymock.classextension.EasyMock.createMock; +import static org.jclouds.http.HttpUtils.sortAndConcatHeadersIntoString; +import static org.jclouds.util.Utils.toStringAndClose; +import static org.mortbay.jetty.HttpHeaders.TRANSFER_ENCODING; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertNull; import java.io.IOException; import java.lang.reflect.Method; +import javax.annotation.Nullable; + +import org.jclouds.concurrent.MoreExecutors; import org.jclouds.concurrent.config.ConfiguresExecutorService; import org.jclouds.concurrent.config.ExecutorServiceModule; -import org.jclouds.encryption.EncryptionService; +import org.jclouds.crypto.Crypto; +import org.jclouds.crypto.CryptoStreams; import org.jclouds.http.HttpRequest; -import org.jclouds.http.HttpUtils; import org.jclouds.http.TransformingHttpCommandExecutorService; import org.jclouds.http.config.ConfiguresHttpCommandExecutorService; import org.jclouds.http.functions.ParseSax; import org.jclouds.rest.functions.MapHttp4xxCodesToExceptions; import org.jclouds.rest.internal.RestAnnotationProcessor; -import org.jclouds.util.Utils; -import org.mortbay.jetty.HttpHeaders; import com.google.inject.AbstractModule; import com.google.inject.Injector; -import com.google.inject.internal.Nullable; public abstract class BaseRestClientTest { protected Injector injector; protected ParseSax.Factory parserFactory; - protected EncryptionService encryptionService; + protected Crypto crypto; @ConfiguresHttpCommandExecutorService @ConfiguresExecutorService @@ -64,35 +67,41 @@ public abstract class BaseRestClientTest { @Override protected void configure() { - install(new ExecutorServiceModule(sameThreadExecutor(), sameThreadExecutor())); + install(new ExecutorServiceModule(MoreExecutors.sameThreadExecutor(), MoreExecutors.sameThreadExecutor())); bind(TransformingHttpCommandExecutorService.class).toInstance(mock); } } - protected void assertPayloadEquals(HttpRequest request, String toMatch, String contentType, - boolean contentMD5) throws IOException { + protected void assertPayloadEquals(HttpRequest request, String toMatch, String contentType, boolean contentMD5) { if (request.getPayload() == null) { assertNull(toMatch); } else { - String payload = Utils.toStringAndClose(request.getPayload().getInput()); + String payload = null; + try { + payload = toStringAndClose(request.getPayload().getInput()); + } catch (IOException e) { + propagate(e); + } assertEquals(payload, toMatch); - if (request.getFirstHeaderOrNull(HttpHeaders.TRANSFER_ENCODING) == null) { - assertEquals(request.getPayload().getContentLength(), new Long( - payload.getBytes().length)); + if (request.getFirstHeaderOrNull(TRANSFER_ENCODING) == null) { + assertEquals(request.getPayload().getContentLength(), new Long(payload.getBytes().length)); } else { - assertEquals(request.getFirstHeaderOrNull(HttpHeaders.TRANSFER_ENCODING), "chunked"); + assertEquals(request.getFirstHeaderOrNull(TRANSFER_ENCODING), "chunked"); assert request.getPayload().getContentLength() == null - || request.getPayload().getContentLength().equals( - new Long(payload.getBytes().length)); + || request.getPayload().getContentLength().equals(new Long(payload.getBytes().length)); } assertEquals(request.getPayload().getContentType(), contentType); - assertEquals(request.getPayload().getContentMD5(), contentMD5 ? encryptionService - .md5(request.getPayload().getInput()) : null); + try { + assertEquals(request.getPayload().getContentMD5(), contentMD5 ? CryptoStreams.md5(request.getPayload()) + : null); + } catch (IOException e) { + propagate(e); + } } } protected void assertNonPayloadHeadersEqual(HttpRequest request, String toMatch) { - assertEquals(HttpUtils.sortAndConcatHeadersIntoString(request.getHeaders()), toMatch); + assertEquals(sortAndConcatHeadersIntoString(request.getHeaders()), toMatch); } protected void assertRequestLineEquals(HttpRequest request, String toMatch) { @@ -101,25 +110,20 @@ public abstract class BaseRestClientTest { protected void assertExceptionParserClassEquals(Method method, @Nullable Class parserClass) { if (parserClass == null) - assertEquals( - RestAnnotationProcessor - .createExceptionParserOrThrowResourceNotFoundOn404IfNoAnnotation( - injector, method).getClass(), MapHttp4xxCodesToExceptions.class); + assertEquals(RestAnnotationProcessor.createExceptionParserOrThrowResourceNotFoundOn404IfNoAnnotation(injector, + method).getClass(), MapHttp4xxCodesToExceptions.class); else - assertEquals( - RestAnnotationProcessor - .createExceptionParserOrThrowResourceNotFoundOn404IfNoAnnotation( - injector, method).getClass(), parserClass); + assertEquals(RestAnnotationProcessor.createExceptionParserOrThrowResourceNotFoundOn404IfNoAnnotation(injector, + method).getClass(), parserClass); } protected void assertSaxResponseParserClassEquals(Method method, @Nullable Class parserClass) { assertEquals(RestAnnotationProcessor.getSaxResponseParserClassOrNull(method), parserClass); } - protected void assertResponseParserClassEquals(Method method, HttpRequest request, - @Nullable Class parserClass) { - assertEquals(RestAnnotationProcessor.createResponseParser(parserFactory, injector, method, - request).getClass(), parserClass); + protected void assertResponseParserClassEquals(Method method, HttpRequest request, @Nullable Class parserClass) { + assertEquals(RestAnnotationProcessor.createResponseParser(parserFactory, injector, method, request).getClass(), + parserClass); } } \ No newline at end of file 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 c34f8de211..d3c274f701 100755 --- a/core/src/test/java/org/jclouds/rest/internal/RestAnnotationProcessorTest.java +++ b/core/src/test/java/org/jclouds/rest/internal/RestAnnotationProcessorTest.java @@ -27,6 +27,7 @@ import static org.easymock.EasyMock.reportMatcher; import static org.easymock.classextension.EasyMock.createNiceMock; import static org.easymock.classextension.EasyMock.replay; import static org.easymock.classextension.EasyMock.verify; +import static org.jclouds.io.Payloads.calculateMD5; import static org.jclouds.io.Payloads.newInputStreamPayload; import static org.jclouds.io.Payloads.newStringPayload; import static org.jclouds.rest.RestContextFactory.contextSpec; @@ -46,6 +47,7 @@ import java.lang.reflect.Array; import java.lang.reflect.Method; import java.net.URI; import java.net.URLEncoder; +import java.security.NoSuchAlgorithmException; import java.util.Collection; import java.util.Collections; import java.util.Date; @@ -76,16 +78,15 @@ import javax.ws.rs.core.UriBuilder; import org.easymock.IArgumentMatcher; import org.jboss.resteasy.specimpl.UriBuilderImpl; import org.jclouds.concurrent.Timeout; +import org.jclouds.crypto.Crypto; import org.jclouds.date.DateService; import org.jclouds.date.internal.SimpleDateFormatDateService; -import org.jclouds.encryption.EncryptionService; import org.jclouds.http.HttpCommand; import org.jclouds.http.HttpException; import org.jclouds.http.HttpRequest; import org.jclouds.http.HttpRequestFilter; import org.jclouds.http.HttpResponse; import org.jclouds.http.IOExceptionRetryHandler; -import org.jclouds.http.PayloadEnclosing; import org.jclouds.http.RequiresHttp; import org.jclouds.http.TransformingHttpCommandExecutorService; import org.jclouds.http.functions.ParseJson; @@ -101,7 +102,7 @@ import org.jclouds.http.options.BaseHttpRequestOptions; import org.jclouds.http.options.GetOptions; import org.jclouds.http.options.HttpRequestOptions; import org.jclouds.io.Payload; -import org.jclouds.io.Payloads; +import org.jclouds.io.PayloadEnclosing; import org.jclouds.logging.config.NullLoggingModule; import org.jclouds.rest.AsyncClientFactory; import org.jclouds.rest.BaseRestClientTest; @@ -805,7 +806,7 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest { Function parser = (Function) RestAnnotationProcessor .createResponseParser(parserFactory, injector, method, request); - assertEquals(parser.apply(new HttpResponse(200, "ok", Payloads.newStringPayload("{ foo:\"bar\"}"))).foo, "bar"); + assertEquals(parser.apply(new HttpResponse(200, "ok", newStringPayload("{ foo:\"bar\"}"))).foo, "bar"); } @@ -820,8 +821,8 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest { Function> parser = (Function>) RestAnnotationProcessor .createResponseParser(parserFactory, injector, method, request); - assertEquals(parser.apply(new HttpResponse(200, "ok", Payloads.newStringPayload("{ foo:\"bar\"}"))), ImmutableMap - .of("foo", "bar")); + assertEquals(parser.apply(new HttpResponse(200, "ok", newStringPayload("{ foo:\"bar\"}"))), ImmutableMap.of( + "foo", "bar")); } @@ -836,8 +837,8 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest { Function> parser = (Function>) RestAnnotationProcessor .createResponseParser(parserFactory, injector, method, request); - assertEquals(parser.apply(new HttpResponse(200, "ok", Payloads.newStringPayload("{ foo:\"bar\"}"))), ImmutableMap - .of("foo", "bar")); + assertEquals(parser.apply(new HttpResponse(200, "ok", newStringPayload("{ foo:\"bar\"}"))), ImmutableMap.of( + "foo", "bar")); } @@ -852,8 +853,8 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest { Function> parser = (Function>) RestAnnotationProcessor .createResponseParser(parserFactory, injector, method, request); - assertEquals(parser.apply(new HttpResponse(200, "ok", Payloads.newStringPayload("{ foo:\"bar\"}"))), ImmutableMap - .of("foo", "bar")); + assertEquals(parser.apply(new HttpResponse(200, "ok", newStringPayload("{ foo:\"bar\"}"))), ImmutableMap.of( + "foo", "bar")); } @@ -868,7 +869,7 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest { Function> parser = (Function>) RestAnnotationProcessor .createResponseParser(parserFactory, injector, method, request); - assertEquals(parser.apply(new HttpResponse(200, "ok", Payloads.newStringPayload("{ foo:\"bar\"}"))), "bar"); + assertEquals(parser.apply(new HttpResponse(200, "ok", newStringPayload("{ foo:\"bar\"}"))), "bar"); } @@ -883,7 +884,7 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest { Function> parser = (Function>) RestAnnotationProcessor .createResponseParser(parserFactory, injector, method, request); - assertEquals(parser.apply(new HttpResponse(200, "ok", Payloads.newStringPayload("{ foo:\"bar\"}"))), "bar"); + assertEquals(parser.apply(new HttpResponse(200, "ok", newStringPayload("{ foo:\"bar\"}"))), "bar"); } @@ -898,8 +899,8 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest { Function> parser = (Function>) RestAnnotationProcessor .createResponseParser(parserFactory, injector, method, request); - assertEquals(parser.apply(new HttpResponse(200, "ok", Payloads - .newStringPayload("{\"runit\":[\"0.7.0\",\"0.7.1\"]}"))), ImmutableSet.of("0.7.0", "0.7.1")); + assertEquals(parser.apply(new HttpResponse(200, "ok", newStringPayload("{\"runit\":[\"0.7.0\",\"0.7.1\"]}"))), + ImmutableSet.of("0.7.0", "0.7.1")); } @SuppressWarnings("unchecked") @@ -913,8 +914,8 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest { Function> parser = (Function>) RestAnnotationProcessor .createResponseParser(parserFactory, injector, method, request); - assertEquals(parser.apply(new HttpResponse(200, "ok", Payloads - .newStringPayload("{\"runit\":[\"0.7.0\",\"0.7.1\"]}"))), ImmutableSet.of("0.7.0", "0.7.1")); + assertEquals(parser.apply(new HttpResponse(200, "ok", newStringPayload("{\"runit\":[\"0.7.0\",\"0.7.1\"]}"))), + ImmutableSet.of("0.7.0", "0.7.1")); } static class TestRequestFilter1 implements HttpRequestFilter { @@ -1427,8 +1428,7 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest { public void testPutPayloadEnclosingGenerateMD5() throws SecurityException, NoSuchMethodException, IOException { Method method = TestTransformers.class.getMethod("put", PayloadEnclosing.class); PayloadEnclosing payloadEnclosing = new PayloadEnclosingImpl(newStringPayload("whoops")); - - encryptionService.generateMD5BufferingIfNotRepeatable(payloadEnclosing); + calculateMD5(payloadEnclosing, crypto.md5()); HttpRequest request = factory(TestQuery.class).createRequest(method, payloadEnclosing); assertRequestLineEquals(request, "PUT http://localhost:9999?x-ms-version=2009-07-17 HTTP/1.1"); assertNonPayloadHeadersEqual(request, ""); @@ -1441,7 +1441,7 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest { Method method = TestTransformers.class.getMethod("put", PayloadEnclosing.class); PayloadEnclosing payloadEnclosing = new PayloadEnclosingImpl(newInputStreamPayload(toInputStream("whoops"))); - encryptionService.generateMD5BufferingIfNotRepeatable(payloadEnclosing); + calculateMD5(payloadEnclosing, crypto.md5()); HttpRequest request = factory(TestQuery.class).createRequest(method, payloadEnclosing); assertRequestLineEquals(request, "PUT http://localhost:9999?x-ms-version=2009-07-17 HTTP/1.1"); assertNonPayloadHeadersEqual(request, ""); @@ -1468,7 +1468,7 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest { public void testPutPayloadWithGeneratedMD5AndNoContentType() throws SecurityException, NoSuchMethodException, IOException { Payload payload = newStringPayload("whoops"); - payload = encryptionService.generateMD5BufferingIfNotRepeatable(payload); + calculateMD5(payload, crypto.md5()); Method method = TestTransformers.class.getMethod("put", Payload.class); HttpRequest request = factory(TestQuery.class).createRequest(method, payload); assertRequestLineEquals(request, "PUT http://localhost:9999?x-ms-version=2009-07-17 HTTP/1.1"); @@ -1476,15 +1476,6 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest { assertPayloadEquals(request, "whoops", "application/unknown", true); } - @Test(expectedExceptions = IllegalArgumentException.class) - public void testPutInputStreamPayloadWithNoLengthThrowsException() throws SecurityException, NoSuchMethodException, - IOException { - Payload payload = newInputStreamPayload(toInputStream("whoops")); - encryptionService.generateMD5BufferingIfNotRepeatable(payload); - Method method = TestTransformers.class.getMethod("put", Payload.class); - factory(TestQuery.class).createRequest(method, payload); - } - public void testPutInputStreamPayload() throws SecurityException, NoSuchMethodException, IOException { Payload payload = newInputStreamPayload(toInputStream("whoops")); payload.setContentLength((long) "whoops".length()); @@ -1495,10 +1486,11 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest { assertPayloadEquals(request, "whoops", "application/unknown", false); } - public void testPutInputStreamPayloadWithMD5() throws SecurityException, NoSuchMethodException, IOException { + public void testPutInputStreamPayloadWithMD5() throws NoSuchAlgorithmException, IOException, SecurityException, + NoSuchMethodException { Payload payload = newStringPayload("whoops"); payload.setContentLength((long) "whoops".length()); - payload.setContentMD5(encryptionService.md5(toInputStream("whoops"))); + calculateMD5(payload, crypto.md5()); Method method = TestTransformers.class.getMethod("put", Payload.class); HttpRequest request = factory(TestQuery.class).createRequest(method, payload); assertRequestLineEquals(request, "PUT http://localhost:9999?x-ms-version=2009-07-17 HTTP/1.1"); @@ -1991,7 +1983,7 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest { injector = createContextBuilder(contextSpec).buildInjector(); parserFactory = injector.getInstance(ParseSax.Factory.class); - encryptionService = injector.getInstance(EncryptionService.class); + crypto = injector.getInstance(Crypto.class); } } diff --git a/demos/speedtest-azurequeue/src/main/java/org/jclouds/azure/azurequeue/SpeedTest.java b/demos/speedtest-azurequeue/src/main/java/org/jclouds/azure/azurequeue/SpeedTest.java index be52ab2c74..56dea08116 100755 --- a/demos/speedtest-azurequeue/src/main/java/org/jclouds/azure/azurequeue/SpeedTest.java +++ b/demos/speedtest-azurequeue/src/main/java/org/jclouds/azure/azurequeue/SpeedTest.java @@ -18,17 +18,18 @@ */ package org.jclouds.azure.azurequeue; -import static org.jclouds.concurrent.ConcurrentUtils.sameThreadExecutor; -import static org.jclouds.concurrent.ConcurrentUtils.awaitCompletion; +import static org.jclouds.concurrent.FutureIterables.awaitCompletion; import java.util.Map; import java.util.Set; import java.util.SortedSet; +import java.util.concurrent.Future; import org.jclouds.azure.storage.options.ListOptions; import org.jclouds.azure.storage.queue.AzureQueueAsyncClient; import org.jclouds.azure.storage.queue.AzureQueueClient; import org.jclouds.azure.storage.queue.domain.QueueMetadata; +import org.jclouds.concurrent.MoreExecutors; import org.jclouds.enterprise.config.EnterpriseConfigurationModule; import org.jclouds.logging.ConsoleLogger; import org.jclouds.logging.Logger; @@ -39,7 +40,6 @@ import org.jclouds.rest.RestContextFactory; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Maps; import com.google.common.collect.Sets; -import java.util.concurrent.Future; import com.google.inject.Module; /** @@ -135,7 +135,7 @@ public class SpeedTest { queueName, message)); } - Map exceptions = awaitCompletion(responses, sameThreadExecutor(), + Map exceptions = awaitCompletion(responses, MoreExecutors.sameThreadExecutor(), timeOut, traceLogger, String.format("context: %s", contextName)); if (exceptions.size() > 0) diff --git a/extensions/apachehc/src/main/java/org/jclouds/http/apachehc/ApacheHCHttpCommandExecutorService.java b/extensions/apachehc/src/main/java/org/jclouds/http/apachehc/ApacheHCHttpCommandExecutorService.java index ae8aea3a7f..fb6614eb89 100644 --- a/extensions/apachehc/src/main/java/org/jclouds/http/apachehc/ApacheHCHttpCommandExecutorService.java +++ b/extensions/apachehc/src/main/java/org/jclouds/http/apachehc/ApacheHCHttpCommandExecutorService.java @@ -31,7 +31,7 @@ import org.apache.http.client.ClientProtocolException; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpUriRequest; import org.jclouds.Constants; -import org.jclouds.encryption.EncryptionService; +import org.jclouds.crypto.CryptoStreams; import org.jclouds.http.HttpRequest; import org.jclouds.http.HttpResponse; import org.jclouds.http.HttpUtils; @@ -53,17 +53,15 @@ import com.google.inject.Inject; * @author Sam Tunnicliffe * @author Adrian Cole */ -public class ApacheHCHttpCommandExecutorService extends - BaseHttpCommandExecutorService { +public class ApacheHCHttpCommandExecutorService extends BaseHttpCommandExecutorService { private final HttpClient client; @Inject - ApacheHCHttpCommandExecutorService(HttpUtils utils, EncryptionService encryptionService, + ApacheHCHttpCommandExecutorService(HttpUtils utils, @Named(Constants.PROPERTY_IO_WORKER_THREADS) ExecutorService ioWorkerExecutor, DelegatingRetryHandler retryHandler, IOExceptionRetryHandler ioRetryHandler, DelegatingErrorHandler errorHandler, HttpWire wire, HttpClient client) { - super(utils, encryptionService, ioWorkerExecutor, retryHandler, ioRetryHandler, errorHandler, - wire); + super(utils, ioWorkerExecutor, retryHandler, ioRetryHandler, errorHandler, wire); this.client = client; } @@ -71,8 +69,7 @@ public class ApacheHCHttpCommandExecutorService extends protected HttpUriRequest convert(HttpRequest request) throws IOException { HttpUriRequest returnVal = ApacheHCUtils.convertToApacheRequest(request); if (request.getPayload() != null && request.getPayload().getContentMD5() != null) - returnVal.addHeader("Content-MD5", encryptionService.base64(request.getPayload() - .getContentMD5())); + returnVal.addHeader("Content-MD5", CryptoStreams.md5Base64(request.getPayload())); return returnVal; } @@ -83,19 +80,17 @@ public class ApacheHCHttpCommandExecutorService extends Payload payload = null; if (apacheResponse.getEntity() != null) try { - payload = Payloads.newInputStreamPayload(consumeOnClose(apacheResponse.getEntity() - .getContent())); + payload = Payloads.newInputStreamPayload(consumeOnClose(apacheResponse.getEntity().getContent())); if (apacheResponse.getEntity().getContentLength() >= 0) payload.setContentLength(apacheResponse.getEntity().getContentLength()); if (apacheResponse.getEntity().getContentType() != null) payload.setContentType(apacheResponse.getEntity().getContentType().getValue()); } catch (IOException e) { - logger.warn(e, "couldn't receive payload for request: %s", nativeRequest - .getRequestLine()); + logger.warn(e, "couldn't receive payload for request: %s", nativeRequest.getRequestLine()); throw e; } - HttpResponse response = new HttpResponse(apacheResponse.getStatusLine().getStatusCode(), - apacheResponse.getStatusLine().getReasonPhrase(), payload); + HttpResponse response = new HttpResponse(apacheResponse.getStatusLine().getStatusCode(), apacheResponse + .getStatusLine().getReasonPhrase(), payload); Multimap headers = LinkedHashMultimap.create(); for (Header header : apacheResponse.getAllHeaders()) { headers.put(header.getName(), header.getValue()); @@ -104,8 +99,8 @@ public class ApacheHCHttpCommandExecutorService extends return response; } - private org.apache.http.HttpResponse executeRequest(HttpUriRequest nativeRequest) - throws IOException, ClientProtocolException { + private org.apache.http.HttpResponse executeRequest(HttpUriRequest nativeRequest) throws IOException, + ClientProtocolException { URI endpoint = URI.create(nativeRequest.getRequestLine().getUri()); HttpHost host = new HttpHost(endpoint.getHost(), endpoint.getPort(), endpoint.getScheme()); org.apache.http.HttpResponse nativeResponse = client.execute(host, nativeRequest); diff --git a/extensions/bouncycastle/src/main/java/org/jclouds/encryption/bouncycastle/BouncyCastleCrypto.java b/extensions/bouncycastle/src/main/java/org/jclouds/encryption/bouncycastle/BouncyCastleCrypto.java new file mode 100644 index 0000000000..634fce9e07 --- /dev/null +++ b/extensions/bouncycastle/src/main/java/org/jclouds/encryption/bouncycastle/BouncyCastleCrypto.java @@ -0,0 +1,40 @@ +/** + * + * Copyright (C) 2009 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ==================================================================== + */ +package org.jclouds.encryption.bouncycastle; + +import java.security.NoSuchAlgorithmException; +import java.security.cert.CertificateException; + +import javax.inject.Singleton; + +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.jclouds.encryption.internal.JCECrypto; + +/** + * + * @author Adrian Cole + */ +@Singleton +public class BouncyCastleCrypto extends JCECrypto { + + public BouncyCastleCrypto() throws NoSuchAlgorithmException, CertificateException { + super(new BouncyCastleProvider()); + } + +} diff --git a/extensions/bouncycastle/src/main/java/org/jclouds/encryption/bouncycastle/BouncyCastleEncryptionService.java b/extensions/bouncycastle/src/main/java/org/jclouds/encryption/bouncycastle/BouncyCastleEncryptionService.java deleted file mode 100644 index 38e27ea78c..0000000000 --- a/extensions/bouncycastle/src/main/java/org/jclouds/encryption/bouncycastle/BouncyCastleEncryptionService.java +++ /dev/null @@ -1,192 +0,0 @@ -/** - * - * Copyright (C) 2009 Cloud Conscious, LLC. - * - * ==================================================================== - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ -package org.jclouds.encryption.bouncycastle; - -import static com.google.common.base.Throwables.propagate; -import static com.google.common.io.Closeables.closeQuietly; -import static org.jclouds.util.Utils.encodeString; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.security.KeyFactory; -import java.security.NoSuchAlgorithmException; -import java.security.cert.CertificateException; -import java.security.cert.CertificateFactory; - -import javax.inject.Singleton; - -import org.bouncycastle.crypto.Digest; -import org.bouncycastle.crypto.digests.MD5Digest; -import org.bouncycastle.crypto.digests.SHA1Digest; -import org.bouncycastle.crypto.digests.SHA256Digest; -import org.bouncycastle.crypto.io.DigestOutputStream; -import org.bouncycastle.crypto.macs.HMac; -import org.bouncycastle.crypto.params.KeyParameter; -import org.bouncycastle.util.encoders.Base64; -import org.jclouds.encryption.internal.BaseEncryptionService; -import org.jclouds.io.payloads.ByteArrayPayload; - -/** - * - * @author Adrian Cole - */ -@Singleton -public class BouncyCastleEncryptionService extends BaseEncryptionService { - public BouncyCastleEncryptionService(KeyFactory rsaKeyFactory, CertificateFactory certFactory) { - super(rsaKeyFactory, certFactory); - } - - public BouncyCastleEncryptionService() throws NoSuchAlgorithmException, CertificateException { - this(KeyFactory.getInstance("RSA"), CertificateFactory.getInstance("X.509")); - } - - @Override - public byte[] hmacSha256(String toEncode, byte[] key) { - return hmac(toEncode, key, new SHA256Digest()); - } - - @Override - public byte[] hmacSha1(String toEncode, byte[] key) { - return hmac(toEncode, key, new SHA1Digest()); - } - - public byte[] hmac(String toEncode, byte[] key, Digest digest) { - HMac hmac = new HMac(digest); - byte[] resBuf = new byte[hmac.getMacSize()]; - byte[] plainBytes = encodeString(toEncode); - byte[] keyBytes = key; - hmac.init(new KeyParameter(keyBytes)); - hmac.update(plainBytes, 0, plainBytes.length); - hmac.doFinal(resBuf, 0); - return resBuf; - } - - @Override - public byte[] md5(InputStream toEncode) { - MD5Digest eTag = new MD5Digest(); - byte[] resBuf = new byte[eTag.getDigestSize()]; - byte[] buffer = new byte[BUF_SIZE]; - int numRead = -1; - try { - do { - numRead = toEncode.read(buffer); - if (numRead > 0) { - eTag.update(buffer, 0, numRead); - } - } while (numRead != -1); - } catch (IOException e) { - propagate(e); - } finally { - closeQuietly(toEncode); - } - eTag.doFinal(resBuf, 0); - return resBuf; - } - - @Override - public String base64(byte[] resBuf) { - return new String(Base64.encode(resBuf)); - } - - @Override - public ByteArrayPayload generatePayloadWithMD5For(InputStream toEncode) { - MD5Digest eTag = new MD5Digest(); - byte[] resBuf = new byte[eTag.getDigestSize()]; - byte[] buffer = new byte[BUF_SIZE]; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - long length = 0; - int numRead = -1; - try { - do { - numRead = toEncode.read(buffer); - if (numRead > 0) { - length += numRead; - eTag.update(buffer, 0, numRead); - out.write(buffer, 0, numRead); - } - } while (numRead != -1); - } catch (IOException e) { - propagate(e); - } finally { - closeQuietly(out); - closeQuietly(toEncode); - } - eTag.doFinal(resBuf, 0); - return new ByteArrayPayload(out.toByteArray(), resBuf); - } - - @Override - public byte[] fromBase64(String encoded) { - return Base64.decode(encoded); - } - - @Override - public MD5OutputStream md5OutputStream(OutputStream out) { - return new BouncyCastleMD5OutputStream(out); - } - - private static class BouncyCastleMD5OutputStream extends MD5OutputStream { - public BouncyCastleMD5OutputStream(OutputStream out) { - super(new DigestOutputStream(out, new MD5Digest())); - } - - @Override - public byte[] getMD5() { - MD5Digest digest = (MD5Digest) ((DigestOutputStream) out).getDigest(); - byte[] resBuf = new byte[digest.getDigestSize()]; - digest.doFinal(resBuf, 0); - return resBuf; - } - } - - @Override - public byte[] sha256(InputStream plainBytes) { - return sha(plainBytes, new SHA256Digest()); - } - - @Override - public byte[] sha1(InputStream plainBytes) { - return sha(plainBytes, new SHA1Digest()); - } - - private byte[] sha(InputStream plainBytes, Digest digest) { - byte[] resBuf = new byte[digest.getDigestSize()]; - byte[] buffer = new byte[BUF_SIZE]; - long length = 0; - int numRead = -1; - try { - do { - numRead = plainBytes.read(buffer); - if (numRead > 0) { - length += numRead; - digest.update(buffer, 0, numRead); - } - } while (numRead != -1); - } catch (IOException e) { - propagate(e); - } finally { - closeQuietly(plainBytes); - } - digest.doFinal(resBuf, 0); - return resBuf; - } - -} diff --git a/extensions/bouncycastle/src/main/java/org/jclouds/encryption/bouncycastle/config/BouncyCastleEncryptionServiceModule.java b/extensions/bouncycastle/src/main/java/org/jclouds/encryption/bouncycastle/config/BouncyCastleCryptoModule.java similarity index 73% rename from extensions/bouncycastle/src/main/java/org/jclouds/encryption/bouncycastle/config/BouncyCastleEncryptionServiceModule.java rename to extensions/bouncycastle/src/main/java/org/jclouds/encryption/bouncycastle/config/BouncyCastleCryptoModule.java index b8fa05292c..eab1d2df2e 100755 --- a/extensions/bouncycastle/src/main/java/org/jclouds/encryption/bouncycastle/config/BouncyCastleEncryptionServiceModule.java +++ b/extensions/bouncycastle/src/main/java/org/jclouds/encryption/bouncycastle/config/BouncyCastleCryptoModule.java @@ -18,22 +18,22 @@ */ package org.jclouds.encryption.bouncycastle.config; -import org.jclouds.encryption.EncryptionService; -import org.jclouds.encryption.bouncycastle.BouncyCastleEncryptionService; +import org.jclouds.crypto.Crypto; +import org.jclouds.encryption.bouncycastle.BouncyCastleCrypto; import com.google.inject.AbstractModule; /** - * Configures EncryptionService of type {@link BouncyCastleEncryptionService} + * Configures Crypto of type {@link BouncyCastleCrypto} * * @author Adrian Cole * */ -public class BouncyCastleEncryptionServiceModule extends AbstractModule { +public class BouncyCastleCryptoModule extends AbstractModule { @Override protected void configure() { - bind(EncryptionService.class).to(BouncyCastleEncryptionService.class); + bind(Crypto.class).to(BouncyCastleCrypto.class); } } diff --git a/extensions/bouncycastle/src/test/java/org/jclouds/encryption/bouncycastle/BouncyCastleEncryptionServiceTest.java b/extensions/bouncycastle/src/test/java/org/jclouds/encryption/bouncycastle/BouncyCastleCryptoTest.java similarity index 66% rename from extensions/bouncycastle/src/test/java/org/jclouds/encryption/bouncycastle/BouncyCastleEncryptionServiceTest.java rename to extensions/bouncycastle/src/test/java/org/jclouds/encryption/bouncycastle/BouncyCastleCryptoTest.java index 86795fcc26..02f2bad3d5 100644 --- a/extensions/bouncycastle/src/test/java/org/jclouds/encryption/bouncycastle/BouncyCastleEncryptionServiceTest.java +++ b/extensions/bouncycastle/src/test/java/org/jclouds/encryption/bouncycastle/BouncyCastleCryptoTest.java @@ -18,9 +18,9 @@ */ package org.jclouds.encryption.bouncycastle; -import org.jclouds.encryption.EncryptionService; -import org.jclouds.encryption.EncryptionServiceTest; -import org.jclouds.encryption.bouncycastle.config.BouncyCastleEncryptionServiceModule; +import org.jclouds.crypto.Crypto; +import org.jclouds.encryption.bouncycastle.config.BouncyCastleCryptoModule; +import org.jclouds.io.CryptoTest; import org.testng.annotations.BeforeTest; import org.testng.annotations.Test; @@ -32,13 +32,13 @@ import com.google.inject.Injector; * * @author Adrian Cole */ -@Test(groups = "performance", sequential = true, testName = "jclouds.BouncyCastleEncryptionServiceTest") -public class BouncyCastleEncryptionServiceTest extends EncryptionServiceTest { +@Test(groups = "performance", sequential = true, testName = "jclouds.BouncyCastleCryptoTest") +public class BouncyCastleCryptoTest extends CryptoTest { @BeforeTest - protected void createEncryptionService() { - Injector i = Guice.createInjector(new BouncyCastleEncryptionServiceModule()); - encryptionService = i.getInstance(EncryptionService.class); - assert encryptionService instanceof BouncyCastleEncryptionService; + protected void createCrypto() { + Injector i = Guice.createInjector(new BouncyCastleCryptoModule()); + crypto = i.getInstance(Crypto.class); + assert crypto instanceof BouncyCastleCrypto; } } diff --git a/extensions/enterprise/src/main/java/org/jclouds/enterprise/config/EnterpriseConfigurationModule.java b/extensions/enterprise/src/main/java/org/jclouds/enterprise/config/EnterpriseConfigurationModule.java index 38a1b75c20..6da10897ca 100755 --- a/extensions/enterprise/src/main/java/org/jclouds/enterprise/config/EnterpriseConfigurationModule.java +++ b/extensions/enterprise/src/main/java/org/jclouds/enterprise/config/EnterpriseConfigurationModule.java @@ -23,7 +23,7 @@ import java.util.concurrent.ExecutorService; import org.jclouds.concurrent.config.ConfiguresExecutorService; import org.jclouds.concurrent.config.ExecutorServiceModule; import org.jclouds.date.joda.config.JodaDateServiceModule; -import org.jclouds.encryption.bouncycastle.config.BouncyCastleEncryptionServiceModule; +import org.jclouds.encryption.bouncycastle.config.BouncyCastleCryptoModule; /** * Configures Enterprise-grade components @@ -44,7 +44,7 @@ public class EnterpriseConfigurationModule extends ExecutorServiceModule { @Override protected void configure() { - install(new BouncyCastleEncryptionServiceModule()); + install(new BouncyCastleCryptoModule()); install(new JodaDateServiceModule()); } diff --git a/extensions/gae/src/main/java/org/jclouds/gae/AsyncGaeHttpCommandExecutorService.java b/extensions/gae/src/main/java/org/jclouds/gae/AsyncGaeHttpCommandExecutorService.java index 941a1b7be2..d48e871571 100644 --- a/extensions/gae/src/main/java/org/jclouds/gae/AsyncGaeHttpCommandExecutorService.java +++ b/extensions/gae/src/main/java/org/jclouds/gae/AsyncGaeHttpCommandExecutorService.java @@ -32,7 +32,7 @@ import javax.inject.Named; import javax.inject.Singleton; import org.jclouds.Constants; -import static org.jclouds.concurrent.ConcurrentUtils.*; +import org.jclouds.concurrent.Futures; import org.jclouds.concurrent.SingleThreaded; import org.jclouds.http.HttpCommand; import org.jclouds.http.HttpCommandExecutorService; @@ -111,10 +111,10 @@ public class AsyncGaeHttpCommandExecutorService implements HttpCommandExecutorSe HTTPRequest nativeRequest = filterLogAndConvertRe(command.getRequest()); - ListenableFuture response = compose(urlFetchService.fetchAsync(nativeRequest), + ListenableFuture response = Futures.compose(urlFetchService.fetchAsync(nativeRequest), convertToJcloudsResponse, service); - return compose(response, new Function() { + return Futures.compose(response, new Function() { @Override public HttpResponse apply(HttpResponse response) { diff --git a/extensions/gae/src/main/java/org/jclouds/gae/ConvertToGaeRequest.java b/extensions/gae/src/main/java/org/jclouds/gae/ConvertToGaeRequest.java index c436ec5a10..bfcb7ad9e1 100644 --- a/extensions/gae/src/main/java/org/jclouds/gae/ConvertToGaeRequest.java +++ b/extensions/gae/src/main/java/org/jclouds/gae/ConvertToGaeRequest.java @@ -28,11 +28,10 @@ import java.io.InputStream; import java.net.MalformedURLException; import java.net.URL; -import javax.inject.Inject; import javax.inject.Singleton; import javax.ws.rs.core.HttpHeaders; -import org.jclouds.encryption.EncryptionService; +import org.jclouds.crypto.CryptoStreams; import org.jclouds.http.HttpRequest; import org.jclouds.io.Payload; @@ -51,16 +50,9 @@ import com.google.common.base.Function; public class ConvertToGaeRequest implements Function { public static final String USER_AGENT = "jclouds/1.0 urlfetch/1.3.5"; - private final EncryptionService encryptionService; - - @Inject - public ConvertToGaeRequest(EncryptionService encryptionService) { - this.encryptionService = encryptionService; - } - /** - * byte [] content is replayable and the only content type supportable by - * GAE. As such, we convert the original request content to a byte array. + * byte [] content is replayable and the only content type supportable by GAE. As such, we + * convert the original request content to a byte array. */ @Override public HTTPRequest apply(HttpRequest request) { @@ -84,8 +76,8 @@ public class ConvertToGaeRequest implements Function { } gaeRequest.addHeader(new HTTPHeader(HttpHeaders.USER_AGENT, USER_AGENT)); /** - * byte [] content is replayable and the only content type supportable by - * GAE. As such, we convert the original request content to a byte array. + * byte [] content is replayable and the only content type supportable by GAE. As such, we + * convert the original request content to a byte array. */ if (request.getPayload() != null) { InputStream input = request.getPayload().getInput(); @@ -106,8 +98,8 @@ public class ConvertToGaeRequest implements Function { closeQuietly(input); } if (request.getPayload().getContentMD5() != null) - gaeRequest.setHeader(new HTTPHeader("Content-MD5", encryptionService.base64(request.getPayload() - .getContentMD5()))); + gaeRequest.setHeader(new HTTPHeader("Content-MD5", CryptoStreams.base64(request.getPayload() + .getContentMD5()))); if (request.getPayload().getContentType() != null) gaeRequest.setHeader(new HTTPHeader(HttpHeaders.CONTENT_TYPE, request.getPayload().getContentType())); Long length = checkNotNull(request.getPayload().getContentLength(), "payload.getContentLength"); diff --git a/extensions/gae/src/main/java/org/jclouds/gae/GaeHttpCommandExecutorService.java b/extensions/gae/src/main/java/org/jclouds/gae/GaeHttpCommandExecutorService.java index 28b1c0c074..7c13dc74fc 100644 --- a/extensions/gae/src/main/java/org/jclouds/gae/GaeHttpCommandExecutorService.java +++ b/extensions/gae/src/main/java/org/jclouds/gae/GaeHttpCommandExecutorService.java @@ -27,7 +27,6 @@ import javax.inject.Singleton; import org.jclouds.Constants; import org.jclouds.concurrent.SingleThreaded; -import org.jclouds.encryption.EncryptionService; import org.jclouds.http.HttpCommandExecutorService; import org.jclouds.http.HttpRequest; import org.jclouds.http.HttpResponse; @@ -59,13 +58,11 @@ public class GaeHttpCommandExecutorService extends BaseHttpCommandExecutorServic @Inject public GaeHttpCommandExecutorService(URLFetchService urlFetchService, HttpUtils utils, - EncryptionService encryptionService, @Named(Constants.PROPERTY_IO_WORKER_THREADS) ExecutorService ioExecutor, IOExceptionRetryHandler ioRetryHandler, DelegatingRetryHandler retryHandler, - DelegatingErrorHandler errorHandler, HttpWire wire, - ConvertToGaeRequest convertToGaeRequest, + DelegatingErrorHandler errorHandler, HttpWire wire, ConvertToGaeRequest convertToGaeRequest, ConvertToJcloudsResponse convertToJcloudsResponse) { - super(utils, encryptionService, ioExecutor, retryHandler, ioRetryHandler, errorHandler, wire); + super(utils, ioExecutor, retryHandler, ioRetryHandler, errorHandler, wire); this.urlFetchService = urlFetchService; this.convertToGaeRequest = convertToGaeRequest; this.convertToJcloudsResponse = convertToJcloudsResponse; diff --git a/extensions/gae/src/main/java/org/jclouds/gae/config/GoogleAppEngineConfigurationModule.java b/extensions/gae/src/main/java/org/jclouds/gae/config/GoogleAppEngineConfigurationModule.java index 9fb1fc9332..cc03fb4027 100644 --- a/extensions/gae/src/main/java/org/jclouds/gae/config/GoogleAppEngineConfigurationModule.java +++ b/extensions/gae/src/main/java/org/jclouds/gae/config/GoogleAppEngineConfigurationModule.java @@ -18,10 +18,9 @@ */ package org.jclouds.gae.config; -import static org.jclouds.concurrent.ConcurrentUtils.sameThreadExecutor; - import javax.inject.Singleton; +import org.jclouds.concurrent.MoreExecutors; import org.jclouds.concurrent.SingleThreaded; import org.jclouds.concurrent.config.ConfiguresExecutorService; import org.jclouds.concurrent.config.ExecutorServiceModule; @@ -48,7 +47,7 @@ import com.google.inject.Provides; public class GoogleAppEngineConfigurationModule extends ExecutorServiceModule { public GoogleAppEngineConfigurationModule() { - super(sameThreadExecutor(), sameThreadExecutor()); + super(MoreExecutors.sameThreadExecutor(), MoreExecutors.sameThreadExecutor()); } @Override diff --git a/extensions/gae/src/test/java/org/jclouds/gae/AsyncGaeHttpCommandExecutorServiceIntegrationTest.java b/extensions/gae/src/test/java/org/jclouds/gae/AsyncGaeHttpCommandExecutorServiceIntegrationTest.java index 5b9d975fcd..28bc4a3f2f 100644 --- a/extensions/gae/src/test/java/org/jclouds/gae/AsyncGaeHttpCommandExecutorServiceIntegrationTest.java +++ b/extensions/gae/src/test/java/org/jclouds/gae/AsyncGaeHttpCommandExecutorServiceIntegrationTest.java @@ -18,9 +18,7 @@ */ package org.jclouds.gae; -import static org.jclouds.concurrent.ConcurrentUtils.awaitCompletion; -import static org.jclouds.concurrent.ConcurrentUtils.makeListenable; -import static org.jclouds.concurrent.ConcurrentUtils.sameThreadExecutor; +import static org.jclouds.concurrent.FutureIterables.awaitCompletion; import static org.testng.Assert.assertEquals; import java.io.IOException; @@ -32,6 +30,8 @@ import java.util.Properties; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeoutException; +import org.jclouds.concurrent.Futures; +import org.jclouds.concurrent.MoreExecutors; import org.jclouds.concurrent.SingleThreaded; import org.jclouds.concurrent.config.ConfiguresExecutorService; import org.jclouds.gae.config.GoogleAppEngineConfigurationModule; @@ -76,7 +76,7 @@ public class AsyncGaeHttpCommandExecutorServiceIntegrationTest extends BaseHttpC @Override public ListenableFuture get() { try { - return makeListenable(service.fetchAsync(fetch.toURL()), sameThreadExecutor()); + return Futures.makeListenable(service.fetchAsync(fetch.toURL()), MoreExecutors.sameThreadExecutor()); } catch (MalformedURLException e) { Throwables.propagate(e); return null; @@ -159,7 +159,8 @@ public class AsyncGaeHttpCommandExecutorServiceIntegrationTest extends BaseHttpC responses.put(i + "", getSupplier.get()); results.createFutures = System.currentTimeMillis() - start; start = System.currentTimeMillis(); - Map exceptions = awaitCompletion(responses, sameThreadExecutor(), null, logger, who); + Map exceptions = awaitCompletion(responses, MoreExecutors.sameThreadExecutor(), null, logger, + who); results.futuresReady = System.currentTimeMillis() - start; assert exceptions.size() == 0 : exceptions; start = System.currentTimeMillis(); diff --git a/extensions/gae/src/test/java/org/jclouds/gae/ConvertToGaeRequestTest.java b/extensions/gae/src/test/java/org/jclouds/gae/ConvertToGaeRequestTest.java index 70d068df38..4666e6e4f9 100644 --- a/extensions/gae/src/test/java/org/jclouds/gae/ConvertToGaeRequestTest.java +++ b/extensions/gae/src/test/java/org/jclouds/gae/ConvertToGaeRequestTest.java @@ -31,8 +31,8 @@ import java.util.Date; import javax.ws.rs.HttpMethod; import javax.ws.rs.core.HttpHeaders; -import org.jclouds.encryption.EncryptionService; -import org.jclouds.encryption.internal.JCEEncryptionService; +import org.jclouds.crypto.Crypto; +import org.jclouds.encryption.internal.JCECrypto; import org.jclouds.http.HttpRequest; import org.jclouds.io.Payloads; import org.jclouds.util.Utils; @@ -55,10 +55,10 @@ public class ConvertToGaeRequestTest { ConvertToGaeRequest req; URI endPoint; - protected volatile static EncryptionService encryptionService; + protected volatile static Crypto crypto; static { try { - encryptionService = new JCEEncryptionService(); + crypto = new JCECrypto(); } catch (NoSuchAlgorithmException e) { Throwables.propagate(e); } catch (CertificateException e) { @@ -69,7 +69,7 @@ public class ConvertToGaeRequestTest { @BeforeTest void setupClient() throws MalformedURLException { endPoint = URI.create("http://localhost:80/foo"); - req = new ConvertToGaeRequest(encryptionService); + req = new ConvertToGaeRequest(); } @Test diff --git a/extensions/gae/src/test/java/org/jclouds/gae/ConvertToJcloudsResponseTest.java b/extensions/gae/src/test/java/org/jclouds/gae/ConvertToJcloudsResponseTest.java index 68827cb82b..7419a2f188 100644 --- a/extensions/gae/src/test/java/org/jclouds/gae/ConvertToJcloudsResponseTest.java +++ b/extensions/gae/src/test/java/org/jclouds/gae/ConvertToJcloudsResponseTest.java @@ -33,8 +33,8 @@ import java.util.List; import javax.ws.rs.core.HttpHeaders; -import org.jclouds.encryption.EncryptionService; -import org.jclouds.encryption.internal.JCEEncryptionService; +import org.jclouds.crypto.Crypto; +import org.jclouds.encryption.internal.JCECrypto; import org.jclouds.http.HttpResponse; import org.jclouds.http.HttpUtils; import org.jclouds.util.Utils; @@ -54,10 +54,10 @@ public class ConvertToJcloudsResponseTest { ConvertToJcloudsResponse req; URI endPoint; - protected volatile static EncryptionService encryptionService; + protected volatile static Crypto crypto; static { try { - encryptionService = new JCEEncryptionService(); + crypto = new JCECrypto(); } catch (NoSuchAlgorithmException e) { Throwables.propagate(e); } catch (CertificateException e) { @@ -68,7 +68,7 @@ public class ConvertToJcloudsResponseTest { @BeforeTest void setupClient() throws MalformedURLException { endPoint = URI.create("http://localhost:80/foo"); - req = new ConvertToJcloudsResponse(new HttpUtils(encryptionService, 0, 0, 0, 0)); + req = new ConvertToJcloudsResponse(new HttpUtils(0, 0, 0, 0)); } @Test diff --git a/extensions/ning/src/main/java/org/jclouds/http/ning/NingHttpCommandExecutorService.java b/extensions/ning/src/main/java/org/jclouds/http/ning/NingHttpCommandExecutorService.java index 4ea2deb3dc..02ce23c65c 100644 --- a/extensions/ning/src/main/java/org/jclouds/http/ning/NingHttpCommandExecutorService.java +++ b/extensions/ning/src/main/java/org/jclouds/http/ning/NingHttpCommandExecutorService.java @@ -34,18 +34,18 @@ import javax.inject.Singleton; import javax.ws.rs.HttpMethod; import javax.ws.rs.core.HttpHeaders; -import org.jclouds.encryption.EncryptionService; +import org.jclouds.crypto.CryptoStreams; import org.jclouds.http.HttpCommand; import org.jclouds.http.HttpCommandExecutorService; import org.jclouds.http.HttpRequest; import org.jclouds.http.HttpRequestFilter; import org.jclouds.http.HttpResponse; import org.jclouds.http.HttpUtils; -import org.jclouds.http.Payload; -import org.jclouds.http.Payloads; import org.jclouds.http.handlers.DelegatingErrorHandler; import org.jclouds.http.handlers.DelegatingRetryHandler; import org.jclouds.http.internal.BaseHttpCommandExecutorService; +import org.jclouds.io.Payload; +import org.jclouds.io.Payloads; import com.google.common.base.Function; import com.google.common.base.Throwables; @@ -78,8 +78,7 @@ public class NingHttpCommandExecutorService implements HttpCommandExecutorServic private final DelegatingErrorHandler errorHandler; @Inject - public NingHttpCommandExecutorService(AsyncHttpClient client, - ConvertToNingRequest convertToNingRequest, + public NingHttpCommandExecutorService(AsyncHttpClient client, ConvertToNingRequest convertToNingRequest, ConvertToJCloudsResponse convertToJCloudsResponse, DelegatingRetryHandler retryHandler, DelegatingErrorHandler errorHandler) { this.client = client; @@ -93,8 +92,7 @@ public class NingHttpCommandExecutorService implements HttpCommandExecutorServic public ListenableFuture submit(HttpCommand command) { try { for (;;) { - Future responseF = client.executeRequest(convertToNingRequest.apply(command - .getRequest())); + Future responseF = client.executeRequest(convertToNingRequest.apply(command.getRequest())); final HttpResponse httpResponse = convertToJCloudsResponse.apply(responseF.get()); int statusCode = httpResponse.getStatusCode(); if (statusCode >= 300) { @@ -129,12 +127,6 @@ public class NingHttpCommandExecutorService implements HttpCommandExecutorServic @Singleton public static class ConvertToNingRequest implements Function { - private final EncryptionService encryptionService; - - @Inject - ConvertToNingRequest(EncryptionService encryptionService) { - this.encryptionService = encryptionService; - } private static class PayloadEntityWriter implements EntityWriter { private final Payload payload; @@ -177,14 +169,12 @@ public class NingHttpCommandExecutorService implements HttpCommandExecutorServic boolean chunked = "chunked".equals(request.getFirstHeaderOrNull("Transfer-Encoding")); if (request.getPayload().getContentMD5() != null) - nativeRequestBuilder.addHeader("Content-MD5", encryptionService.base64(request - .getPayload().getContentMD5())); + nativeRequestBuilder + .addHeader("Content-MD5", CryptoStreams.base64(request.getPayload().getContentMD5())); if (request.getPayload().getContentType() != null) - nativeRequestBuilder.addHeader(HttpHeaders.CONTENT_TYPE, request.getPayload() - .getContentType()); + nativeRequestBuilder.addHeader(HttpHeaders.CONTENT_TYPE, request.getPayload().getContentType()); if (!chunked) { - Long length = checkNotNull(request.getPayload().getContentLength(), - "payload.getContentLength"); + Long length = checkNotNull(request.getPayload().getContentLength(), "payload.getContentLength"); nativeRequestBuilder.addHeader(HttpHeaders.CONTENT_LENGTH, length.toString()); } setPayload(nativeRequestBuilder, payload); @@ -220,8 +210,7 @@ public class NingHttpCommandExecutorService implements HttpCommandExecutorServic InputStream in = null; try { - in = BaseHttpCommandExecutorService.consumeOnClose(nativeResponse - .getResponseBodyAsStream()); + in = BaseHttpCommandExecutorService.consumeOnClose(nativeResponse.getResponseBodyAsStream()); } catch (IOException e) { Closeables.closeQuietly(in); propagate(e); @@ -229,8 +218,8 @@ public class NingHttpCommandExecutorService implements HttpCommandExecutorServic } Payload payload = in != null ? Payloads.newInputStreamPayload(in) : null; - HttpResponse response = new HttpResponse(nativeResponse.getStatusCode(), nativeResponse - .getStatusText(), payload); + HttpResponse response = new HttpResponse(nativeResponse.getStatusCode(), nativeResponse.getStatusText(), + payload); Multimap headers = LinkedHashMultimap.create(); for (Entry> header : nativeResponse.getHeaders()) { headers.putAll(header.getKey(), header.getValue()); diff --git a/gogrid/src/main/java/org/jclouds/gogrid/filters/SharedKeyLiteAuthentication.java b/gogrid/src/main/java/org/jclouds/gogrid/filters/SharedKeyLiteAuthentication.java index 53dfed653c..1b160d41d4 100644 --- a/gogrid/src/main/java/org/jclouds/gogrid/filters/SharedKeyLiteAuthentication.java +++ b/gogrid/src/main/java/org/jclouds/gogrid/filters/SharedKeyLiteAuthentication.java @@ -36,13 +36,13 @@ import javax.inject.Inject; import javax.inject.Named; import org.jclouds.Constants; +import org.jclouds.crypto.CryptoStreams; import org.jclouds.date.TimeStamp; -import org.jclouds.encryption.EncryptionService; import org.jclouds.http.HttpRequest; import org.jclouds.http.HttpRequestFilter; import org.jclouds.http.HttpUtils; +import org.jclouds.io.InputSuppliers; import org.jclouds.logging.Logger; -import org.jclouds.util.Utils; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Multimap; @@ -55,7 +55,6 @@ public class SharedKeyLiteAuthentication implements HttpRequestFilter { private final String apiKey; private final String secret; private final Long timeStamp; - private final EncryptionService encryptionService; private final HttpUtils utils; @Resource @@ -64,9 +63,7 @@ public class SharedKeyLiteAuthentication implements HttpRequestFilter { @Inject public SharedKeyLiteAuthentication(@Named(PROPERTY_IDENTITY) String apiKey, - @Named(PROPERTY_CREDENTIAL) String secret, @TimeStamp Long timeStamp, - EncryptionService encryptionService, HttpUtils utils) { - this.encryptionService = encryptionService; + @Named(PROPERTY_CREDENTIAL) String secret, @TimeStamp Long timeStamp, HttpUtils utils) { this.apiKey = apiKey; this.secret = secret; this.timeStamp = timeStamp; @@ -86,8 +83,7 @@ public class SharedKeyLiteAuthentication implements HttpRequestFilter { String updatedQuery = makeQueryLine(decodedParams, null); String requestBasePart = request.getEndpoint().toASCIIString(); - String updatedEndpoint = requestBasePart.substring(0, requestBasePart.indexOf("?") + 1) - + updatedQuery; + String updatedEndpoint = requestBasePart.substring(0, requestBasePart.indexOf("?") + 1) + updatedQuery; request.setEndpoint(URI.create(updatedEndpoint)); utils.logRequest(signatureLog, request, "<<"); @@ -99,7 +95,7 @@ public class SharedKeyLiteAuthentication implements HttpRequestFilter { private String getMd5For(String stringToHash) { try { - return encryptionService.hex(encryptionService.md5(Utils.toInputStream(stringToHash))); + return CryptoStreams.md5Hex(InputSuppliers.of(stringToHash)); } catch (Exception e) { throw new RuntimeException(e); } diff --git a/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/domain/PCSFile.java b/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/domain/PCSFile.java index 27b5a77c04..81d96aae59 100644 --- a/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/domain/PCSFile.java +++ b/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/domain/PCSFile.java @@ -18,7 +18,7 @@ */ package org.jclouds.mezeo.pcs2.domain; -import org.jclouds.http.PayloadEnclosing; +import org.jclouds.io.PayloadEnclosing; import com.google.common.collect.Multimap; import com.google.inject.internal.Nullable; diff --git a/nirvanix/sdn/core/src/test/java/org/jclouds/nirvanix/sdn/SDNAuthenticationLiveTest.java b/nirvanix/sdn/core/src/test/java/org/jclouds/nirvanix/sdn/SDNAuthenticationLiveTest.java index 17531ecfb2..7b4bc37f51 100644 --- a/nirvanix/sdn/core/src/test/java/org/jclouds/nirvanix/sdn/SDNAuthenticationLiveTest.java +++ b/nirvanix/sdn/core/src/test/java/org/jclouds/nirvanix/sdn/SDNAuthenticationLiveTest.java @@ -19,7 +19,6 @@ package org.jclouds.nirvanix.sdn; import static com.google.common.base.Preconditions.checkNotNull; -import static org.jclouds.concurrent.ConcurrentUtils.sameThreadExecutor; import static org.jclouds.rest.RestContextFactory.contextSpec; import static org.jclouds.rest.RestContextFactory.createContextBuilder; import static org.testng.Assert.assertNotNull; @@ -27,6 +26,7 @@ import static org.testng.Assert.assertNotNull; import java.util.ArrayList; import java.util.concurrent.TimeUnit; +import org.jclouds.concurrent.MoreExecutors; import org.jclouds.concurrent.Timeout; import org.jclouds.concurrent.config.ExecutorServiceModule; import org.jclouds.logging.log4j.config.Log4JLoggingModule; @@ -73,12 +73,12 @@ public class SDNAuthenticationLiveTest { identity = checkNotNull(System.getProperty("jclouds.test.identity"), "jclouds.test.identity"); credential = checkNotNull(System.getProperty("jclouds.test.credential"), "jclouds.test.credential"); - ContextSpec contextSpec = contextSpec("test", endpoint, - "1", identity, credential, SDNAuthClient.class, SDNAuthAsyncClient.class); + ContextSpec contextSpec = contextSpec("test", endpoint, "1", identity, + credential, SDNAuthClient.class, SDNAuthAsyncClient.class); context = createContextBuilder( contextSpec, - ImmutableSet. of(new Log4JLoggingModule(), new ExecutorServiceModule( - sameThreadExecutor(), sameThreadExecutor()))).buildContext(); + ImmutableSet. of(new Log4JLoggingModule(), new ExecutorServiceModule(MoreExecutors + .sameThreadExecutor(), MoreExecutors.sameThreadExecutor()))).buildContext(); } } 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 68b9c0c3ae..369f6575e8 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 @@ -22,6 +22,7 @@ import static com.google.common.base.Preconditions.checkNotNull; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertNotNull; +import java.io.IOException; import java.net.URI; import java.util.Map; import java.util.concurrent.ExecutionException; @@ -30,6 +31,7 @@ import java.util.concurrent.TimeoutException; import org.jclouds.blobstore.domain.Blob; import org.jclouds.blobstore.integration.internal.BaseBlobStoreIntegrationTest; import org.jclouds.encryption.internal.Base64; +import org.jclouds.io.Payloads; import org.jclouds.logging.log4j.config.Log4JLoggingModule; import org.jclouds.nirvanix.sdn.domain.UploadInfo; import org.jclouds.rest.RestContext; @@ -67,7 +69,7 @@ public class SDNClientLiveTest { this.connection = context.getApi(); } - public void testUploadToken() throws InterruptedException, ExecutionException, TimeoutException { + public void testUploadToken() throws InterruptedException, ExecutionException, TimeoutException, IOException { String containerName = containerPrefix + ".testObjectOperations"; long size = 1024; @@ -78,7 +80,7 @@ public class SDNClientLiveTest { Blob blob = connection.newBlob(); blob.getMetadata().setName("test.txt"); blob.setPayload("value"); - context.utils().encryption().generateMD5BufferingIfNotRepeatable(blob); + Payloads.calculateMD5(blob); byte[] md5 = blob.getMetadata().getContentMD5(); connection.upload(uploadInfo.getHost(), uploadInfo.getToken(), containerName, blob); diff --git a/nirvanix/sdn/core/src/test/java/org/jclouds/nirvanix/sdn/filters/AddSessionTokenToRequestTest.java b/nirvanix/sdn/core/src/test/java/org/jclouds/nirvanix/sdn/filters/AddSessionTokenToRequestTest.java index 6ed3137825..e7d1298f46 100755 --- a/nirvanix/sdn/core/src/test/java/org/jclouds/nirvanix/sdn/filters/AddSessionTokenToRequestTest.java +++ b/nirvanix/sdn/core/src/test/java/org/jclouds/nirvanix/sdn/filters/AddSessionTokenToRequestTest.java @@ -18,7 +18,6 @@ */ package org.jclouds.nirvanix.sdn.filters; -import static org.jclouds.concurrent.ConcurrentUtils.sameThreadExecutor; import static org.testng.Assert.assertEquals; import java.lang.reflect.Method; @@ -27,6 +26,7 @@ import java.util.Properties; import javax.ws.rs.POST; +import org.jclouds.concurrent.MoreExecutors; import org.jclouds.concurrent.config.ExecutorServiceModule; import org.jclouds.date.DateService; import org.jclouds.http.HttpRequest; @@ -69,8 +69,7 @@ public class AddSessionTokenToRequestTest { })); Method method = TestService.class.getMethod("foo", URI.class); - return new Object[][] { - { factory.createRequest(method, new Object[] { URI.create("https://host:443") }) }, + return new Object[][] { { factory.createRequest(method, new Object[] { URI.create("https://host:443") }) }, { factory.createRequest(method, new Object[] { URI.create("https://host/path") }) }, { factory.createRequest(method, new Object[] { URI.create("https://host/?query") }) @@ -83,8 +82,8 @@ public class AddSessionTokenToRequestTest { String query = request.getEndpoint().getQuery(); filter.filter(request); - assertEquals(request.getEndpoint().getQuery(), query == null ? "sessionToken=" + token - : query + "&sessionToken=" + token); + assertEquals(request.getEndpoint().getQuery(), query == null ? "sessionToken=" + token : query + "&sessionToken=" + + token); } @Test @@ -101,14 +100,14 @@ public class AddSessionTokenToRequestTest { */ @BeforeClass protected void createFilter() { - injector = Guice.createInjector(new RestModule(), new ExecutorServiceModule( - sameThreadExecutor(), sameThreadExecutor()), - new JavaUrlHttpCommandExecutorServiceModule(), new AbstractModule() { + injector = Guice.createInjector(new RestModule(), new ExecutorServiceModule(MoreExecutors.sameThreadExecutor(), + MoreExecutors.sameThreadExecutor()), new JavaUrlHttpCommandExecutorServiceModule(), + new AbstractModule() { protected void configure() { bind(DateService.class); - Names.bindProperties(this.binder(), new SDNPropertiesBuilder(new Properties()) - .credentials("appkey/appname/username", "password").build()); + Names.bindProperties(this.binder(), new SDNPropertiesBuilder(new Properties()).credentials( + "appkey/appname/username", "password").build()); bind(Logger.LoggerFactory.class).toInstance(new LoggerFactory() { public Logger getLogger(String category) { return Logger.NULL; diff --git a/nirvanix/sdn/core/src/test/java/org/jclouds/nirvanix/sdn/filters/InsertUserContextIntoPathTest.java b/nirvanix/sdn/core/src/test/java/org/jclouds/nirvanix/sdn/filters/InsertUserContextIntoPathTest.java index 81f1c39462..59beb6bcda 100644 --- a/nirvanix/sdn/core/src/test/java/org/jclouds/nirvanix/sdn/filters/InsertUserContextIntoPathTest.java +++ b/nirvanix/sdn/core/src/test/java/org/jclouds/nirvanix/sdn/filters/InsertUserContextIntoPathTest.java @@ -18,7 +18,6 @@ */ package org.jclouds.nirvanix.sdn.filters; -import static org.jclouds.concurrent.ConcurrentUtils.sameThreadExecutor; import static org.easymock.EasyMock.expect; import static org.easymock.classextension.EasyMock.createMock; import static org.easymock.classextension.EasyMock.replay; @@ -30,6 +29,7 @@ import java.util.Properties; import javax.ws.rs.POST; +import org.jclouds.concurrent.MoreExecutors; import org.jclouds.concurrent.config.ExecutorServiceModule; import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule; import org.jclouds.logging.Logger; @@ -65,8 +65,7 @@ public class InsertUserContextIntoPathTest { } public void testRequestInvalid() { - GeneratedHttpRequest request = factory.createRequest(method, URI - .create("https://host/path")); + GeneratedHttpRequest request = factory.createRequest(method, URI.create("https://host/path")); filter.filter(request); filter.filter(request); assertEquals(request.getEndpoint().getPath(), "/token/appname/username/path"); @@ -74,8 +73,7 @@ public class InsertUserContextIntoPathTest { } public void testRequestNoSession() { - GeneratedHttpRequest request = factory.createRequest(method, URI - .create("https://host/path")); + GeneratedHttpRequest request = factory.createRequest(method, URI.create("https://host/path")); filter.filter(request); assertEquals(request.getEndpoint().getPath(), "/token/appname/username/path"); assertEquals(request.getEndpoint().getHost(), "host"); @@ -91,9 +89,9 @@ public class InsertUserContextIntoPathTest { @BeforeClass protected void createFilter() throws SecurityException, NoSuchMethodException { - injector = Guice.createInjector(new RestModule(), new ExecutorServiceModule( - sameThreadExecutor(), sameThreadExecutor()), - new JavaUrlHttpCommandExecutorServiceModule(), new AbstractModule() { + injector = Guice.createInjector(new RestModule(), new ExecutorServiceModule(MoreExecutors.sameThreadExecutor(), + MoreExecutors.sameThreadExecutor()), new JavaUrlHttpCommandExecutorServiceModule(), + new AbstractModule() { protected void configure() { install(new SDNAuthRestClientModule()); @@ -106,15 +104,14 @@ public class InsertUserContextIntoPathTest { expect(sessionManager.getSessionToken()).andReturn("token").anyTimes(); replay(sessionManager); bind(AddSessionTokenToRequest.class).toInstance(sessionManager); - Names.bindProperties(this.binder(), new SDNPropertiesBuilder(new Properties()) - .credentials("appkey/appname/username", "password").build()); + Names.bindProperties(this.binder(), new SDNPropertiesBuilder(new Properties()).credentials( + "appkey/appname/username", "password").build()); } }); filter = injector.getInstance(InsertUserContextIntoPath.class); - factory = injector.getInstance(Key - .get(new TypeLiteral>() { - })); + factory = injector.getInstance(Key.get(new TypeLiteral>() { + })); method = TestService.class.getMethod("foo", URI.class); } diff --git a/opscodeplatform/src/test/java/org/jclouds/opscodeplatform/OpscodePlatformAsyncClientTest.java b/opscodeplatform/src/test/java/org/jclouds/opscodeplatform/OpscodePlatformAsyncClientTest.java index 8d43a750d2..7ca17010f8 100644 --- a/opscodeplatform/src/test/java/org/jclouds/opscodeplatform/OpscodePlatformAsyncClientTest.java +++ b/opscodeplatform/src/test/java/org/jclouds/opscodeplatform/OpscodePlatformAsyncClientTest.java @@ -25,7 +25,6 @@ package org.jclouds.opscodeplatform; import static org.easymock.classextension.EasyMock.createMock; import static org.easymock.classextension.EasyMock.replay; -import static org.jclouds.concurrent.ConcurrentUtils.sameThreadExecutor; import static org.jclouds.rest.RestContextFactory.createContextBuilder; import static org.testng.Assert.assertEquals; @@ -38,6 +37,7 @@ import org.jclouds.chef.domain.Organization; import org.jclouds.chef.domain.User; import org.jclouds.chef.filters.SignedHeaderAuth; import org.jclouds.chef.filters.SignedHeaderAuthTest; +import org.jclouds.concurrent.MoreExecutors; import org.jclouds.concurrent.config.ConfiguresExecutorService; import org.jclouds.concurrent.config.ExecutorServiceModule; import org.jclouds.date.TimeStamp; @@ -276,7 +276,7 @@ public class OpscodePlatformAsyncClientTest extends RestClientTest> list() { - return compose(async.listContainers(), + return Futures.compose(async.listContainers(), new Function, org.jclouds.blobstore.domain.PageSet>() { public org.jclouds.blobstore.domain.PageSet apply( Set from) { @@ -144,9 +144,10 @@ public class CloudFilesAsyncBlobStore extends BaseAsyncBlobStore { org.jclouds.rackspace.cloudfiles.options.ListContainerOptions httpOptions = container2ContainerListOptions .apply(options); ListenableFuture> returnVal = async.listObjects(container, httpOptions); - ListenableFuture> list = compose(returnVal, container2ResourceList, service); - return options.isDetailed() ? compose(list, fetchBlobMetadataProvider.get().setContainerName(container), service) - : list; + ListenableFuture> list = Futures.compose(returnVal, container2ResourceList, + service); + return options.isDetailed() ? Futures.compose(list, fetchBlobMetadataProvider.get().setContainerName(container), + service) : list; } /** @@ -172,14 +173,15 @@ public class CloudFilesAsyncBlobStore extends BaseAsyncBlobStore { */ @Override public ListenableFuture blobMetadata(String container, String key) { - return compose(async.getObjectInfo(container, key), new Function() { + return Futures.compose(async.getObjectInfo(container, key), + new Function() { - @Override - public BlobMetadata apply(MutableObjectInfoWithMetadata from) { - return object2BlobMd.apply(from); - } + @Override + public BlobMetadata apply(MutableObjectInfoWithMetadata from) { + return object2BlobMd.apply(from); + } - }, service); + }, service); } /** @@ -194,7 +196,7 @@ public class CloudFilesAsyncBlobStore extends BaseAsyncBlobStore { public ListenableFuture getBlob(String container, String key, org.jclouds.blobstore.options.GetOptions options) { GetOptions httpOptions = blob2ObjectGetOptions.apply(options); ListenableFuture returnVal = async.getObject(container, key, httpOptions); - return compose(returnVal, object2Blob, service); + return Futures.compose(returnVal, object2Blob, service); } /** diff --git a/rackspace/src/main/java/org/jclouds/rackspace/cloudfiles/blobstore/functions/ObjectToBlobMetadata.java b/rackspace/src/main/java/org/jclouds/rackspace/cloudfiles/blobstore/functions/ObjectToBlobMetadata.java index d6c4b28044..f208d3dad6 100644 --- a/rackspace/src/main/java/org/jclouds/rackspace/cloudfiles/blobstore/functions/ObjectToBlobMetadata.java +++ b/rackspace/src/main/java/org/jclouds/rackspace/cloudfiles/blobstore/functions/ObjectToBlobMetadata.java @@ -25,7 +25,7 @@ import org.jclouds.blobstore.domain.MutableBlobMetadata; import org.jclouds.blobstore.domain.StorageType; import org.jclouds.blobstore.domain.internal.MutableBlobMetadataImpl; import org.jclouds.blobstore.strategy.IfDirectoryReturnNameStrategy; -import org.jclouds.encryption.EncryptionService; +import org.jclouds.crypto.CryptoStreams; import org.jclouds.rackspace.cloudfiles.domain.MutableObjectInfoWithMetadata; import org.jclouds.rackspace.cloudfiles.domain.ObjectInfo; @@ -37,13 +37,10 @@ import com.google.common.base.Function; @Singleton public class ObjectToBlobMetadata implements Function { private final IfDirectoryReturnNameStrategy ifDirectoryReturnName; - private final EncryptionService encryptionService; @Inject - public ObjectToBlobMetadata(IfDirectoryReturnNameStrategy ifDirectoryReturnName, - EncryptionService encryptionService) { + public ObjectToBlobMetadata(IfDirectoryReturnNameStrategy ifDirectoryReturnName) { this.ifDirectoryReturnName = ifDirectoryReturnName; - this.encryptionService = encryptionService; } public MutableBlobMetadata apply(ObjectInfo from) { @@ -54,7 +51,7 @@ public class ObjectToBlobMetadata implements Function { - private final EncryptionService encryptionService; - - @Inject - public ResourceToObjectInfo(EncryptionService encryptionService) { - this.encryptionService = encryptionService; - } +public class ResourceToObjectInfo implements Function { public MutableObjectInfoWithMetadata apply(StorageMetadata from) { if (from == null) @@ -56,7 +48,7 @@ public class ResourceToObjectInfo implements to.setContentType("application/directory"); } if (from.getETag() != null && to.getHash() == null) - to.setHash(encryptionService.fromHex(from.getETag())); + to.setHash(CryptoStreams.hex(from.getETag())); to.setName(from.getName()); to.setLastModified(from.getLastModified()); if (from.getSize() != null) diff --git a/rackspace/src/main/java/org/jclouds/rackspace/cloudfiles/domain/CFObject.java b/rackspace/src/main/java/org/jclouds/rackspace/cloudfiles/domain/CFObject.java index 523a43a4a3..90c8b35786 100644 --- a/rackspace/src/main/java/org/jclouds/rackspace/cloudfiles/domain/CFObject.java +++ b/rackspace/src/main/java/org/jclouds/rackspace/cloudfiles/domain/CFObject.java @@ -18,7 +18,7 @@ */ package org.jclouds.rackspace.cloudfiles.domain; -import org.jclouds.http.PayloadEnclosing; +import org.jclouds.io.PayloadEnclosing; import com.google.common.collect.Multimap; import com.google.inject.internal.Nullable; 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 7704fe0e15..9cafe4bfd2 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,9 +22,9 @@ import static com.google.common.base.Preconditions.checkNotNull; import javax.inject.Inject; -import org.jclouds.http.PayloadEnclosing; import org.jclouds.http.internal.PayloadEnclosingImpl; import org.jclouds.io.Payload; +import org.jclouds.io.PayloadEnclosing; import org.jclouds.io.payloads.DelegatingPayload; import org.jclouds.rackspace.cloudfiles.domain.CFObject; import org.jclouds.rackspace.cloudfiles.domain.MutableObjectInfoWithMetadata; diff --git a/rackspace/src/main/java/org/jclouds/rackspace/cloudfiles/functions/ParseObjectInfoFromHeaders.java b/rackspace/src/main/java/org/jclouds/rackspace/cloudfiles/functions/ParseObjectInfoFromHeaders.java index 3061b85a2a..1981ae11f9 100644 --- a/rackspace/src/main/java/org/jclouds/rackspace/cloudfiles/functions/ParseObjectInfoFromHeaders.java +++ b/rackspace/src/main/java/org/jclouds/rackspace/cloudfiles/functions/ParseObjectInfoFromHeaders.java @@ -24,7 +24,7 @@ import javax.inject.Inject; import org.jclouds.blobstore.domain.BlobMetadata; import org.jclouds.blobstore.functions.ParseSystemAndUserMetadataFromHeaders; -import org.jclouds.encryption.EncryptionService; +import org.jclouds.crypto.CryptoStreams; import org.jclouds.http.HttpRequest; import org.jclouds.http.HttpResponse; import org.jclouds.rackspace.cloudfiles.blobstore.functions.ResourceToObjectInfo; @@ -39,22 +39,19 @@ import com.google.common.base.Function; * @author Adrian Cole */ public class ParseObjectInfoFromHeaders implements Function, - InvocationContext { + InvocationContext { private final ParseSystemAndUserMetadataFromHeaders blobMetadataParser; private final ResourceToObjectInfo blobToObjectInfo; - private final EncryptionService encryptionService; @Inject public ParseObjectInfoFromHeaders(ParseSystemAndUserMetadataFromHeaders blobMetadataParser, - ResourceToObjectInfo blobToObjectInfo, EncryptionService encryptionService) { + ResourceToObjectInfo blobToObjectInfo) { this.blobMetadataParser = blobMetadataParser; this.blobToObjectInfo = blobToObjectInfo; - this.encryptionService = encryptionService; } /** - * parses the http response headers to create a new - * {@link MutableObjectInfoWithMetadata} object. + * parses the http response headers to create a new {@link MutableObjectInfoWithMetadata} object. */ public MutableObjectInfoWithMetadata apply(HttpResponse from) { BlobMetadata base = blobMetadataParser.apply(from); @@ -62,7 +59,7 @@ public class ParseObjectInfoFromHeaders implements Function contextSpec = contextSpec("test", - "https://api.mosso.com", "1", null, null, RackspaceAuthClient.class, - RackspaceAuthAsyncClient.class); + "https://api.mosso.com", "1", null, null, RackspaceAuthClient.class, RackspaceAuthAsyncClient.class); context = createContextBuilder( contextSpec, - ImmutableSet. of(new Log4JLoggingModule(), new ExecutorServiceModule( - sameThreadExecutor(), sameThreadExecutor()))).buildContext(); + ImmutableSet. of(new Log4JLoggingModule(), new ExecutorServiceModule(MoreExecutors + .sameThreadExecutor(), MoreExecutors.sameThreadExecutor()))).buildContext(); } } 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 bd548d9137..7c87d6fdcf 100644 --- a/rackspace/src/test/java/org/jclouds/rackspace/cloudfiles/CloudFilesClientLiveTest.java +++ b/rackspace/src/test/java/org/jclouds/rackspace/cloudfiles/CloudFilesClientLiveTest.java @@ -35,8 +35,10 @@ import java.util.concurrent.TimeoutException; import org.jclouds.blobstore.ContainerNotFoundException; import org.jclouds.blobstore.domain.PageSet; import org.jclouds.blobstore.integration.internal.BaseBlobStoreIntegrationTest; +import org.jclouds.crypto.CryptoStreams; import org.jclouds.http.HttpResponseException; import org.jclouds.http.options.GetOptions; +import org.jclouds.io.Payloads; import org.jclouds.rackspace.cloudfiles.domain.AccountMetadata; import org.jclouds.rackspace.cloudfiles.domain.CFObject; import org.jclouds.rackspace.cloudfiles.domain.ContainerCDNMetadata; @@ -303,8 +305,7 @@ public class CloudFilesClientLiveTest extends BaseBlobStoreIntegrationTest { byte[] md5 = object.getPayload().getContentMD5(); String newEtag = getApi().putObject(containerName, object); assert newEtag != null; - assertEquals(context.utils().encryption().hex(md5), context.utils().encryption().hex( - object.getPayload().getContentMD5())); + assertEquals(CryptoStreams.hex(md5), CryptoStreams.hex(object.getPayload().getContentMD5())); // Test HEAD of missing object assert getApi().getObjectInfo(containerName, "non-existent-object") == null; @@ -320,8 +321,8 @@ public class CloudFilesClientLiveTest extends BaseBlobStoreIntegrationTest { // assertEquals(metadata.getBytes(), new Long(data.length())); // assertEquals(metadata.getContentType(), "text/plain"); - assertEquals(context.utils().encryption().hex(md5), context.utils().encryption().hex(metadata.getHash())); - assertEquals(metadata.getHash(), context.utils().encryption().fromHex(newEtag)); + assertEquals(CryptoStreams.hex(md5), CryptoStreams.hex(metadata.getHash())); + assertEquals(metadata.getHash(), CryptoStreams.hex(newEtag)); assertEquals(metadata.getMetadata().entrySet().size(), 1); assertEquals(metadata.getMetadata().get("metadata"), "metadata-value"); @@ -340,9 +341,8 @@ public class CloudFilesClientLiveTest extends BaseBlobStoreIntegrationTest { // object.getMetadata().getName()); assertEquals(getBlob.getInfo().getBytes(), new Long(data.length())); assertEquals(getBlob.getInfo().getContentType(), "text/plain"); - assertEquals(context.utils().encryption().hex(md5), context.utils().encryption().hex( - getBlob.getInfo().getHash())); - assertEquals(context.utils().encryption().fromHex(newEtag), getBlob.getInfo().getHash()); + assertEquals(CryptoStreams.hex(md5), CryptoStreams.hex(getBlob.getInfo().getHash())); + assertEquals(CryptoStreams.hex(newEtag), getBlob.getInfo().getHash()); assertEquals(getBlob.getInfo().getMetadata().entrySet().size(), 2); assertEquals(getBlob.getInfo().getMetadata().get("new-metadata-1"), "value-1"); assertEquals(getBlob.getInfo().getMetadata().get("new-metadata-2"), "value-2"); @@ -351,7 +351,7 @@ public class CloudFilesClientLiveTest extends BaseBlobStoreIntegrationTest { // transit) String correctEtag = newEtag; String incorrectEtag = "0" + correctEtag.substring(1); - object.getInfo().setHash(context.utils().encryption().fromHex(incorrectEtag)); + object.getInfo().setHash(CryptoStreams.hex(incorrectEtag)); try { getApi().putObject(containerName, object); } catch (HttpResponseException e) { @@ -364,8 +364,7 @@ public class CloudFilesClientLiveTest extends BaseBlobStoreIntegrationTest { blob.getInfo().setName("chunked-object"); blob.setPayload(bais); newEtag = getApi().putObject(containerName, blob); - assertEquals(context.utils().encryption().hex(md5), context.utils().encryption().hex( - getBlob.getInfo().getHash())); + assertEquals(CryptoStreams.hex(md5), CryptoStreams.hex(getBlob.getInfo().getHash())); // Test GET with options // Non-matching ETag @@ -380,7 +379,7 @@ public class CloudFilesClientLiveTest extends BaseBlobStoreIntegrationTest { // Matching ETag getBlob = getApi().getObject(containerName, object.getInfo().getName(), GetOptions.Builder.ifETagMatches(newEtag)); - assertEquals(getBlob.getInfo().getHash(), context.utils().encryption().fromHex(newEtag)); + assertEquals(getBlob.getInfo().getHash(), CryptoStreams.hex(newEtag)); getBlob = getApi().getObject(containerName, object.getInfo().getName(), GetOptions.Builder.startAt(8)); assertEquals(Utils.toStringAndClose(getBlob.getPayload().getInput()), data.substring(8)); @@ -393,7 +392,7 @@ public class CloudFilesClientLiveTest extends BaseBlobStoreIntegrationTest { CFObject object = getApi().newCFObject(); object.getInfo().setName(key); object.setPayload(data); - context.utils().encryption().generateMD5BufferingIfNotRepeatable(object); + Payloads.calculateMD5(object); object.getInfo().setContentType("text/plain"); object.getInfo().getMetadata().put("Metadata", "metadata-value"); return object; diff --git a/rackspace/src/test/java/org/jclouds/rackspace/cloudfiles/domain/internal/ParseObjectInfoListFromJsonResponseTest.java b/rackspace/src/test/java/org/jclouds/rackspace/cloudfiles/domain/internal/ParseObjectInfoListFromJsonResponseTest.java index 9554c52408..5364ec4b8b 100644 --- a/rackspace/src/test/java/org/jclouds/rackspace/cloudfiles/domain/internal/ParseObjectInfoListFromJsonResponseTest.java +++ b/rackspace/src/test/java/org/jclouds/rackspace/cloudfiles/domain/internal/ParseObjectInfoListFromJsonResponseTest.java @@ -26,8 +26,8 @@ import static org.testng.Assert.assertEquals; import java.io.InputStream; import java.util.Set; +import org.jclouds.crypto.CryptoStreams; import org.jclouds.date.internal.SimpleDateFormatDateService; -import org.jclouds.encryption.EncryptionService; import org.jclouds.json.config.GsonModule; import org.jclouds.rackspace.cloudfiles.domain.ObjectInfo; import org.jclouds.rackspace.cloudfiles.functions.ParseObjectInfoListFromJsonResponse; @@ -55,14 +55,14 @@ public class ParseObjectInfoListFromJsonResponseTest { Set expects = Sets.newHashSet(); ObjectInfoImpl one = i.getInstance(ObjectInfoImpl.class); one.name = "test_obj_1"; - one.hash = i.getInstance(EncryptionService.class).fromHex("4281c348eaf83e70ddce0e07221c3d28"); + one.hash = CryptoStreams.hex("4281c348eaf83e70ddce0e07221c3d28"); one.bytes = 14l; one.content_type = "application/octet-stream"; one.last_modified = new SimpleDateFormatDateService().iso8601DateParse("2009-02-03T05:26:32.612Z"); expects.add(one); ObjectInfoImpl two = i.getInstance(ObjectInfoImpl.class); two.name = ("test_obj_2"); - two.hash = (i.getInstance(EncryptionService.class).fromHex("b039efe731ad111bc1b0ef221c3849d0")); + two.hash = CryptoStreams.hex("b039efe731ad111bc1b0ef221c3849d0"); two.bytes = (64l); two.content_type = ("application/octet-stream"); two.last_modified = (new SimpleDateFormatDateService().iso8601DateParse("2009-02-03T05:26:32.612Z")); @@ -70,7 +70,7 @@ public class ParseObjectInfoListFromJsonResponseTest { GeneratedHttpRequest request = createMock(GeneratedHttpRequest.class); ListContainerOptions options = new ListContainerOptions(); expect(request.getArgs()).andReturn(new Object[] { "containter", new ListContainerOptions[] { options } }) - .atLeastOnce(); + .atLeastOnce(); replay(request); ParseObjectInfoListFromJsonResponse parser = i.getInstance(ParseObjectInfoListFromJsonResponse.class); parser.setContext(request); diff --git a/rackspace/src/test/java/org/jclouds/rackspace/cloudfiles/internal/StubCloudFilesAsyncClient.java b/rackspace/src/test/java/org/jclouds/rackspace/cloudfiles/internal/StubCloudFilesAsyncClient.java index 2fa5cd8e04..0f277c8e9f 100644 --- a/rackspace/src/test/java/org/jclouds/rackspace/cloudfiles/internal/StubCloudFilesAsyncClient.java +++ b/rackspace/src/test/java/org/jclouds/rackspace/cloudfiles/internal/StubCloudFilesAsyncClient.java @@ -19,7 +19,6 @@ package org.jclouds.rackspace.cloudfiles.internal; import static com.google.common.base.Preconditions.checkNotNull; -import static org.jclouds.concurrent.ConcurrentUtils.compose; import static com.google.common.util.concurrent.Futures.immediateFuture; import java.net.URI; @@ -39,6 +38,7 @@ import org.jclouds.blobstore.domain.BlobMetadata; import org.jclouds.blobstore.domain.PageSet; import org.jclouds.blobstore.functions.HttpGetOptionsListToGetOptions; import org.jclouds.blobstore.options.ListContainerOptions; +import org.jclouds.concurrent.Futures; import org.jclouds.http.options.GetOptions; import org.jclouds.rackspace.cloudfiles.CloudFilesAsyncClient; import org.jclouds.rackspace.cloudfiles.blobstore.functions.BlobToObject; @@ -131,11 +131,11 @@ public class StubCloudFilesAsyncClient implements CloudFilesAsyncClient { public ListenableFuture getObject(String container, String key, GetOptions... options) { org.jclouds.blobstore.options.GetOptions getOptions = httpGetOptionsConverter.apply(options); - return compose(blobStore.getBlob(container, key, getOptions), blob2Object, service); + return Futures.compose(blobStore.getBlob(container, key, getOptions), blob2Object, service); } public ListenableFuture getObjectInfo(String container, String key) { - return compose(blobStore.blobMetadata(container, key), + return Futures.compose(blobStore.blobMetadata(container, key), new Function() { @Override @@ -164,7 +164,7 @@ public class StubCloudFilesAsyncClient implements CloudFilesAsyncClient { public ListenableFuture> listObjects(String container, org.jclouds.rackspace.cloudfiles.options.ListContainerOptions... optionsList) { ListContainerOptions options = container2ContainerListOptions.apply(optionsList); - return compose(blobStore.list(container, options), resource2ObjectList, service); + return Futures.compose(blobStore.list(container, options), resource2ObjectList, service); } public ListenableFuture putObject(String container, CFObject object) { diff --git a/slicehost/src/main/java/org/jclouds/slicehost/filters/SlicehostBasic.java b/slicehost/src/main/java/org/jclouds/slicehost/filters/SlicehostBasic.java index b3a658dd52..7630be8548 100644 --- a/slicehost/src/main/java/org/jclouds/slicehost/filters/SlicehostBasic.java +++ b/slicehost/src/main/java/org/jclouds/slicehost/filters/SlicehostBasic.java @@ -27,7 +27,7 @@ import javax.inject.Named; import javax.inject.Singleton; import org.jclouds.Constants; -import org.jclouds.encryption.EncryptionService; +import org.jclouds.crypto.CryptoStreams; import org.jclouds.http.HttpException; import org.jclouds.http.HttpRequest; import org.jclouds.http.HttpRequestFilter; @@ -39,17 +39,15 @@ import org.jclouds.http.HttpRequestFilter; @Singleton public class SlicehostBasic implements HttpRequestFilter { private final String apikey; - private final EncryptionService encryptionService; @Inject - public SlicehostBasic(@Named(Constants.PROPERTY_IDENTITY) String apikey, EncryptionService encryptionService) { + public SlicehostBasic(@Named(Constants.PROPERTY_IDENTITY) String apikey) { this.apikey = checkNotNull(apikey, "apikey"); - this.encryptionService = checkNotNull(encryptionService, "encryptionService"); } @Override public void filter(HttpRequest request) throws HttpException { request.getHeaders().replaceValues("Authorization", - Collections.singleton(String.format("Basic %s", encryptionService.base64(apikey.getBytes())))); + Collections.singleton(String.format("Basic %s", CryptoStreams.base64(apikey.getBytes())))); } } 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 de4b405996..aceac5029e 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 @@ -58,6 +58,7 @@ import org.jclouds.blobstore.domain.StorageMetadata; import org.jclouds.blobstore.domain.StorageType; import org.jclouds.blobstore.options.ListContainerOptions; import org.jclouds.blobstore.strategy.internal.ConcatenateContainerLists; +import org.jclouds.io.Payloads; import org.jclouds.util.Utils; import com.google.common.base.Predicate; @@ -76,8 +77,8 @@ public class BlobStoreFileObject extends AbstractFileObject { private static final Logger logger = Logger.getLogger(BlobStoreFileObject.class); private static final Pattern UNDESCRIBED = Pattern.compile("[^/]*//*"); - public BlobStoreFileObject(FileName fileName, BlobStoreFileSystem fileSystem, - BlobStoreContext context, String container) throws FileSystemException { + public BlobStoreFileObject(FileName fileName, BlobStoreFileSystem fileSystem, BlobStoreContext context, + String container) throws FileSystemException { super(fileName, fileSystem); this.context = checkNotNull(context, "context"); this.container = checkNotNull(container, "container"); @@ -91,8 +92,7 @@ public class BlobStoreFileObject extends AbstractFileObject { private final Blob blob; private final File file; - public BlobStoreOutputStream(File file, BlobStore context, Blob blob) - throws FileNotFoundException { + public BlobStoreOutputStream(File file, BlobStore context, Blob blob) throws FileNotFoundException { super(Channels.newOutputStream(new RandomAccessFile(file, "rw").getChannel())); this.context = context; this.file = file; @@ -102,12 +102,11 @@ public class BlobStoreFileObject extends AbstractFileObject { protected void onClose() throws IOException { try { blob.setPayload(file); - context.getContext().utils().encryption().generateMD5BufferingIfNotRepeatable(blob); - logger.info(String.format(">> put: %s/%s %d bytes", getContainer(), - getNameTrimLeadingSlashes(), blob.getPayload().getContentLength())); + Payloads.calculateMD5(blob); + logger.info(String.format(">> put: %s/%s %d bytes", getContainer(), getNameTrimLeadingSlashes(), blob + .getPayload().getContentLength())); String tag = context.putBlob(getContainer(), blob); - logger.info(String.format("<< tag %s: %s/%s", tag, getContainer(), - getNameTrimLeadingSlashes())); + logger.info(String.format("<< tag %s: %s/%s", tag, getContainer(), getNameTrimLeadingSlashes())); } finally { file.delete(); } @@ -176,9 +175,10 @@ public class BlobStoreFileObject extends AbstractFileObject { } String childName = Utils.replaceAll(md.getName(), UNDESCRIBED, ""); BlobStoreFileObject fo = (BlobStoreFileObject) FileObjectUtils - .getAbstractFileObject(getFileSystem().resolveFile( - getFileSystem().getFileSystemManager().resolveName(getName(), - childName, NameScope.CHILD))); + .getAbstractFileObject(getFileSystem() + .resolveFile( + getFileSystem().getFileSystemManager().resolveName(getName(), childName, + NameScope.CHILD))); children.add(fo); } } @@ -232,8 +232,7 @@ public class BlobStoreFileObject extends AbstractFileObject { private void deleteBlob(String id) { getBlobStore().removeBlob(getContainer(), getNameTrimLeadingSlashes()); - logger.info(String.format("<< deleted blob: %s/%s", getContainer(), - getNameTrimLeadingSlashes())); + logger.info(String.format("<< deleted blob: %s/%s", getContainer(), getNameTrimLeadingSlashes())); } @Override @@ -243,15 +242,13 @@ public class BlobStoreFileObject extends AbstractFileObject { if (metadata != null) { return new BlobStoreOutputStream(file, getBlobStore(), newBlob(getBlobStore(), metadata)); } else { - return new BlobStoreOutputStream(file, getBlobStore(), getBlobStore().newBlob( - getNameTrimLeadingSlashes())); + return new BlobStoreOutputStream(file, getBlobStore(), getBlobStore().newBlob(getNameTrimLeadingSlashes())); } } @Override protected void doCreateFolder() throws Exception { - logger.info(String - .format(">> put folder: %s/%s", getContainer(), getNameTrimLeadingSlashes())); + logger.info(String.format(">> put folder: %s/%s", getContainer(), getNameTrimLeadingSlashes())); getBlobStore().createDirectory(getContainer(), getNameTrimLeadingSlashes()); } @@ -298,13 +295,12 @@ public class BlobStoreFileObject extends AbstractFileObject { options.inDirectory(dir); } try { - metadata = Iterables.find(lister.execute(getContainer(), options), - new Predicate() { - @Override - public boolean apply(StorageMetadata input) { - return input.getType() != StorageType.BLOB && input.getName().equals(name); - } - }); + metadata = Iterables.find(lister.execute(getContainer(), options), new Predicate() { + @Override + public boolean apply(StorageMetadata input) { + return input.getType() != StorageType.BLOB && input.getName().equals(name); + } + }); logger.info(String.format("<< dir: %s/%s", getContainer(), name)); } catch (NoSuchElementException nse) { metadata = null; @@ -320,8 +316,7 @@ public class BlobStoreFileObject extends AbstractFileObject { } @Override - protected RandomAccessContent doGetRandomAccessContent(final RandomAccessMode mode) - throws Exception { + protected RandomAccessContent doGetRandomAccessContent(final RandomAccessMode mode) throws Exception { return new BlobStoreRandomAccessContent(this, mode); } @@ -334,8 +329,7 @@ public class BlobStoreFileObject extends AbstractFileObject { if (metadata == null || metadata.getLastModified() == null) { getMetadataAtPath(getNameTrimLeadingSlashes()); } - return metadata.getLastModified() != null ? metadata.getLastModified().getTime() : super - .doGetLastModifiedTime(); + return metadata.getLastModified() != null ? metadata.getLastModified().getTime() : super.doGetLastModifiedTime(); } @SuppressWarnings("unchecked") @@ -344,8 +338,7 @@ public class BlobStoreFileObject extends AbstractFileObject { if (metadata == null || metadata.getUserMetadata() == null) { getMetadataAtPath(getNameTrimLeadingSlashes()); } - return metadata.getUserMetadata() != null ? metadata.getUserMetadata() : super - .doGetAttributes(); + return metadata.getUserMetadata() != null ? metadata.getUserMetadata() : super.doGetAttributes(); } @Override diff --git a/vcloud/core/src/main/java/org/jclouds/vcloud/functions/AllCatalogItemsInCatalog.java b/vcloud/core/src/main/java/org/jclouds/vcloud/functions/AllCatalogItemsInCatalog.java index 6e786bab70..00bddf2bee 100644 --- a/vcloud/core/src/main/java/org/jclouds/vcloud/functions/AllCatalogItemsInCatalog.java +++ b/vcloud/core/src/main/java/org/jclouds/vcloud/functions/AllCatalogItemsInCatalog.java @@ -19,7 +19,7 @@ package org.jclouds.vcloud.functions; import static com.google.common.collect.Iterables.filter; -import static org.jclouds.concurrent.ConcurrentUtils.transformParallel; +import static org.jclouds.concurrent.FutureIterables.transformParallel; import java.util.concurrent.ExecutorService; import java.util.concurrent.Future; diff --git a/vcloud/core/src/main/java/org/jclouds/vcloud/functions/AllCatalogsInOrganization.java b/vcloud/core/src/main/java/org/jclouds/vcloud/functions/AllCatalogsInOrganization.java index 91f6f4c09e..259f63cb0a 100644 --- a/vcloud/core/src/main/java/org/jclouds/vcloud/functions/AllCatalogsInOrganization.java +++ b/vcloud/core/src/main/java/org/jclouds/vcloud/functions/AllCatalogsInOrganization.java @@ -18,7 +18,7 @@ */ package org.jclouds.vcloud.functions; -import static org.jclouds.concurrent.ConcurrentUtils.transformParallel; +import static org.jclouds.concurrent.FutureIterables.transformParallel; import java.util.concurrent.ExecutorService; import java.util.concurrent.Future; diff --git a/vcloud/core/src/main/java/org/jclouds/vcloud/functions/AllVDCsInOrganization.java b/vcloud/core/src/main/java/org/jclouds/vcloud/functions/AllVDCsInOrganization.java index e8fdea4dd3..c256022707 100644 --- a/vcloud/core/src/main/java/org/jclouds/vcloud/functions/AllVDCsInOrganization.java +++ b/vcloud/core/src/main/java/org/jclouds/vcloud/functions/AllVDCsInOrganization.java @@ -18,7 +18,7 @@ */ package org.jclouds.vcloud.functions; -import static org.jclouds.concurrent.ConcurrentUtils.transformParallel; +import static org.jclouds.concurrent.FutureIterables.transformParallel; import java.util.concurrent.ExecutorService; import java.util.concurrent.Future; diff --git a/vcloud/core/src/main/java/org/jclouds/vcloud/functions/OrganizatonsForLocations.java b/vcloud/core/src/main/java/org/jclouds/vcloud/functions/OrganizatonsForLocations.java index 2044294f01..d3fd286733 100644 --- a/vcloud/core/src/main/java/org/jclouds/vcloud/functions/OrganizatonsForLocations.java +++ b/vcloud/core/src/main/java/org/jclouds/vcloud/functions/OrganizatonsForLocations.java @@ -19,7 +19,7 @@ package org.jclouds.vcloud.functions; import static com.google.common.collect.Iterables.filter; -import static org.jclouds.concurrent.ConcurrentUtils.transformParallel; +import static org.jclouds.concurrent.FutureIterables.transformParallel; import java.util.concurrent.ExecutorService; import java.util.concurrent.Future; diff --git a/vcloud/core/src/main/java/org/jclouds/vcloud/functions/VAppTemplatesForCatalogItems.java b/vcloud/core/src/main/java/org/jclouds/vcloud/functions/VAppTemplatesForCatalogItems.java index a09e2a2dcf..ba1f5f9ee3 100644 --- a/vcloud/core/src/main/java/org/jclouds/vcloud/functions/VAppTemplatesForCatalogItems.java +++ b/vcloud/core/src/main/java/org/jclouds/vcloud/functions/VAppTemplatesForCatalogItems.java @@ -19,7 +19,7 @@ package org.jclouds.vcloud.functions; import static com.google.common.collect.Iterables.filter; -import static org.jclouds.concurrent.ConcurrentUtils.transformParallel; +import static org.jclouds.concurrent.FutureIterables.transformParallel; import java.util.concurrent.ExecutorService; import java.util.concurrent.Future; diff --git a/vcloud/core/src/main/java/org/jclouds/vcloud/functions/VAppTemplatesForResourceEntities.java b/vcloud/core/src/main/java/org/jclouds/vcloud/functions/VAppTemplatesForResourceEntities.java index f732650723..632483f345 100644 --- a/vcloud/core/src/main/java/org/jclouds/vcloud/functions/VAppTemplatesForResourceEntities.java +++ b/vcloud/core/src/main/java/org/jclouds/vcloud/functions/VAppTemplatesForResourceEntities.java @@ -19,7 +19,7 @@ package org.jclouds.vcloud.functions; import static com.google.common.collect.Iterables.filter; -import static org.jclouds.concurrent.ConcurrentUtils.transformParallel; +import static org.jclouds.concurrent.FutureIterables.transformParallel; import java.util.concurrent.ExecutorService; import java.util.concurrent.Future; diff --git a/vcloud/core/src/test/java/org/jclouds/vcloud/VCloudLoginLiveTest.java b/vcloud/core/src/test/java/org/jclouds/vcloud/VCloudLoginLiveTest.java index 216ef06320..0abf563645 100755 --- a/vcloud/core/src/test/java/org/jclouds/vcloud/VCloudLoginLiveTest.java +++ b/vcloud/core/src/test/java/org/jclouds/vcloud/VCloudLoginLiveTest.java @@ -19,7 +19,6 @@ package org.jclouds.vcloud; import static com.google.common.base.Preconditions.checkNotNull; -import static org.jclouds.concurrent.ConcurrentUtils.sameThreadExecutor; import static org.jclouds.rest.RestContextFactory.contextSpec; import static org.jclouds.rest.RestContextFactory.createContextBuilder; import static org.testng.Assert.assertNotNull; @@ -27,6 +26,7 @@ import static org.testng.Assert.assertNotNull; import java.net.URI; import java.util.concurrent.TimeUnit; +import org.jclouds.concurrent.MoreExecutors; import org.jclouds.concurrent.Timeout; import org.jclouds.concurrent.config.ExecutorServiceModule; import org.jclouds.logging.log4j.config.Log4JLoggingModule; @@ -73,21 +73,19 @@ public class VCloudLoginLiveTest { @BeforeClass void setupFactory() { - String endpoint = checkNotNull(System.getProperty("jclouds.test.endpoint"), - "jclouds.test.endpoint") + String endpoint = checkNotNull(System.getProperty("jclouds.test.endpoint"), "jclouds.test.endpoint") + "/v0.8/login"; String identity = checkNotNull(System.getProperty("jclouds.test.identity"), "jclouds.test.identity"); String credential = checkNotNull(System.getProperty("jclouds.test.credential"), "jclouds.test.credential"); - ContextSpec contextSpec = contextSpec("test", - endpoint, "1", identity, credential, VCloudLoginClient.class, - VCloudLoginAsyncClient.class); + ContextSpec contextSpec = contextSpec("test", endpoint, "1", identity, + credential, VCloudLoginClient.class, VCloudLoginAsyncClient.class); context = createContextBuilder( contextSpec, - ImmutableSet. of(new Log4JLoggingModule(), new ExecutorServiceModule( - sameThreadExecutor(), sameThreadExecutor()), new AbstractModule() { + ImmutableSet. of(new Log4JLoggingModule(), new ExecutorServiceModule(MoreExecutors + .sameThreadExecutor(), MoreExecutors.sameThreadExecutor()), new AbstractModule() { @Override protected void configure() { diff --git a/vcloud/core/src/test/java/org/jclouds/vcloud/VCloudVersionsLiveTest.java b/vcloud/core/src/test/java/org/jclouds/vcloud/VCloudVersionsLiveTest.java index 260f7bfe3c..447ac25062 100644 --- a/vcloud/core/src/test/java/org/jclouds/vcloud/VCloudVersionsLiveTest.java +++ b/vcloud/core/src/test/java/org/jclouds/vcloud/VCloudVersionsLiveTest.java @@ -19,7 +19,6 @@ package org.jclouds.vcloud; import static com.google.common.base.Preconditions.checkNotNull; -import static org.jclouds.concurrent.ConcurrentUtils.sameThreadExecutor; import static org.jclouds.rest.RestContextFactory.contextSpec; import static org.jclouds.rest.RestContextFactory.createContextBuilder; import static org.testng.Assert.assertNotNull; @@ -28,6 +27,7 @@ import java.net.URI; import java.util.SortedMap; import java.util.concurrent.TimeUnit; +import org.jclouds.concurrent.MoreExecutors; import org.jclouds.concurrent.Timeout; import org.jclouds.concurrent.config.ExecutorServiceModule; import org.jclouds.logging.log4j.config.Log4JLoggingModule; @@ -59,8 +59,7 @@ public class VCloudVersionsLiveTest { public void testGetSupportedVersions() throws Exception { VCloudVersionsAsyncClient authentication = context.getAsyncApi(); for (int i = 0; i < 5; i++) { - SortedMap response = authentication.getSupportedVersions().get(45, - TimeUnit.SECONDS); + SortedMap response = authentication.getSupportedVersions().get(45, TimeUnit.SECONDS); assertNotNull(response); assertNotNull(response.containsKey("0.8")); } @@ -68,18 +67,16 @@ public class VCloudVersionsLiveTest { @BeforeClass void setupFactory() { - String endpoint = checkNotNull(System.getProperty("jclouds.test.endpoint"), - "jclouds.test.endpoint"); + String endpoint = checkNotNull(System.getProperty("jclouds.test.endpoint"), "jclouds.test.endpoint"); String identity = checkNotNull(System.getProperty("jclouds.test.identity"), "jclouds.test.identity"); String credential = checkNotNull(System.getProperty("jclouds.test.credential"), "jclouds.test.credential"); - ContextSpec contextSpec = contextSpec( - "test", endpoint, "1", identity, credential, VCloudVersionsClient.class, - VCloudVersionsAsyncClient.class); + ContextSpec contextSpec = contextSpec("test", endpoint, "1", + identity, credential, VCloudVersionsClient.class, VCloudVersionsAsyncClient.class); context = createContextBuilder( contextSpec, - ImmutableSet. of(new Log4JLoggingModule(), new ExecutorServiceModule( - sameThreadExecutor(), sameThreadExecutor()))).buildContext(); + ImmutableSet. of(new Log4JLoggingModule(), new ExecutorServiceModule(MoreExecutors + .sameThreadExecutor(), MoreExecutors.sameThreadExecutor()))).buildContext(); } }