Issue 131: extract out bouncycastle

git-svn-id: http://jclouds.googlecode.com/svn/trunk@2408 3d8758e0-26b5-11de-8745-db77d3ebf521
This commit is contained in:
adrian.f.cole 2009-12-13 05:16:26 +00:00
parent 507794042e
commit 1eb4619faa
67 changed files with 2690 additions and 526 deletions

View File

@ -35,6 +35,7 @@ import org.jclouds.http.RequiresHttp;
import org.jclouds.http.filters.BasicAuthentication; import org.jclouds.http.filters.BasicAuthentication;
import org.jclouds.rest.ConfiguresRestClient; import org.jclouds.rest.ConfiguresRestClient;
import org.jclouds.rest.RestClientFactory; import org.jclouds.rest.RestClientFactory;
import org.jclouds.util.EncryptionService;
import ${package}.${clientName}; import ${package}.${clientName};
import ${package}.${clientName}Client; import ${package}.${clientName}Client;
@ -63,9 +64,10 @@ public class ${clientName}RestClientModule extends AbstractModule {
@Singleton @Singleton
public BasicAuthentication provideBasicAuthentication( public BasicAuthentication provideBasicAuthentication(
@Named(${clientName}Constants.PROPERTY_${ucaseClientName}_USER) String user, @Named(${clientName}Constants.PROPERTY_${ucaseClientName}_USER) String user,
@Named(${clientName}Constants.PROPERTY_${ucaseClientName}_PASSWORD) String password) @Named(${clientName}Constants.PROPERTY_${ucaseClientName}_PASSWORD) String password,
EncryptionService encryptionService)
throws UnsupportedEncodingException { throws UnsupportedEncodingException {
return new BasicAuthentication(user, password); return new BasicAuthentication(user, password, encryptionService);
} }
@Provides @Provides

View File

@ -102,9 +102,9 @@ public class ${clientName}AsyncClientTest extends RestClientTest<${clientName}As
@SuppressWarnings("unused") @SuppressWarnings("unused")
@Provides @Provides
@Singleton @Singleton
public BasicAuthentication provideBasicAuthentication() public BasicAuthentication provideBasicAuthentication(EncryptionService encryptionService)
throws UnsupportedEncodingException { throws UnsupportedEncodingException {
return new BasicAuthentication("foo", "bar"); return new BasicAuthentication("foo", "bar", encryptionService);
} }
}; };

View File

@ -30,15 +30,18 @@ import javax.ws.rs.core.HttpHeaders;
import org.jclouds.atmosonline.saas.domain.AtmosObject; import org.jclouds.atmosonline.saas.domain.AtmosObject;
import org.jclouds.http.HttpRequest; import org.jclouds.http.HttpRequest;
import org.jclouds.http.HttpUtils;
import org.jclouds.rest.Binder; import org.jclouds.rest.Binder;
import org.jclouds.util.EncryptionService;
public class BindAtmosObjectToEntityAndMetadataToHeaders implements Binder { public class BindAtmosObjectToEntityAndMetadataToHeaders implements Binder {
private final BindUserMetadataToHeaders metaBinder; private final BindUserMetadataToHeaders metaBinder;
private final EncryptionService encryptionService;
@Inject @Inject
protected BindAtmosObjectToEntityAndMetadataToHeaders(BindUserMetadataToHeaders metaBinder) { protected BindAtmosObjectToEntityAndMetadataToHeaders(BindUserMetadataToHeaders metaBinder,
EncryptionService encryptionService) {
this.metaBinder = metaBinder; this.metaBinder = metaBinder;
this.encryptionService = encryptionService;
} }
public void bindToRequest(HttpRequest request, Object entity) { public void bindToRequest(HttpRequest request, Object entity) {
@ -55,7 +58,7 @@ public class BindAtmosObjectToEntityAndMetadataToHeaders implements Binder {
if (object.getContentMetadata().getContentMD5() != null) { if (object.getContentMetadata().getContentMD5() != null) {
request.getHeaders().put("Content-MD5", request.getHeaders().put("Content-MD5",
HttpUtils.toBase64String(object.getContentMetadata().getContentMD5())); encryptionService.toBase64String(object.getContentMetadata().getContentMD5()));
} }
metaBinder.bindToRequest(request, object.getUserMetadata()); metaBinder.bindToRequest(request, object.getUserMetadata());
} }

View File

@ -52,15 +52,16 @@ import org.jclouds.blobstore.domain.Blob.Factory;
import org.jclouds.blobstore.functions.BlobToHttpGetOptions; import org.jclouds.blobstore.functions.BlobToHttpGetOptions;
import org.jclouds.blobstore.strategy.ClearListStrategy; import org.jclouds.blobstore.strategy.ClearListStrategy;
import org.jclouds.concurrent.FutureFunctionCallable; import org.jclouds.concurrent.FutureFunctionCallable;
import org.jclouds.http.HttpUtils;
import org.jclouds.http.options.GetOptions; import org.jclouds.http.options.GetOptions;
import org.jclouds.logging.Logger.LoggerFactory; import org.jclouds.logging.Logger.LoggerFactory;
import org.jclouds.util.EncryptionService;
import org.jclouds.util.Utils; import org.jclouds.util.Utils;
import com.google.common.base.Function; import com.google.common.base.Function;
import com.google.common.base.Supplier; import com.google.common.base.Supplier;
public class AtmosAsyncBlobStore extends BaseAtmosBlobStore implements AsyncBlobStore { public class AtmosAsyncBlobStore extends BaseAtmosBlobStore implements AsyncBlobStore {
private final EncryptionService encryptionService;
@Inject @Inject
public AtmosAsyncBlobStore(AtmosStorageAsyncClient async, AtmosStorageClient sync, public AtmosAsyncBlobStore(AtmosStorageAsyncClient async, AtmosStorageClient sync,
@ -69,10 +70,12 @@ public class AtmosAsyncBlobStore extends BaseAtmosBlobStore implements AsyncBlob
ObjectToBlob object2Blob, BlobToObject blob2Object, ObjectToBlob object2Blob, BlobToObject blob2Object,
BlobStoreListOptionsToListOptions container2ContainerListOptions, BlobStoreListOptionsToListOptions container2ContainerListOptions,
BlobToHttpGetOptions blob2ObjectGetOptions, BlobToHttpGetOptions blob2ObjectGetOptions,
DirectoryEntryListToResourceMetadataList container2ResourceList, ExecutorService service) { DirectoryEntryListToResourceMetadataList container2ResourceList,
ExecutorService service, EncryptionService encryptionService) {
super(async, sync, blobFactory, logFactory, clearContainerStrategy, object2BlobMd, super(async, sync, blobFactory, logFactory, clearContainerStrategy, object2BlobMd,
object2Blob, blob2Object, container2ContainerListOptions, blob2ObjectGetOptions, object2Blob, blob2Object, container2ContainerListOptions, blob2ObjectGetOptions,
container2ResourceList, service); container2ResourceList, service);
this.encryptionService = encryptionService;
} }
/** /**
@ -194,7 +197,7 @@ public class AtmosAsyncBlobStore extends BaseAtmosBlobStore implements AsyncBlob
} }
if (blob.getMetadata().getContentMD5() != null) if (blob.getMetadata().getContentMD5() != null)
blob.getMetadata().getUserMetadata().put("content-md5", blob.getMetadata().getUserMetadata().put("content-md5",
HttpUtils.toHexString(blob.getMetadata().getContentMD5())); encryptionService.toHexString(blob.getMetadata().getContentMD5()));
sync.createFile(container, blob2Object.apply(blob)); sync.createFile(container, blob2Object.apply(blob));
return path; return path;
} catch (InterruptedException e) { } catch (InterruptedException e) {

View File

@ -47,14 +47,15 @@ import org.jclouds.blobstore.domain.ResourceMetadata;
import org.jclouds.blobstore.domain.Blob.Factory; import org.jclouds.blobstore.domain.Blob.Factory;
import org.jclouds.blobstore.functions.BlobToHttpGetOptions; import org.jclouds.blobstore.functions.BlobToHttpGetOptions;
import org.jclouds.blobstore.strategy.ClearListStrategy; import org.jclouds.blobstore.strategy.ClearListStrategy;
import org.jclouds.http.HttpUtils;
import org.jclouds.http.options.GetOptions; import org.jclouds.http.options.GetOptions;
import org.jclouds.logging.Logger.LoggerFactory; import org.jclouds.logging.Logger.LoggerFactory;
import org.jclouds.util.EncryptionService;
import org.jclouds.util.Utils; import org.jclouds.util.Utils;
import com.google.common.base.Supplier; import com.google.common.base.Supplier;
public class AtmosBlobStore extends BaseAtmosBlobStore implements BlobStore { public class AtmosBlobStore extends BaseAtmosBlobStore implements BlobStore {
private final EncryptionService encryptionService;
@Inject @Inject
public AtmosBlobStore(AtmosStorageAsyncClient async, AtmosStorageClient sync, public AtmosBlobStore(AtmosStorageAsyncClient async, AtmosStorageClient sync,
@ -63,10 +64,11 @@ public class AtmosBlobStore extends BaseAtmosBlobStore implements BlobStore {
ObjectToBlob object2Blob, BlobToObject blob2Object, ObjectToBlob object2Blob, BlobToObject blob2Object,
BlobStoreListOptionsToListOptions container2ContainerListOptions, BlobStoreListOptionsToListOptions container2ContainerListOptions,
BlobToHttpGetOptions blob2ObjectGetOptions, BlobToHttpGetOptions blob2ObjectGetOptions,
DirectoryEntryListToResourceMetadataList container2ResourceList, ExecutorService service) { DirectoryEntryListToResourceMetadataList container2ResourceList, ExecutorService service,EncryptionService encryptionService) {
super(async, sync, blobFactory, logFactory, clearContainerStrategy, object2BlobMd, super(async, sync, blobFactory, logFactory, clearContainerStrategy, object2BlobMd,
object2Blob, blob2Object, container2ContainerListOptions, blob2ObjectGetOptions, object2Blob, blob2Object, container2ContainerListOptions, blob2ObjectGetOptions,
container2ResourceList, service); container2ResourceList, service);
this.encryptionService = encryptionService;
} }
/** /**
@ -149,7 +151,7 @@ public class AtmosBlobStore extends BaseAtmosBlobStore implements BlobStore {
deleteAndEnsurePathGone(path); deleteAndEnsurePathGone(path);
if (blob.getMetadata().getContentMD5() != null) if (blob.getMetadata().getContentMD5() != null)
blob.getMetadata().getUserMetadata().put("content-md5", blob.getMetadata().getUserMetadata().put("content-md5",
HttpUtils.toHexString(blob.getMetadata().getContentMD5())); encryptionService.toHexString(blob.getMetadata().getContentMD5()));
sync.createFile(container, blob2Object.apply(blob)); sync.createFile(container, blob2Object.apply(blob));
return path; return path;
} }

View File

@ -35,7 +35,7 @@ import org.jclouds.atmosonline.saas.functions.AtmosObjectName;
import org.jclouds.blobstore.domain.MutableBlobMetadata; import org.jclouds.blobstore.domain.MutableBlobMetadata;
import org.jclouds.blobstore.domain.ResourceType; import org.jclouds.blobstore.domain.ResourceType;
import org.jclouds.blobstore.domain.internal.MutableBlobMetadataImpl; import org.jclouds.blobstore.domain.internal.MutableBlobMetadataImpl;
import org.jclouds.http.HttpUtils; import org.jclouds.util.EncryptionService;
import com.google.common.base.Function; import com.google.common.base.Function;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
@ -50,10 +50,12 @@ public class ObjectToBlobMetadata implements Function<AtmosObject, MutableBlobMe
private static final Set<String> systemMetadata = ImmutableSet.of("atime", "mtime", "ctime", private static final Set<String> systemMetadata = ImmutableSet.of("atime", "mtime", "ctime",
"itime", "type", "uid", "gid", "objectid", "objname", "size", "nlink", "policyname", "itime", "type", "uid", "gid", "objectid", "objname", "size", "nlink", "policyname",
"content-md5"); "content-md5");
private final EncryptionService encryptionService;
@Inject @Inject
protected ObjectToBlobMetadata(AtmosObjectName objectName) { protected ObjectToBlobMetadata(AtmosObjectName objectName, EncryptionService encryptionService) {
this.objectName = objectName; this.objectName = objectName;
this.encryptionService = encryptionService;
} }
public MutableBlobMetadata apply(AtmosObject from) { public MutableBlobMetadata apply(AtmosObject from) {
@ -62,7 +64,7 @@ public class ObjectToBlobMetadata implements Function<AtmosObject, MutableBlobMe
to.setLastModified(from.getSystemMetadata().getLastUserDataModification()); to.setLastModified(from.getSystemMetadata().getLastUserDataModification());
String md5hex = from.getUserMetadata().getMetadata().get("content-md5"); String md5hex = from.getUserMetadata().getMetadata().get("content-md5");
if (md5hex != null) if (md5hex != null)
to.setContentMD5(HttpUtils.fromHexString(md5hex)); to.setContentMD5(encryptionService.fromHexString(md5hex));
if (from.getContentMetadata().getContentType() != null) if (from.getContentMetadata().getContentType() != null)
to.setContentType(from.getContentMetadata().getContentType()); to.setContentType(from.getContentMetadata().getContentType());
to.setName(objectName.apply(from)); to.setName(objectName.apply(from));

View File

@ -45,6 +45,7 @@ import org.jclouds.http.HttpRequestFilter;
import org.jclouds.http.HttpUtils; import org.jclouds.http.HttpUtils;
import org.jclouds.http.internal.SignatureWire; import org.jclouds.http.internal.SignatureWire;
import org.jclouds.logging.Logger; import org.jclouds.logging.Logger;
import org.jclouds.util.EncryptionService;
import org.jclouds.util.TimeStamp; import org.jclouds.util.TimeStamp;
import com.google.common.annotations.VisibleForTesting; import com.google.common.annotations.VisibleForTesting;
@ -63,6 +64,8 @@ public class SignRequest implements HttpRequestFilter {
private final String uid; private final String uid;
private final byte[] key; private final byte[] key;
private final Provider<String> timeStampProvider; private final Provider<String> timeStampProvider;
private final EncryptionService encryptionService;
@Resource @Resource
@Named(HttpConstants.SIGNATURE_LOGGER) @Named(HttpConstants.SIGNATURE_LOGGER)
Logger signatureLog = Logger.NULL; Logger signatureLog = Logger.NULL;
@ -71,11 +74,12 @@ public class SignRequest implements HttpRequestFilter {
public SignRequest(SignatureWire signatureWire, public SignRequest(SignatureWire signatureWire,
@Named(AtmosStorageConstants.PROPERTY_EMCSAAS_UID) String uid, @Named(AtmosStorageConstants.PROPERTY_EMCSAAS_UID) String uid,
@Named(AtmosStorageConstants.PROPERTY_EMCSAAS_KEY) String encodedKey, @Named(AtmosStorageConstants.PROPERTY_EMCSAAS_KEY) String encodedKey,
@TimeStamp Provider<String> timeStampProvider) { @TimeStamp Provider<String> timeStampProvider, EncryptionService encryptionService) {
this.signatureWire = signatureWire; this.signatureWire = signatureWire;
this.uid = uid; this.uid = uid;
this.key = HttpUtils.fromBase64String(encodedKey); this.key = encryptionService.fromBase64String(encodedKey);
this.timeStampProvider = timeStampProvider; this.timeStampProvider = timeStampProvider;
this.encryptionService = encryptionService;
} }
public void filter(HttpRequest request) throws HttpException { public void filter(HttpRequest request) throws HttpException {
@ -110,7 +114,7 @@ public class SignRequest implements HttpRequestFilter {
public String signString(String toSign) { public String signString(String toSign) {
String signature; String signature;
try { try {
signature = HttpUtils.hmacSha1Base64(toSign, key); signature = encryptionService.hmacSha1Base64(toSign, key);
} catch (Exception e) { } catch (Exception e) {
throw new HttpException("error signing request", e); throw new HttpException("error signing request", e);
} }
@ -139,12 +143,14 @@ public class SignRequest implements HttpRequestFilter {
if (header.startsWith("x-emc-")) { if (header.startsWith("x-emc-")) {
// Convert all header names to lowercase. // Convert all header names to lowercase.
toSign.append(header.toLowerCase()).append(":"); toSign.append(header.toLowerCase()).append(":");
// For headers with values that span multiple lines, convert them into one line by replacing any // For headers with values that span multiple lines, convert them into one line by
// replacing any
// newline characters and extra embedded white spaces in the value. // newline characters and extra embedded white spaces in the value.
for (String value : request.getHeaders().get(header)) for (String value : request.getHeaders().get(header))
toSign.append(value.replaceAll("\r?\n", "").replaceAll(" ", " ")).append(" "); toSign.append(value.replaceAll("\r?\n", "").replaceAll(" ", " ")).append(" ");
toSign.deleteCharAt(toSign.lastIndexOf(" ")); toSign.deleteCharAt(toSign.lastIndexOf(" "));
// Concatenate all headers together, using newlines (\n) separating each header from the next one. // Concatenate all headers together, using newlines (\n) separating each header from the
// next one.
toSign.append("\n"); toSign.append("\n");
} }
} }

View File

@ -46,7 +46,6 @@ import org.jclouds.blobstore.binders.BindBlobToMultipartFormTest;
import org.jclouds.blobstore.config.BlobStoreObjectModule; import org.jclouds.blobstore.config.BlobStoreObjectModule;
import org.jclouds.blobstore.functions.ReturnVoidOnNotFoundOr404; import org.jclouds.blobstore.functions.ReturnVoidOnNotFoundOr404;
import org.jclouds.blobstore.functions.ThrowKeyNotFoundOn404; import org.jclouds.blobstore.functions.ThrowKeyNotFoundOn404;
import org.jclouds.http.HttpUtils;
import org.jclouds.http.functions.ParseURIFromListOrLocationHeaderIf20x; import org.jclouds.http.functions.ParseURIFromListOrLocationHeaderIf20x;
import org.jclouds.http.functions.ReturnVoidIf2xx; import org.jclouds.http.functions.ReturnVoidIf2xx;
import org.jclouds.http.options.GetOptions; import org.jclouds.http.options.GetOptions;
@ -57,6 +56,7 @@ import org.jclouds.rest.internal.GeneratedHttpRequest;
import org.jclouds.rest.internal.RestAnnotationProcessor; import org.jclouds.rest.internal.RestAnnotationProcessor;
import org.jclouds.util.Jsr330; import org.jclouds.util.Jsr330;
import org.jclouds.util.TimeStamp; import org.jclouds.util.TimeStamp;
import org.jclouds.util.internal.Base64;
import org.testng.annotations.BeforeClass; import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test; import org.testng.annotations.Test;
@ -303,7 +303,7 @@ public class AtmosStorageClientTest extends RestClientTest<AtmosStorageAsyncClie
bindConstant().annotatedWith(Jsr330.named(AtmosStorageConstants.PROPERTY_EMCSAAS_UID)) bindConstant().annotatedWith(Jsr330.named(AtmosStorageConstants.PROPERTY_EMCSAAS_UID))
.to("uid"); .to("uid");
bindConstant().annotatedWith(Jsr330.named(AtmosStorageConstants.PROPERTY_EMCSAAS_KEY)) bindConstant().annotatedWith(Jsr330.named(AtmosStorageConstants.PROPERTY_EMCSAAS_KEY))
.to(HttpUtils.toBase64String("key".getBytes())); .to(Base64.encodeBytes("key".getBytes()));
bind(Logger.LoggerFactory.class).toInstance(new LoggerFactory() { bind(Logger.LoggerFactory.class).toInstance(new LoggerFactory() {
public Logger getLogger(String category) { public Logger getLogger(String category) {
return Logger.NULL; return Logger.NULL;

View File

@ -57,6 +57,7 @@ import org.jclouds.http.internal.SignatureWire;
import org.jclouds.logging.Logger; import org.jclouds.logging.Logger;
import org.jclouds.rest.internal.GeneratedHttpRequest; import org.jclouds.rest.internal.GeneratedHttpRequest;
import org.jclouds.rest.internal.RestAnnotationProcessor; import org.jclouds.rest.internal.RestAnnotationProcessor;
import org.jclouds.util.EncryptionService;
import org.jclouds.util.TimeStamp; import org.jclouds.util.TimeStamp;
import com.google.common.annotations.VisibleForTesting; import com.google.common.annotations.VisibleForTesting;
@ -80,19 +81,21 @@ public class FormSigner implements HttpRequestFilter, RequestSigner {
private final String accessKey; private final String accessKey;
private final String secretKey; private final String secretKey;
private final Provider<String> dateService; private final Provider<String> dateService;
private final EncryptionService encryptionService;
@Resource @Resource
@Named(HttpConstants.SIGNATURE_LOGGER) @Named(HttpConstants.SIGNATURE_LOGGER)
private final Logger signatureLog = Logger.NULL; private Logger signatureLog = Logger.NULL;
@Inject @Inject
public FormSigner(SignatureWire signatureWire, public FormSigner(SignatureWire signatureWire,
@Named(AWSConstants.PROPERTY_AWS_ACCESSKEYID) String accessKey, @Named(AWSConstants.PROPERTY_AWS_ACCESSKEYID) String accessKey,
@Named(AWSConstants.PROPERTY_AWS_SECRETACCESSKEY) String secretKey, @Named(AWSConstants.PROPERTY_AWS_SECRETACCESSKEY) String secretKey,
@TimeStamp Provider<String> dateService) { @TimeStamp Provider<String> dateService, EncryptionService encryptionService) {
this.signatureWire = signatureWire; this.signatureWire = signatureWire;
this.accessKey = accessKey; this.accessKey = accessKey;
this.secretKey = secretKey; this.secretKey = secretKey;
this.dateService = dateService; this.dateService = dateService;
this.encryptionService = encryptionService;
} }
public void filter(HttpRequest in) throws HttpException { public void filter(HttpRequest in) throws HttpException {
@ -157,7 +160,7 @@ public class FormSigner implements HttpRequestFilter, RequestSigner {
public String signString(String stringToSign) { public String signString(String stringToSign) {
String signature; String signature;
try { try {
signature = HttpUtils.hmacSha256Base64(stringToSign, secretKey.getBytes()); signature = encryptionService.hmacSha256Base64(stringToSign, secretKey.getBytes());
if (signatureWire.enabled()) if (signatureWire.enabled())
signatureWire.input(IOUtils.toInputStream(signature)); signatureWire.input(IOUtils.toInputStream(signature));
} catch (Exception e) { } catch (Exception e) {

View File

@ -47,6 +47,7 @@ import org.jclouds.http.HttpRequestFilter;
import org.jclouds.http.HttpUtils; import org.jclouds.http.HttpUtils;
import org.jclouds.http.internal.SignatureWire; import org.jclouds.http.internal.SignatureWire;
import org.jclouds.logging.Logger; import org.jclouds.logging.Logger;
import org.jclouds.util.EncryptionService;
import org.jclouds.util.TimeStamp; import org.jclouds.util.TimeStamp;
import com.google.common.annotations.VisibleForTesting; import com.google.common.annotations.VisibleForTesting;
@ -67,6 +68,8 @@ public class RequestAuthorizeSignature implements HttpRequestFilter, RequestSign
private final String accessKey; private final String accessKey;
private final String secretKey; private final String secretKey;
private final Provider<String> timeStampProvider; private final Provider<String> timeStampProvider;
private final EncryptionService encryptionService;
@Resource @Resource
@Named(HttpConstants.SIGNATURE_LOGGER) @Named(HttpConstants.SIGNATURE_LOGGER)
Logger signatureLog = Logger.NULL; Logger signatureLog = Logger.NULL;
@ -75,11 +78,12 @@ public class RequestAuthorizeSignature implements HttpRequestFilter, RequestSign
public RequestAuthorizeSignature(SignatureWire signatureWire, public RequestAuthorizeSignature(SignatureWire signatureWire,
@Named(S3Constants.PROPERTY_AWS_ACCESSKEYID) String accessKey, @Named(S3Constants.PROPERTY_AWS_ACCESSKEYID) String accessKey,
@Named(S3Constants.PROPERTY_AWS_SECRETACCESSKEY) String secretKey, @Named(S3Constants.PROPERTY_AWS_SECRETACCESSKEY) String secretKey,
@TimeStamp Provider<String> timeStampProvider) { @TimeStamp Provider<String> timeStampProvider, EncryptionService encryptionService) {
this.signatureWire = signatureWire; this.signatureWire = signatureWire;
this.accessKey = accessKey; this.accessKey = accessKey;
this.secretKey = secretKey; this.secretKey = secretKey;
this.timeStampProvider = timeStampProvider; this.timeStampProvider = timeStampProvider;
this.encryptionService = encryptionService;
} }
public void filter(HttpRequest request) throws HttpException { public void filter(HttpRequest request) throws HttpException {
@ -115,7 +119,7 @@ public class RequestAuthorizeSignature implements HttpRequestFilter, RequestSign
public String signString(String toSign) { public String signString(String toSign) {
String signature; String signature;
try { try {
signature = HttpUtils.hmacSha1Base64(toSign, secretKey.getBytes()); signature = encryptionService.hmacSha1Base64(toSign, secretKey.getBytes());
} catch (Exception e) { } catch (Exception e) {
throw new HttpException("error signing request", e); throw new HttpException("error signing request", e);
} }

View File

@ -32,9 +32,9 @@ import org.jclouds.aws.s3.reference.S3Headers;
import org.jclouds.blobstore.domain.BlobMetadata; import org.jclouds.blobstore.domain.BlobMetadata;
import org.jclouds.blobstore.functions.ParseSystemAndUserMetadataFromHeaders; import org.jclouds.blobstore.functions.ParseSystemAndUserMetadataFromHeaders;
import org.jclouds.http.HttpResponse; import org.jclouds.http.HttpResponse;
import org.jclouds.http.HttpUtils;
import org.jclouds.rest.InvocationContext; import org.jclouds.rest.InvocationContext;
import org.jclouds.rest.internal.GeneratedHttpRequest; import org.jclouds.rest.internal.GeneratedHttpRequest;
import org.jclouds.util.EncryptionService;
import com.google.common.annotations.VisibleForTesting; import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Function; import com.google.common.base.Function;
@ -50,12 +50,14 @@ public class ParseObjectMetadataFromHeaders implements
Function<HttpResponse, MutableObjectMetadata>, InvocationContext { Function<HttpResponse, MutableObjectMetadata>, InvocationContext {
private final ParseSystemAndUserMetadataFromHeaders blobMetadataParser; private final ParseSystemAndUserMetadataFromHeaders blobMetadataParser;
private final BlobToObjectMetadata blobToObjectMetadata; private final BlobToObjectMetadata blobToObjectMetadata;
private final EncryptionService encryptionService;
@Inject @Inject
public ParseObjectMetadataFromHeaders(ParseSystemAndUserMetadataFromHeaders blobMetadataParser, public ParseObjectMetadataFromHeaders(ParseSystemAndUserMetadataFromHeaders blobMetadataParser,
BlobToObjectMetadata blobToObjectMetadata) { BlobToObjectMetadata blobToObjectMetadata, EncryptionService encryptionService) {
this.blobMetadataParser = blobMetadataParser; this.blobMetadataParser = blobMetadataParser;
this.blobToObjectMetadata = blobToObjectMetadata; this.blobToObjectMetadata = blobToObjectMetadata;
this.encryptionService = encryptionService;
} }
/** /**
@ -66,7 +68,7 @@ public class ParseObjectMetadataFromHeaders implements
BlobMetadata base = blobMetadataParser.apply(from); BlobMetadata base = blobMetadataParser.apply(from);
MutableObjectMetadata to = blobToObjectMetadata.apply(base); MutableObjectMetadata to = blobToObjectMetadata.apply(base);
addETagTo(from, to); addETagTo(from, to);
to.setContentMD5(HttpUtils.fromHexString(to.getETag().replaceAll("\"", ""))); to.setContentMD5(encryptionService.fromHexString(to.getETag().replaceAll("\"", "")));
to.setCacheControl(from.getFirstHeaderOrNull(HttpHeaders.CACHE_CONTROL)); to.setCacheControl(from.getFirstHeaderOrNull(HttpHeaders.CACHE_CONTROL));
to.setContentDisposition(from.getFirstHeaderOrNull("Content-Disposition")); to.setContentDisposition(from.getFirstHeaderOrNull("Content-Disposition"));
to.setContentEncoding(from.getFirstHeaderOrNull(HttpHeaders.CONTENT_ENCODING)); to.setContentEncoding(from.getFirstHeaderOrNull(HttpHeaders.CONTENT_ENCODING));

View File

@ -34,9 +34,9 @@ import org.jclouds.aws.s3.domain.ObjectMetadata;
import org.jclouds.aws.s3.domain.ObjectMetadata.StorageClass; import org.jclouds.aws.s3.domain.ObjectMetadata.StorageClass;
import org.jclouds.aws.s3.domain.internal.BucketListObjectMetadata; import org.jclouds.aws.s3.domain.internal.BucketListObjectMetadata;
import org.jclouds.aws.s3.domain.internal.TreeSetListBucketResponse; import org.jclouds.aws.s3.domain.internal.TreeSetListBucketResponse;
import org.jclouds.http.HttpUtils;
import org.jclouds.http.functions.ParseSax; import org.jclouds.http.functions.ParseSax;
import org.jclouds.util.DateService; import org.jclouds.util.DateService;
import org.jclouds.util.EncryptionService;
import org.xml.sax.Attributes; import org.xml.sax.Attributes;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
@ -58,6 +58,8 @@ public class ListBucketHandler extends ParseSax.HandlerWithResult<ListBucketResp
private StringBuilder currentText = new StringBuilder(); private StringBuilder currentText = new StringBuilder();
private final DateService dateParser; private final DateService dateParser;
private final EncryptionService encryptionService;
private String bucketName; private String bucketName;
private String prefix; private String prefix;
private String marker; private String marker;
@ -66,8 +68,9 @@ public class ListBucketHandler extends ParseSax.HandlerWithResult<ListBucketResp
private boolean isTruncated; private boolean isTruncated;
@Inject @Inject
public ListBucketHandler(DateService dateParser) { public ListBucketHandler(DateService dateParser, EncryptionService encryptionService) {
this.dateParser = dateParser; this.dateParser = dateParser;
this.encryptionService = encryptionService;
this.contents = Sets.newTreeSet(); this.contents = Sets.newTreeSet();
this.commonPrefixes = Sets.newTreeSet(); this.commonPrefixes = Sets.newTreeSet();
} }
@ -102,7 +105,7 @@ public class ListBucketHandler extends ParseSax.HandlerWithResult<ListBucketResp
currentLastModified = dateParser.iso8601DateParse(currentText.toString().trim()); currentLastModified = dateParser.iso8601DateParse(currentText.toString().trim());
} else if (qName.equals("ETag")) { } else if (qName.equals("ETag")) {
currentETag = currentText.toString().trim(); currentETag = currentText.toString().trim();
currentMD5 = HttpUtils.fromHexString(currentETag.replaceAll("\"", "")); currentMD5 = encryptionService.fromHexString(currentETag.replaceAll("\"", ""));
} else if (qName.equals("Size")) { } else if (qName.equals("Size")) {
currentSize = new Long(currentText.toString().trim()); currentSize = new Long(currentText.toString().trim());
} else if (qName.equals("Owner")) { } else if (qName.equals("Owner")) {

View File

@ -42,7 +42,8 @@ import org.jclouds.blobstore.domain.MutableBlobMetadata;
import org.jclouds.blobstore.domain.internal.MutableBlobMetadataImpl; import org.jclouds.blobstore.domain.internal.MutableBlobMetadataImpl;
import org.jclouds.blobstore.functions.ParseSystemAndUserMetadataFromHeaders; import org.jclouds.blobstore.functions.ParseSystemAndUserMetadataFromHeaders;
import org.jclouds.http.HttpResponse; import org.jclouds.http.HttpResponse;
import org.jclouds.http.HttpUtils; import org.jclouds.util.EncryptionService;
import org.jclouds.util.internal.JCEEncryptionService;
import org.testng.annotations.BeforeTest; import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test; import org.testng.annotations.Test;
@ -53,6 +54,7 @@ import com.google.common.collect.ImmutableMap;
*/ */
@Test(testName = "s3.ParseObjectMetadataFromHeadersTest") @Test(testName = "s3.ParseObjectMetadataFromHeadersTest")
public class ParseObjectMetadataFromHeadersTest { public class ParseObjectMetadataFromHeadersTest {
private static final EncryptionService encryptionService = new JCEEncryptionService();
@Test @Test
void testNormal() throws Exception { void testNormal() throws Exception {
@ -62,7 +64,7 @@ public class ParseObjectMetadataFromHeadersTest {
http.getHeaders().put("Content-Disposition", "contentDisposition"); http.getHeaders().put("Content-Disposition", "contentDisposition");
http.getHeaders().put(HttpHeaders.CONTENT_ENCODING, "encoding"); http.getHeaders().put(HttpHeaders.CONTENT_ENCODING, "encoding");
ParseObjectMetadataFromHeaders parser = new ParseObjectMetadataFromHeaders(blobParser(http, ParseObjectMetadataFromHeaders parser = new ParseObjectMetadataFromHeaders(blobParser(http,
"\"abc\""), blobToObjectMetadata); "\"abc\""), blobToObjectMetadata, encryptionService);
MutableObjectMetadata response = parser.apply(http); MutableObjectMetadata response = parser.apply(http);
assertEquals(response, expects); assertEquals(response, expects);
} }
@ -76,7 +78,7 @@ public class ParseObjectMetadataFromHeadersTest {
http.getHeaders().put(HttpHeaders.CONTENT_ENCODING, "encoding"); http.getHeaders().put(HttpHeaders.CONTENT_ENCODING, "encoding");
http.getHeaders().put(S3Headers.AMZ_MD5, "\"abc\""); http.getHeaders().put(S3Headers.AMZ_MD5, "\"abc\"");
ParseObjectMetadataFromHeaders parser = new ParseObjectMetadataFromHeaders(blobParser(http, ParseObjectMetadataFromHeaders parser = new ParseObjectMetadataFromHeaders(blobParser(http,
null), blobToObjectMetadata); null), blobToObjectMetadata, encryptionService);
MutableObjectMetadata response = parser.apply(http); MutableObjectMetadata response = parser.apply(http);
assertEquals(response, expects); assertEquals(response, expects);
} }
@ -107,7 +109,7 @@ public class ParseObjectMetadataFromHeadersTest {
expects.setCacheControl("cacheControl"); expects.setCacheControl("cacheControl");
expects.setContentDisposition("contentDisposition"); expects.setContentDisposition("contentDisposition");
expects.setContentEncoding("encoding"); expects.setContentEncoding("encoding");
expects.setContentMD5(HttpUtils.fromHexString("abc")); expects.setContentMD5(encryptionService.fromHexString("abc"));
expects.setContentType("type"); expects.setContentType("type");
expects.setETag("\"abc\""); expects.setETag("\"abc\"");
expects.setKey("key"); expects.setKey("key");

View File

@ -36,10 +36,11 @@ import org.jclouds.aws.s3.domain.ObjectMetadata.StorageClass;
import org.jclouds.aws.s3.domain.internal.BucketListObjectMetadata; import org.jclouds.aws.s3.domain.internal.BucketListObjectMetadata;
import org.jclouds.aws.s3.domain.internal.TreeSetListBucketResponse; import org.jclouds.aws.s3.domain.internal.TreeSetListBucketResponse;
import org.jclouds.http.HttpException; import org.jclouds.http.HttpException;
import org.jclouds.http.HttpUtils;
import org.jclouds.http.functions.BaseHandlerTest; import org.jclouds.http.functions.BaseHandlerTest;
import org.jclouds.http.functions.ParseSax; import org.jclouds.http.functions.ParseSax;
import org.jclouds.util.DateService; import org.jclouds.util.DateService;
import org.jclouds.util.EncryptionService;
import org.jclouds.util.internal.JCEEncryptionService;
import org.testng.annotations.BeforeTest; import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test; import org.testng.annotations.Test;
@ -50,6 +51,7 @@ public class ListBucketHandlerTest extends BaseHandlerTest {
public static final String listBucketWithPrefixAppsSlash = "<ListBucketResult xmlns=\"http://s3.amazonaws.com/doc/2006-03-01/\"><Name>adriancole.org.jclouds.aws.s3.amazons3testdelimiter</Name><Prefix>apps/</Prefix><Marker></Marker><MaxKeys>1000</MaxKeys><IsTruncated>false</IsTruncated><Contents><Key>apps/0</Key><LastModified>2009-05-07T18:27:08.000Z</LastModified><ETag>&quot;c82e6a0025c31c5de5947fda62ac51ab&quot;</ETag><Size>8</Size><Owner><ID>e1a5f66a480ca99a4fdfe8e318c3020446c9989d7004e7778029fbcc5d990fa0</ID><DisplayName>ferncam</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>apps/1</Key><LastModified>2009-05-07T18:27:09.000Z</LastModified><ETag>&quot;944fab2c5a9a6bacf07db5e688310d7a&quot;</ETag><Size>8</Size><Owner><ID>e1a5f66a480ca99a4fdfe8e318c3020446c9989d7004e7778029fbcc5d990fa0</ID><DisplayName>ferncam</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>apps/2</Key><LastModified>2009-05-07T18:27:09.000Z</LastModified><ETag>&quot;a227b8888045c8fd159fb495214000f0&quot;</ETag><Size>8</Size><Owner><ID>e1a5f66a480ca99a4fdfe8e318c3020446c9989d7004e7778029fbcc5d990fa0</ID><DisplayName>ferncam</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>apps/3</Key><LastModified>2009-05-07T18:27:09.000Z</LastModified><ETag>&quot;c9caa76c3dec53e2a192608ce73eef03&quot;</ETag><Size>8</Size><Owner><ID>e1a5f66a480ca99a4fdfe8e318c3020446c9989d7004e7778029fbcc5d990fa0</ID><DisplayName>ferncam</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>apps/4</Key><LastModified>2009-05-07T18:27:09.000Z</LastModified><ETag>&quot;1ce5d0dcc6154a647ea90c7bdf82a224&quot;</ETag><Size>8</Size><Owner><ID>e1a5f66a480ca99a4fdfe8e318c3020446c9989d7004e7778029fbcc5d990fa0</ID><DisplayName>ferncam</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>apps/5</Key><LastModified>2009-05-07T18:27:09.000Z</LastModified><ETag>&quot;79433524d87462ee05708a8ef894ed55&quot;</ETag><Size>8</Size><Owner><ID>e1a5f66a480ca99a4fdfe8e318c3020446c9989d7004e7778029fbcc5d990fa0</ID><DisplayName>ferncam</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>apps/6</Key><LastModified>2009-05-07T18:27:10.000Z</LastModified><ETag>&quot;dd00a060b28ddca8bc5a21a49e306f67&quot;</ETag><Size>8</Size><Owner><ID>e1a5f66a480ca99a4fdfe8e318c3020446c9989d7004e7778029fbcc5d990fa0</ID><DisplayName>ferncam</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>apps/7</Key><LastModified>2009-05-07T18:27:10.000Z</LastModified><ETag>&quot;8cd06eca6e819a927b07a285d750b100&quot;</ETag><Size>8</Size><Owner><ID>e1a5f66a480ca99a4fdfe8e318c3020446c9989d7004e7778029fbcc5d990fa0</ID><DisplayName>ferncam</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>apps/8</Key><LastModified>2009-05-07T18:27:10.000Z</LastModified><ETag>&quot;174495094d0633b92cbe46603eee6bad&quot;</ETag><Size>8</Size><Owner><ID>e1a5f66a480ca99a4fdfe8e318c3020446c9989d7004e7778029fbcc5d990fa0</ID><DisplayName>ferncam</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>apps/9</Key><LastModified>2009-05-07T18:27:10.000Z</LastModified><ETag>&quot;cd8a19b26fea8a827276df0ad11c580d&quot;</ETag><Size>8</Size><Owner><ID>e1a5f66a480ca99a4fdfe8e318c3020446c9989d7004e7778029fbcc5d990fa0</ID><DisplayName>ferncam</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents></ListBucketResult>"; public static final String listBucketWithPrefixAppsSlash = "<ListBucketResult xmlns=\"http://s3.amazonaws.com/doc/2006-03-01/\"><Name>adriancole.org.jclouds.aws.s3.amazons3testdelimiter</Name><Prefix>apps/</Prefix><Marker></Marker><MaxKeys>1000</MaxKeys><IsTruncated>false</IsTruncated><Contents><Key>apps/0</Key><LastModified>2009-05-07T18:27:08.000Z</LastModified><ETag>&quot;c82e6a0025c31c5de5947fda62ac51ab&quot;</ETag><Size>8</Size><Owner><ID>e1a5f66a480ca99a4fdfe8e318c3020446c9989d7004e7778029fbcc5d990fa0</ID><DisplayName>ferncam</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>apps/1</Key><LastModified>2009-05-07T18:27:09.000Z</LastModified><ETag>&quot;944fab2c5a9a6bacf07db5e688310d7a&quot;</ETag><Size>8</Size><Owner><ID>e1a5f66a480ca99a4fdfe8e318c3020446c9989d7004e7778029fbcc5d990fa0</ID><DisplayName>ferncam</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>apps/2</Key><LastModified>2009-05-07T18:27:09.000Z</LastModified><ETag>&quot;a227b8888045c8fd159fb495214000f0&quot;</ETag><Size>8</Size><Owner><ID>e1a5f66a480ca99a4fdfe8e318c3020446c9989d7004e7778029fbcc5d990fa0</ID><DisplayName>ferncam</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>apps/3</Key><LastModified>2009-05-07T18:27:09.000Z</LastModified><ETag>&quot;c9caa76c3dec53e2a192608ce73eef03&quot;</ETag><Size>8</Size><Owner><ID>e1a5f66a480ca99a4fdfe8e318c3020446c9989d7004e7778029fbcc5d990fa0</ID><DisplayName>ferncam</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>apps/4</Key><LastModified>2009-05-07T18:27:09.000Z</LastModified><ETag>&quot;1ce5d0dcc6154a647ea90c7bdf82a224&quot;</ETag><Size>8</Size><Owner><ID>e1a5f66a480ca99a4fdfe8e318c3020446c9989d7004e7778029fbcc5d990fa0</ID><DisplayName>ferncam</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>apps/5</Key><LastModified>2009-05-07T18:27:09.000Z</LastModified><ETag>&quot;79433524d87462ee05708a8ef894ed55&quot;</ETag><Size>8</Size><Owner><ID>e1a5f66a480ca99a4fdfe8e318c3020446c9989d7004e7778029fbcc5d990fa0</ID><DisplayName>ferncam</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>apps/6</Key><LastModified>2009-05-07T18:27:10.000Z</LastModified><ETag>&quot;dd00a060b28ddca8bc5a21a49e306f67&quot;</ETag><Size>8</Size><Owner><ID>e1a5f66a480ca99a4fdfe8e318c3020446c9989d7004e7778029fbcc5d990fa0</ID><DisplayName>ferncam</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>apps/7</Key><LastModified>2009-05-07T18:27:10.000Z</LastModified><ETag>&quot;8cd06eca6e819a927b07a285d750b100&quot;</ETag><Size>8</Size><Owner><ID>e1a5f66a480ca99a4fdfe8e318c3020446c9989d7004e7778029fbcc5d990fa0</ID><DisplayName>ferncam</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>apps/8</Key><LastModified>2009-05-07T18:27:10.000Z</LastModified><ETag>&quot;174495094d0633b92cbe46603eee6bad&quot;</ETag><Size>8</Size><Owner><ID>e1a5f66a480ca99a4fdfe8e318c3020446c9989d7004e7778029fbcc5d990fa0</ID><DisplayName>ferncam</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>apps/9</Key><LastModified>2009-05-07T18:27:10.000Z</LastModified><ETag>&quot;cd8a19b26fea8a827276df0ad11c580d&quot;</ETag><Size>8</Size><Owner><ID>e1a5f66a480ca99a4fdfe8e318c3020446c9989d7004e7778029fbcc5d990fa0</ID><DisplayName>ferncam</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents></ListBucketResult>";
public static final String listBucketWithSlashDelimiterAndCommonPrefixApps = "<ListBucketResult xmlns=\"http://s3.amazonaws.com/doc/2006-03-01/\"> <Delimiter>/</Delimiter> <CommonPrefixes><Prefix>apps/</Prefix></CommonPrefixes></ListBucketResult>"; public static final String listBucketWithSlashDelimiterAndCommonPrefixApps = "<ListBucketResult xmlns=\"http://s3.amazonaws.com/doc/2006-03-01/\"> <Delimiter>/</Delimiter> <CommonPrefixes><Prefix>apps/</Prefix></CommonPrefixes></ListBucketResult>";
private DateService dateService; private DateService dateService;
private static final EncryptionService encryptionService = new JCEEncryptionService();
@BeforeTest @BeforeTest
@Override @Override
@ -67,52 +69,52 @@ public class ListBucketHandlerTest extends BaseHandlerTest {
"adriancole.org.jclouds.aws.s3.amazons3testdelimiter", ImmutableList.of( "adriancole.org.jclouds.aws.s3.amazons3testdelimiter", ImmutableList.of(
(ObjectMetadata) new BucketListObjectMetadata("apps/0", dateService (ObjectMetadata) new BucketListObjectMetadata("apps/0", dateService
.iso8601DateParse("2009-05-07T18:27:08.000Z"), .iso8601DateParse("2009-05-07T18:27:08.000Z"),
"\"c82e6a0025c31c5de5947fda62ac51ab\"", HttpUtils "\"c82e6a0025c31c5de5947fda62ac51ab\"", encryptionService
.fromHexString("c82e6a0025c31c5de5947fda62ac51ab"), 8, .fromHexString("c82e6a0025c31c5de5947fda62ac51ab"), 8,
owner, StorageClass.STANDARD), owner, StorageClass.STANDARD),
(ObjectMetadata) new BucketListObjectMetadata("apps/1", dateService (ObjectMetadata) new BucketListObjectMetadata("apps/1", dateService
.iso8601DateParse("2009-05-07T18:27:09.000Z"), .iso8601DateParse("2009-05-07T18:27:09.000Z"),
"\"944fab2c5a9a6bacf07db5e688310d7a\"", HttpUtils "\"944fab2c5a9a6bacf07db5e688310d7a\"", encryptionService
.fromHexString("944fab2c5a9a6bacf07db5e688310d7a"), 8, .fromHexString("944fab2c5a9a6bacf07db5e688310d7a"), 8,
owner, StorageClass.STANDARD), owner, StorageClass.STANDARD),
(ObjectMetadata) new BucketListObjectMetadata("apps/2", dateService (ObjectMetadata) new BucketListObjectMetadata("apps/2", dateService
.iso8601DateParse("2009-05-07T18:27:09.000Z"), .iso8601DateParse("2009-05-07T18:27:09.000Z"),
"\"a227b8888045c8fd159fb495214000f0\"", HttpUtils "\"a227b8888045c8fd159fb495214000f0\"", encryptionService
.fromHexString("a227b8888045c8fd159fb495214000f0"), 8, .fromHexString("a227b8888045c8fd159fb495214000f0"), 8,
owner, StorageClass.STANDARD), owner, StorageClass.STANDARD),
(ObjectMetadata) new BucketListObjectMetadata("apps/3", dateService (ObjectMetadata) new BucketListObjectMetadata("apps/3", dateService
.iso8601DateParse("2009-05-07T18:27:09.000Z"), .iso8601DateParse("2009-05-07T18:27:09.000Z"),
"\"c9caa76c3dec53e2a192608ce73eef03\"", HttpUtils "\"c9caa76c3dec53e2a192608ce73eef03\"", encryptionService
.fromHexString("c9caa76c3dec53e2a192608ce73eef03"), 8, .fromHexString("c9caa76c3dec53e2a192608ce73eef03"), 8,
owner, StorageClass.STANDARD), owner, StorageClass.STANDARD),
(ObjectMetadata) new BucketListObjectMetadata("apps/4", dateService (ObjectMetadata) new BucketListObjectMetadata("apps/4", dateService
.iso8601DateParse("2009-05-07T18:27:09.000Z"), .iso8601DateParse("2009-05-07T18:27:09.000Z"),
"\"1ce5d0dcc6154a647ea90c7bdf82a224\"", HttpUtils "\"1ce5d0dcc6154a647ea90c7bdf82a224\"", encryptionService
.fromHexString("1ce5d0dcc6154a647ea90c7bdf82a224"), 8, .fromHexString("1ce5d0dcc6154a647ea90c7bdf82a224"), 8,
owner, StorageClass.STANDARD), owner, StorageClass.STANDARD),
(ObjectMetadata) new BucketListObjectMetadata("apps/5", dateService (ObjectMetadata) new BucketListObjectMetadata("apps/5", dateService
.iso8601DateParse("2009-05-07T18:27:09.000Z"), .iso8601DateParse("2009-05-07T18:27:09.000Z"),
"\"79433524d87462ee05708a8ef894ed55\"", HttpUtils "\"79433524d87462ee05708a8ef894ed55\"", encryptionService
.fromHexString("79433524d87462ee05708a8ef894ed55"), 8, .fromHexString("79433524d87462ee05708a8ef894ed55"), 8,
owner, StorageClass.STANDARD), owner, StorageClass.STANDARD),
(ObjectMetadata) new BucketListObjectMetadata("apps/6", dateService (ObjectMetadata) new BucketListObjectMetadata("apps/6", dateService
.iso8601DateParse("2009-05-07T18:27:10.000Z"), .iso8601DateParse("2009-05-07T18:27:10.000Z"),
"\"dd00a060b28ddca8bc5a21a49e306f67\"", HttpUtils "\"dd00a060b28ddca8bc5a21a49e306f67\"", encryptionService
.fromHexString("dd00a060b28ddca8bc5a21a49e306f67"), 8, .fromHexString("dd00a060b28ddca8bc5a21a49e306f67"), 8,
owner, StorageClass.STANDARD), owner, StorageClass.STANDARD),
(ObjectMetadata) new BucketListObjectMetadata("apps/7", dateService (ObjectMetadata) new BucketListObjectMetadata("apps/7", dateService
.iso8601DateParse("2009-05-07T18:27:10.000Z"), .iso8601DateParse("2009-05-07T18:27:10.000Z"),
"\"8cd06eca6e819a927b07a285d750b100\"", HttpUtils "\"8cd06eca6e819a927b07a285d750b100\"", encryptionService
.fromHexString("8cd06eca6e819a927b07a285d750b100"), 8, .fromHexString("8cd06eca6e819a927b07a285d750b100"), 8,
owner, StorageClass.STANDARD), owner, StorageClass.STANDARD),
(ObjectMetadata) new BucketListObjectMetadata("apps/8", dateService (ObjectMetadata) new BucketListObjectMetadata("apps/8", dateService
.iso8601DateParse("2009-05-07T18:27:10.000Z"), .iso8601DateParse("2009-05-07T18:27:10.000Z"),
"\"174495094d0633b92cbe46603eee6bad\"", HttpUtils "\"174495094d0633b92cbe46603eee6bad\"", encryptionService
.fromHexString("174495094d0633b92cbe46603eee6bad"), 8, .fromHexString("174495094d0633b92cbe46603eee6bad"), 8,
owner, StorageClass.STANDARD), owner, StorageClass.STANDARD),
(ObjectMetadata) new BucketListObjectMetadata("apps/9", dateService (ObjectMetadata) new BucketListObjectMetadata("apps/9", dateService
.iso8601DateParse("2009-05-07T18:27:10.000Z"), .iso8601DateParse("2009-05-07T18:27:10.000Z"),
"\"cd8a19b26fea8a827276df0ad11c580d\"", HttpUtils "\"cd8a19b26fea8a827276df0ad11c580d\"", encryptionService
.fromHexString("cd8a19b26fea8a827276df0ad11c580d"), 8, .fromHexString("cd8a19b26fea8a827276df0ad11c580d"), 8,
owner, StorageClass.STANDARD)), "apps/", null, 1000, null, false, owner, StorageClass.STANDARD)), "apps/", null, 1000, null, false,
new TreeSet<String>()); new TreeSet<String>());

View File

@ -35,6 +35,7 @@ import org.jclouds.azure.storage.blob.domain.AzureBlob;
import org.jclouds.azure.storage.blob.reference.AzureBlobConstants; import org.jclouds.azure.storage.blob.reference.AzureBlobConstants;
import org.jclouds.blobstore.binders.BindBlobToEntityAndUserMetadataToHeadersWithPrefix; import org.jclouds.blobstore.binders.BindBlobToEntityAndUserMetadataToHeadersWithPrefix;
import org.jclouds.http.HttpRequest; import org.jclouds.http.HttpRequest;
import org.jclouds.util.EncryptionService;
public class BindAzureBlobToEntity extends BindBlobToEntityAndUserMetadataToHeadersWithPrefix { public class BindAzureBlobToEntity extends BindBlobToEntityAndUserMetadataToHeadersWithPrefix {
@ -42,8 +43,9 @@ public class BindAzureBlobToEntity extends BindBlobToEntityAndUserMetadataToHead
@Inject @Inject
public BindAzureBlobToEntity(AzureBlobToBlob azureBlob2Blob, public BindAzureBlobToEntity(AzureBlobToBlob azureBlob2Blob,
@Named(AzureBlobConstants.PROPERTY_AZUREBLOB_METADATA_PREFIX) String prefix) { @Named(AzureBlobConstants.PROPERTY_AZUREBLOB_METADATA_PREFIX) String prefix,
super(prefix); EncryptionService encryptionService) {
super(prefix, encryptionService);
this.azureBlob2Blob = azureBlob2Blob; this.azureBlob2Blob = azureBlob2Blob;
} }

View File

@ -44,6 +44,7 @@ import org.jclouds.http.HttpRequestFilter;
import org.jclouds.http.HttpUtils; import org.jclouds.http.HttpUtils;
import org.jclouds.http.internal.SignatureWire; import org.jclouds.http.internal.SignatureWire;
import org.jclouds.logging.Logger; import org.jclouds.logging.Logger;
import org.jclouds.util.EncryptionService;
import org.jclouds.util.TimeStamp; import org.jclouds.util.TimeStamp;
import com.google.common.annotations.VisibleForTesting; import com.google.common.annotations.VisibleForTesting;
@ -64,6 +65,7 @@ public class SharedKeyAuthentication implements HttpRequestFilter {
private final String account; private final String account;
private final byte[] key; private final byte[] key;
private final Provider<String> timeStampProvider; private final Provider<String> timeStampProvider;
private final EncryptionService encryptionService;
@Resource @Resource
@Named(HttpConstants.SIGNATURE_LOGGER) @Named(HttpConstants.SIGNATURE_LOGGER)
Logger signatureLog = Logger.NULL; Logger signatureLog = Logger.NULL;
@ -72,10 +74,11 @@ public class SharedKeyAuthentication implements HttpRequestFilter {
public SharedKeyAuthentication(SignatureWire signatureWire, public SharedKeyAuthentication(SignatureWire signatureWire,
@Named(AzureStorageConstants.PROPERTY_AZURESTORAGE_ACCOUNT) String account, @Named(AzureStorageConstants.PROPERTY_AZURESTORAGE_ACCOUNT) String account,
@Named(AzureStorageConstants.PROPERTY_AZURESTORAGE_KEY) String encodedKey, @Named(AzureStorageConstants.PROPERTY_AZURESTORAGE_KEY) String encodedKey,
@TimeStamp Provider<String> timeStampProvider) { @TimeStamp Provider<String> timeStampProvider, EncryptionService encryptionService) {
this.encryptionService = encryptionService;
this.signatureWire = signatureWire; this.signatureWire = signatureWire;
this.account = account; this.account = account;
this.key = HttpUtils.fromBase64String(encodedKey); this.key = encryptionService.fromBase64String(encodedKey);
this.timeStampProvider = timeStampProvider; this.timeStampProvider = timeStampProvider;
} }
@ -111,7 +114,7 @@ public class SharedKeyAuthentication implements HttpRequestFilter {
public String signString(String toSign) { public String signString(String toSign) {
String signature; String signature;
try { try {
signature = HttpUtils.hmacSha256Base64(toSign, key); signature = encryptionService.hmacSha256Base64(toSign, key);
} catch (Exception e) { } catch (Exception e) {
throw new HttpException("error signing request", e); throw new HttpException("error signing request", e);
} }

View File

@ -44,10 +44,11 @@ import org.jclouds.azure.storage.blob.options.CreateContainerOptions;
import org.jclouds.azure.storage.domain.BoundedSortedSet; import org.jclouds.azure.storage.domain.BoundedSortedSet;
import org.jclouds.azure.storage.options.ListOptions; import org.jclouds.azure.storage.options.ListOptions;
import org.jclouds.http.HttpResponseException; import org.jclouds.http.HttpResponseException;
import org.jclouds.http.HttpUtils;
import org.jclouds.http.options.GetOptions; import org.jclouds.http.options.GetOptions;
import org.jclouds.logging.log4j.config.Log4JLoggingModule; import org.jclouds.logging.log4j.config.Log4JLoggingModule;
import org.jclouds.util.EncryptionService;
import org.jclouds.util.Utils; import org.jclouds.util.Utils;
import org.jclouds.util.internal.JCEEncryptionService;
import org.testng.annotations.BeforeGroups; import org.testng.annotations.BeforeGroups;
import org.testng.annotations.Test; import org.testng.annotations.Test;
@ -64,6 +65,7 @@ public class AzureBlobClientLiveTest {
protected AzureBlobClient connection; protected AzureBlobClient connection;
private String containerPrefix = System.getProperty("user.name") + "-azureblob"; private String containerPrefix = System.getProperty("user.name") + "-azureblob";
private EncryptionService encryptionService = new JCEEncryptionService();
@BeforeGroups(groups = { "live" }) @BeforeGroups(groups = { "live" })
public void setupClient() { public void setupClient() {
@ -234,8 +236,8 @@ public class AzureBlobClientLiveTest {
object.getProperties().getMetadata().put("Metadata", "metadata-value"); object.getProperties().getMetadata().put("Metadata", "metadata-value");
byte[] md5 = object.getProperties().getContentMD5(); byte[] md5 = object.getProperties().getContentMD5();
String newEtag = connection.putBlob(privateContainer, object); String newEtag = connection.putBlob(privateContainer, object);
assertEquals(HttpUtils.toHexString(md5), HttpUtils.toHexString(object.getProperties() assertEquals(encryptionService.toHexString(md5), encryptionService.toHexString(object
.getContentMD5())); .getProperties().getContentMD5()));
// Test HEAD of missing object // Test HEAD of missing object
try { try {
@ -257,8 +259,8 @@ public class AzureBlobClientLiveTest {
// assertEquals(metadata.getSize(), data.length()); // assertEquals(metadata.getSize(), data.length());
assertEquals(metadata.getContentType(), "text/plain"); assertEquals(metadata.getContentType(), "text/plain");
// Azure doesn't return the Content-MD5 on head request... // Azure doesn't return the Content-MD5 on head request...
assertEquals(HttpUtils.toHexString(md5), HttpUtils.toHexString(object.getProperties() assertEquals(encryptionService.toHexString(md5), encryptionService.toHexString(object
.getContentMD5())); .getProperties().getContentMD5()));
assertEquals(metadata.getETag(), newEtag); assertEquals(metadata.getETag(), newEtag);
assertEquals(metadata.getMetadata().entrySet().size(), 1); assertEquals(metadata.getMetadata().entrySet().size(), 1);
assertEquals(metadata.getMetadata().get("metadata"), "metadata-value"); assertEquals(metadata.getMetadata().get("metadata"), "metadata-value");
@ -283,8 +285,8 @@ public class AzureBlobClientLiveTest {
// TODO assertEquals(getBlob.getName(), object.getProperties().getName()); // TODO assertEquals(getBlob.getName(), object.getProperties().getName());
assertEquals(getBlob.getContentLength(), new Long(data.length())); assertEquals(getBlob.getContentLength(), new Long(data.length()));
assertEquals(getBlob.getProperties().getContentType(), "text/plain"); assertEquals(getBlob.getProperties().getContentType(), "text/plain");
assertEquals(HttpUtils.toHexString(md5), HttpUtils.toHexString(getBlob.getProperties() assertEquals(encryptionService.toHexString(md5), encryptionService.toHexString(getBlob
.getContentMD5())); .getProperties().getContentMD5()));
assertEquals(newEtag, getBlob.getProperties().getETag()); assertEquals(newEtag, getBlob.getProperties().getETag());
// wait until we can update metadata // wait until we can update metadata
// assertEquals(getBlob.getProperties().getMetadata().entries().size(), 2); // assertEquals(getBlob.getProperties().getMetadata().entries().size(), 2);
@ -314,8 +316,8 @@ public class AzureBlobClientLiveTest {
object.setData(bais); object.setData(bais);
object.setContentLength(new Long(data.getBytes().length)); object.setContentLength(new Long(data.getBytes().length));
newEtag = connection.putBlob(privateContainer, object); newEtag = connection.putBlob(privateContainer, object);
assertEquals(HttpUtils.toHexString(md5), HttpUtils.toHexString(getBlob.getProperties() assertEquals(encryptionService.toHexString(md5), encryptionService.toHexString(getBlob
.getContentMD5())); .getProperties().getContentMD5()));
// Test GET with options // Test GET with options
// Non-matching ETag // Non-matching ETag

View File

@ -49,7 +49,6 @@ import org.jclouds.blobstore.functions.ReturnVoidOnNotFoundOr404;
import org.jclouds.blobstore.reference.BlobStoreConstants; import org.jclouds.blobstore.reference.BlobStoreConstants;
import org.jclouds.concurrent.WithinThreadExecutorService; import org.jclouds.concurrent.WithinThreadExecutorService;
import org.jclouds.concurrent.config.ExecutorServiceModule; import org.jclouds.concurrent.config.ExecutorServiceModule;
import org.jclouds.http.HttpUtils;
import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule; import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule;
import org.jclouds.http.functions.ParseSax; import org.jclouds.http.functions.ParseSax;
import org.jclouds.http.functions.ReturnTrueIf2xx; import org.jclouds.http.functions.ReturnTrueIf2xx;
@ -61,6 +60,7 @@ import org.jclouds.rest.config.RestModule;
import org.jclouds.rest.internal.GeneratedHttpRequest; import org.jclouds.rest.internal.GeneratedHttpRequest;
import org.jclouds.rest.internal.RestAnnotationProcessor; import org.jclouds.rest.internal.RestAnnotationProcessor;
import org.jclouds.util.Jsr330; import org.jclouds.util.Jsr330;
import org.jclouds.util.internal.Base64;
import org.testng.annotations.BeforeClass; import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test; import org.testng.annotations.Test;
@ -356,7 +356,7 @@ public class AzureBlobClientTest {
"myaccount"); "myaccount");
bindConstant().annotatedWith( bindConstant().annotatedWith(
Jsr330.named(AzureStorageConstants.PROPERTY_AZURESTORAGE_KEY)).to( Jsr330.named(AzureStorageConstants.PROPERTY_AZURESTORAGE_KEY)).to(
HttpUtils.toBase64String("key".getBytes())); Base64.encodeBytes("key".getBytes()));
bindConstant().annotatedWith( bindConstant().annotatedWith(
Jsr330.named(BlobStoreConstants.PROPERTY_USER_METADATA_PREFIX)).to( Jsr330.named(BlobStoreConstants.PROPERTY_USER_METADATA_PREFIX)).to(
"x-ms-meta-"); "x-ms-meta-");

View File

@ -31,12 +31,12 @@ import org.jclouds.azure.storage.handlers.ParseAzureStorageErrorFromXmlContent;
import org.jclouds.azure.storage.reference.AzureStorageConstants; import org.jclouds.azure.storage.reference.AzureStorageConstants;
import org.jclouds.concurrent.WithinThreadExecutorService; import org.jclouds.concurrent.WithinThreadExecutorService;
import org.jclouds.concurrent.config.ExecutorServiceModule; import org.jclouds.concurrent.config.ExecutorServiceModule;
import org.jclouds.http.HttpUtils;
import org.jclouds.http.functions.config.ParserModule; import org.jclouds.http.functions.config.ParserModule;
import org.jclouds.http.handlers.DelegatingErrorHandler; import org.jclouds.http.handlers.DelegatingErrorHandler;
import org.jclouds.http.handlers.DelegatingRetryHandler; import org.jclouds.http.handlers.DelegatingRetryHandler;
import org.jclouds.http.handlers.RedirectionRetryHandler; import org.jclouds.http.handlers.RedirectionRetryHandler;
import org.jclouds.util.Jsr330; import org.jclouds.util.Jsr330;
import org.jclouds.util.internal.Base64;
import org.testng.annotations.Test; import org.testng.annotations.Test;
import com.google.inject.AbstractModule; import com.google.inject.AbstractModule;
@ -58,7 +58,7 @@ public class RestAzureBlobClientModuleTest {
Jsr330.named(AzureBlobConstants.PROPERTY_AZURESTORAGE_ACCOUNT)).to("user"); Jsr330.named(AzureBlobConstants.PROPERTY_AZURESTORAGE_ACCOUNT)).to("user");
bindConstant() bindConstant()
.annotatedWith(Jsr330.named(AzureBlobConstants.PROPERTY_AZURESTORAGE_KEY)).to( .annotatedWith(Jsr330.named(AzureBlobConstants.PROPERTY_AZURESTORAGE_KEY)).to(
HttpUtils.toBase64String("secret".getBytes())); Base64.encodeBytes("secret".getBytes()));
bindConstant().annotatedWith( bindConstant().annotatedWith(
Jsr330.named(AzureBlobConstants.PROPERTY_AZUREBLOB_ENDPOINT)).to( Jsr330.named(AzureBlobConstants.PROPERTY_AZUREBLOB_ENDPOINT)).to(
"http://localhost"); "http://localhost");

View File

@ -36,9 +36,9 @@ import org.jclouds.azure.storage.reference.AzureStorageConstants;
import org.jclouds.concurrent.WithinThreadExecutorService; import org.jclouds.concurrent.WithinThreadExecutorService;
import org.jclouds.concurrent.config.ExecutorServiceModule; import org.jclouds.concurrent.config.ExecutorServiceModule;
import org.jclouds.http.HttpRequest; import org.jclouds.http.HttpRequest;
import org.jclouds.http.HttpUtils;
import org.jclouds.http.functions.config.ParserModule; import org.jclouds.http.functions.config.ParserModule;
import org.jclouds.util.Jsr330; import org.jclouds.util.Jsr330;
import org.jclouds.util.internal.Base64;
import org.testng.annotations.BeforeClass; import org.testng.annotations.BeforeClass;
import org.testng.annotations.DataProvider; import org.testng.annotations.DataProvider;
import org.testng.annotations.Test; import org.testng.annotations.Test;
@ -50,7 +50,7 @@ import com.google.inject.Injector;
@Test(groups = "unit", testName = "azurestorage.SharedKeyAuthenticationTest") @Test(groups = "unit", testName = "azurestorage.SharedKeyAuthenticationTest")
public class SharedKeyAuthenticationTest { public class SharedKeyAuthenticationTest {
private static final String KEY = HttpUtils.toBase64String("bar".getBytes()); private static final String KEY = Base64.encodeBytes("bar".getBytes());
private static final String ACCOUNT = "foo"; private static final String ACCOUNT = "foo";
private Injector injector; private Injector injector;
private SharedKeyAuthentication filter; private SharedKeyAuthentication filter;

View File

@ -40,7 +40,6 @@ import org.jclouds.azure.storage.options.ListOptions;
import org.jclouds.azure.storage.reference.AzureStorageConstants; import org.jclouds.azure.storage.reference.AzureStorageConstants;
import org.jclouds.concurrent.WithinThreadExecutorService; import org.jclouds.concurrent.WithinThreadExecutorService;
import org.jclouds.concurrent.config.ExecutorServiceModule; import org.jclouds.concurrent.config.ExecutorServiceModule;
import org.jclouds.http.HttpUtils;
import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule; import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule;
import org.jclouds.http.functions.ParseSax; import org.jclouds.http.functions.ParseSax;
import org.jclouds.http.functions.ReturnTrueIf2xx; import org.jclouds.http.functions.ReturnTrueIf2xx;
@ -50,6 +49,7 @@ import org.jclouds.rest.config.RestModule;
import org.jclouds.rest.internal.GeneratedHttpRequest; import org.jclouds.rest.internal.GeneratedHttpRequest;
import org.jclouds.rest.internal.RestAnnotationProcessor; import org.jclouds.rest.internal.RestAnnotationProcessor;
import org.jclouds.util.Jsr330; import org.jclouds.util.Jsr330;
import org.jclouds.util.internal.Base64;
import org.testng.annotations.BeforeClass; import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test; import org.testng.annotations.Test;
@ -179,7 +179,7 @@ public class AzureQueueClientTest {
Jsr330.named(AzureStorageConstants.PROPERTY_AZURESTORAGE_ACCOUNT)).to("user"); Jsr330.named(AzureStorageConstants.PROPERTY_AZURESTORAGE_ACCOUNT)).to("user");
bindConstant().annotatedWith( bindConstant().annotatedWith(
Jsr330.named(AzureStorageConstants.PROPERTY_AZURESTORAGE_KEY)).to( Jsr330.named(AzureStorageConstants.PROPERTY_AZURESTORAGE_KEY)).to(
HttpUtils.toBase64String("key".getBytes())); Base64.encodeBytes("key".getBytes()));
bind(Logger.LoggerFactory.class).toInstance(new LoggerFactory() { bind(Logger.LoggerFactory.class).toInstance(new LoggerFactory() {
public Logger getLogger(String category) { public Logger getLogger(String category) {
return Logger.NULL; return Logger.NULL;

View File

@ -25,14 +25,25 @@ package org.jclouds.blobstore.binders;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
import javax.inject.Inject;
import javax.ws.rs.core.HttpHeaders; import javax.ws.rs.core.HttpHeaders;
import org.jclouds.blobstore.domain.Blob; import org.jclouds.blobstore.domain.Blob;
import org.jclouds.http.HttpRequest; import org.jclouds.http.HttpRequest;
import org.jclouds.http.HttpUtils;
import org.jclouds.rest.Binder; import org.jclouds.rest.Binder;
import org.jclouds.util.EncryptionService;
/**
*
* @author Adrian Cole
*/
public class BindBlobToEntity implements Binder { public class BindBlobToEntity implements Binder {
private final EncryptionService encryptionService;
@Inject
public BindBlobToEntity(EncryptionService encryptionService) {
this.encryptionService = encryptionService;
}
public void bindToRequest(HttpRequest request, Object entity) { public void bindToRequest(HttpRequest request, Object entity) {
Blob object = (Blob) entity; Blob object = (Blob) entity;
@ -48,7 +59,7 @@ public class BindBlobToEntity implements Binder {
if (object.getMetadata().getContentMD5() != null) { if (object.getMetadata().getContentMD5() != null) {
request.getHeaders().put("Content-MD5", request.getHeaders().put("Content-MD5",
HttpUtils.toBase64String(object.getMetadata().getContentMD5())); encryptionService.toBase64String(object.getMetadata().getContentMD5()));
} }
} }
} }

View File

@ -30,13 +30,20 @@ import javax.inject.Named;
import org.jclouds.blobstore.domain.Blob; import org.jclouds.blobstore.domain.Blob;
import org.jclouds.http.HttpRequest; import org.jclouds.http.HttpRequest;
import org.jclouds.util.EncryptionService;
/**
*
* @author Adrian Cole
*/
public class BindBlobToEntityAndUserMetadataToHeadersWithPrefix extends BindBlobToEntity { public class BindBlobToEntityAndUserMetadataToHeadersWithPrefix extends BindBlobToEntity {
private final String metadataPrefix; private final String metadataPrefix;
@Inject @Inject
public BindBlobToEntityAndUserMetadataToHeadersWithPrefix( public BindBlobToEntityAndUserMetadataToHeadersWithPrefix(
@Named(PROPERTY_USER_METADATA_PREFIX) String metadataPrefix) { @Named(PROPERTY_USER_METADATA_PREFIX) String metadataPrefix,
EncryptionService encryptionService) {
super(encryptionService);
this.metadataPrefix = metadataPrefix; this.metadataPrefix = metadataPrefix;
} }

View File

@ -23,7 +23,7 @@
*/ */
package org.jclouds.blobstore.functions; package org.jclouds.blobstore.functions;
import org.jclouds.blobstore.functions.impl.BouncyCastleGenerateMD5; import org.jclouds.blobstore.functions.impl.JCEGenerateMD5;
import com.google.common.base.Function; import com.google.common.base.Function;
import com.google.inject.ImplementedBy; import com.google.inject.ImplementedBy;
@ -32,7 +32,7 @@ import com.google.inject.ImplementedBy;
* *
* @author Adrian Cole * @author Adrian Cole
*/ */
@ImplementedBy(BouncyCastleGenerateMD5.class) @ImplementedBy(JCEGenerateMD5.class)
public interface GenerateMD5 extends Function<Object, byte[]> { public interface GenerateMD5 extends Function<Object, byte[]> {
} }

View File

@ -26,7 +26,7 @@ package org.jclouds.blobstore.functions;
import java.io.InputStream; import java.io.InputStream;
import org.jclouds.blobstore.domain.MD5InputStreamResult; import org.jclouds.blobstore.domain.MD5InputStreamResult;
import org.jclouds.blobstore.functions.impl.BouncyCastleGenerateMD5Result; import org.jclouds.blobstore.functions.impl.JCEGenerateMD5Result;
import com.google.common.base.Function; import com.google.common.base.Function;
import com.google.inject.ImplementedBy; import com.google.inject.ImplementedBy;
@ -35,7 +35,7 @@ import com.google.inject.ImplementedBy;
* *
* @author Adrian Cole * @author Adrian Cole
*/ */
@ImplementedBy(BouncyCastleGenerateMD5Result.class) @ImplementedBy(JCEGenerateMD5Result.class)
public interface GenerateMD5Result extends Function<InputStream, MD5InputStreamResult> { public interface GenerateMD5Result extends Function<InputStream, MD5InputStreamResult> {
} }

View File

@ -35,10 +35,10 @@ import javax.ws.rs.core.HttpHeaders;
import org.jclouds.blobstore.domain.MutableBlobMetadata; import org.jclouds.blobstore.domain.MutableBlobMetadata;
import org.jclouds.http.HttpException; import org.jclouds.http.HttpException;
import org.jclouds.http.HttpResponse; import org.jclouds.http.HttpResponse;
import org.jclouds.http.HttpUtils;
import org.jclouds.rest.InvocationContext; import org.jclouds.rest.InvocationContext;
import org.jclouds.rest.internal.GeneratedHttpRequest; import org.jclouds.rest.internal.GeneratedHttpRequest;
import org.jclouds.util.DateService; import org.jclouds.util.DateService;
import org.jclouds.util.EncryptionService;
import com.google.common.annotations.VisibleForTesting; import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Function; import com.google.common.base.Function;
@ -51,14 +51,17 @@ public class ParseSystemAndUserMetadataFromHeaders implements
private final String metadataPrefix; private final String metadataPrefix;
private final DateService dateParser; private final DateService dateParser;
private final Provider<MutableBlobMetadata> metadataFactory; private final Provider<MutableBlobMetadata> metadataFactory;
private final EncryptionService encryptionService;
private GeneratedHttpRequest<?> request; private GeneratedHttpRequest<?> request;
@Inject @Inject
public ParseSystemAndUserMetadataFromHeaders(Provider<MutableBlobMetadata> metadataFactory, public ParseSystemAndUserMetadataFromHeaders(Provider<MutableBlobMetadata> metadataFactory,
DateService dateParser, @Named(PROPERTY_USER_METADATA_PREFIX) String metadataPrefix) { DateService dateParser, @Named(PROPERTY_USER_METADATA_PREFIX) String metadataPrefix,
EncryptionService encryptionService) {
this.metadataFactory = metadataFactory; this.metadataFactory = metadataFactory;
this.dateParser = dateParser; this.dateParser = dateParser;
this.metadataPrefix = metadataPrefix; this.metadataPrefix = metadataPrefix;
this.encryptionService = encryptionService;
} }
public MutableBlobMetadata apply(HttpResponse from) { public MutableBlobMetadata apply(HttpResponse from) {
@ -115,7 +118,7 @@ public class ParseSystemAndUserMetadataFromHeaders implements
protected void addContentMD5To(HttpResponse from, MutableBlobMetadata metadata) { protected void addContentMD5To(HttpResponse from, MutableBlobMetadata metadata) {
String contentMD5 = from.getFirstHeaderOrNull("Content-MD5"); String contentMD5 = from.getFirstHeaderOrNull("Content-MD5");
if (contentMD5 != null) { if (contentMD5 != null) {
metadata.setContentMD5(HttpUtils.fromBase64String(contentMD5)); metadata.setContentMD5(encryptionService.fromBase64String(contentMD5));
} }
} }

View File

@ -26,17 +26,19 @@ package org.jclouds.blobstore.functions.impl;
import javax.inject.Singleton; import javax.inject.Singleton;
import org.jclouds.blobstore.functions.GenerateMD5; import org.jclouds.blobstore.functions.GenerateMD5;
import org.jclouds.http.HttpUtils; import org.jclouds.util.EncryptionService;
import org.jclouds.util.internal.JCEEncryptionService;
/** /**
* *
* @author Adrian Cole * @author Adrian Cole
*/ */
@Singleton @Singleton
public class BouncyCastleGenerateMD5 implements GenerateMD5 { public class JCEGenerateMD5 implements GenerateMD5 {
private static final EncryptionService encryptionService = new JCEEncryptionService();
public byte[] apply(Object from) { public byte[] apply(Object from) {
return HttpUtils.md5(from); return encryptionService.md5(from);
} }
} }

View File

@ -23,47 +23,26 @@
*/ */
package org.jclouds.blobstore.functions.impl; package org.jclouds.blobstore.functions.impl;
import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import javax.inject.Singleton; import javax.inject.Singleton;
import org.apache.commons.io.IOUtils;
import org.apache.commons.io.output.ByteArrayOutputStream;
import org.bouncycastle.crypto.digests.MD5Digest;
import org.jclouds.blobstore.domain.MD5InputStreamResult; import org.jclouds.blobstore.domain.MD5InputStreamResult;
import org.jclouds.blobstore.functions.GenerateMD5Result; import org.jclouds.blobstore.functions.GenerateMD5Result;
import org.jclouds.blobstore.internal.BlobRuntimeException; import org.jclouds.util.EncryptionService;
import org.jclouds.util.internal.JCEEncryptionService;
/** /**
* *
* @author Adrian Cole * @author Adrian Cole
*/ */
@Singleton @Singleton
public class BouncyCastleGenerateMD5Result implements GenerateMD5Result { public class JCEGenerateMD5Result implements GenerateMD5Result {
private static final EncryptionService encryptionService = new JCEEncryptionService();
public MD5InputStreamResult apply(InputStream toEncode) { public MD5InputStreamResult apply(InputStream toEncode) {
MD5Digest eTag = new MD5Digest(); org.jclouds.util.EncryptionService.MD5InputStreamResult result = encryptionService
byte[] resBuf = new byte[eTag.getDigestSize()]; .generateMD5Result(toEncode);
byte[] buffer = new byte[1024]; return new MD5InputStreamResult(result.data, result.md5, result.length);
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) {
throw new BlobRuntimeException("couldn't get MD5 for: " + toEncode, e);
} finally {
IOUtils.closeQuietly(out);
IOUtils.closeQuietly(toEncode);
}
eTag.doFinal(resBuf, 0);
return new MD5InputStreamResult(out.toByteArray(), resBuf, length);
} }
} }

View File

@ -40,6 +40,7 @@ import org.jclouds.blobstore.domain.internal.MutableBlobMetadataImpl;
import org.jclouds.http.HttpException; import org.jclouds.http.HttpException;
import org.jclouds.http.HttpResponse; import org.jclouds.http.HttpResponse;
import org.jclouds.rest.internal.GeneratedHttpRequest; import org.jclouds.rest.internal.GeneratedHttpRequest;
import org.jclouds.util.internal.JCEEncryptionService;
import org.jclouds.util.internal.SimpleDateFormatDateService; import org.jclouds.util.internal.SimpleDateFormatDateService;
import org.testng.annotations.BeforeTest; import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test; import org.testng.annotations.Test;
@ -62,7 +63,7 @@ public class ParseBlobMetadataFromHeadersTest {
void setUp() { void setUp() {
parser = new ParseSystemAndUserMetadataFromHeaders(blobMetadataProvider, parser = new ParseSystemAndUserMetadataFromHeaders(blobMetadataProvider,
new SimpleDateFormatDateService(), "prefix"); new SimpleDateFormatDateService(), "prefix", new JCEEncryptionService());
GeneratedHttpRequest<?> request = createMock(GeneratedHttpRequest.class); GeneratedHttpRequest<?> request = createMock(GeneratedHttpRequest.class);
expect(request.getEndpoint()).andReturn(URI.create("http://localhost/key")).anyTimes(); expect(request.getEndpoint()).andReturn(URI.create("http://localhost/key")).anyTimes();

View File

@ -46,7 +46,7 @@ import org.jclouds.blobstore.domain.BlobMetadata;
import org.jclouds.blobstore.domain.ResourceMetadata; import org.jclouds.blobstore.domain.ResourceMetadata;
import org.jclouds.blobstore.util.BlobStoreUtils; import org.jclouds.blobstore.util.BlobStoreUtils;
import org.jclouds.http.HttpResponseException; import org.jclouds.http.HttpResponseException;
import org.jclouds.http.HttpUtils; import org.jclouds.util.internal.JCEEncryptionService;
import org.testng.annotations.DataProvider; import org.testng.annotations.DataProvider;
import org.testng.annotations.Test; import org.testng.annotations.Test;
@ -329,7 +329,7 @@ public class BaseBlobIntegrationTest<A, S> extends BaseBlobStoreIntegrationTest<
// NOTE all metadata in jclouds comes out as lowercase, in an effort to normalize the // NOTE all metadata in jclouds comes out as lowercase, in an effort to normalize the
// providers. // providers.
object.getMetadata().getUserMetadata().put("Adrian", "powderpuff"); object.getMetadata().getUserMetadata().put("Adrian", "powderpuff");
object.getMetadata().setContentMD5(HttpUtils.md5(TEST_STRING.getBytes())); object.getMetadata().setContentMD5(new JCEEncryptionService().md5(TEST_STRING.getBytes()));
String containerName = getContainerName(); String containerName = getContainerName();
try { try {
addBlobToContainer(containerName, object); addBlobToContainer(containerName, object);
@ -356,7 +356,7 @@ public class BaseBlobIntegrationTest<A, S> extends BaseBlobStoreIntegrationTest<
assert metadata.getContentType().startsWith("text/plain") : metadata.getContentType(); assert metadata.getContentType().startsWith("text/plain") : metadata.getContentType();
assertEquals(metadata.getSize(), new Long(TEST_STRING.length())); assertEquals(metadata.getSize(), new Long(TEST_STRING.length()));
assertEquals(metadata.getUserMetadata().get("adrian"), "powderpuff"); assertEquals(metadata.getUserMetadata().get("adrian"), "powderpuff");
assertEquals(metadata.getContentMD5(), HttpUtils.md5(TEST_STRING.getBytes())); assertEquals(metadata.getContentMD5(), new JCEEncryptionService().md5(TEST_STRING.getBytes()));
} }
} }

View File

@ -31,7 +31,7 @@ import java.net.URL;
import java.net.URLConnection; import java.net.URLConnection;
import org.jclouds.blobstore.domain.Blob; import org.jclouds.blobstore.domain.Blob;
import org.jclouds.http.HttpUtils; import org.jclouds.util.internal.JCEEncryptionService;
import org.testng.annotations.Optional; import org.testng.annotations.Optional;
import org.testng.annotations.Parameters; import org.testng.annotations.Parameters;
import org.testng.annotations.Test; import org.testng.annotations.Test;
@ -64,7 +64,7 @@ public class BaseBlobLiveTest<A, S> extends BaseBlobStoreIntegrationTest<A, S> {
String key = "hello"; String key = "hello";
URL url = new URL(httpStreamUrl); URL url = new URL(httpStreamUrl);
byte[] md5 = HttpUtils.fromHexString(httpStreamETag); byte[] md5 = new JCEEncryptionService().fromHexString(httpStreamETag);
URLConnection connection = url.openConnection(); URLConnection connection = url.openConnection();
int length = connection.getContentLength(); int length = connection.getContentLength();

View File

@ -82,9 +82,9 @@ import org.jclouds.http.HttpCommand;
import org.jclouds.http.HttpRequest; import org.jclouds.http.HttpRequest;
import org.jclouds.http.HttpResponse; import org.jclouds.http.HttpResponse;
import org.jclouds.http.HttpResponseException; import org.jclouds.http.HttpResponseException;
import org.jclouds.http.HttpUtils;
import org.jclouds.http.options.HttpRequestOptions; import org.jclouds.http.options.HttpRequestOptions;
import org.jclouds.util.DateService; import org.jclouds.util.DateService;
import org.jclouds.util.EncryptionService;
import org.jclouds.util.Utils; import org.jclouds.util.Utils;
import com.google.common.base.Function; import com.google.common.base.Function;
@ -105,6 +105,7 @@ import com.google.inject.internal.Nullable;
public class StubAsyncBlobStore implements AsyncBlobStore { public class StubAsyncBlobStore implements AsyncBlobStore {
protected final DateService dateService; protected final DateService dateService;
protected final EncryptionService encryptionService;
private final ConcurrentMap<String, ConcurrentMap<String, Blob>> containerToBlobs; private final ConcurrentMap<String, ConcurrentMap<String, Blob>> containerToBlobs;
protected final Blob.Factory blobProvider; protected final Blob.Factory blobProvider;
protected final HttpGetOptionsListToGetOptions httpGetOptionsConverter; protected final HttpGetOptionsListToGetOptions httpGetOptionsConverter;
@ -117,11 +118,12 @@ public class StubAsyncBlobStore implements AsyncBlobStore {
@Inject @Inject
protected StubAsyncBlobStore( protected StubAsyncBlobStore(
ConcurrentMap<String, ConcurrentMap<String, Blob>> containerToBlobs, ConcurrentMap<String, ConcurrentMap<String, Blob>> containerToBlobs,
DateService dateService, Blob.Factory blobProvider, DateService dateService, EncryptionService encryptionService,
GetDirectoryStrategy getDirectoryStrategy, MkdirStrategy mkdirStrategy, Blob.Factory blobProvider, GetDirectoryStrategy getDirectoryStrategy,
IsDirectoryStrategy isDirectoryStrategy, MkdirStrategy mkdirStrategy, IsDirectoryStrategy isDirectoryStrategy,
HttpGetOptionsListToGetOptions httpGetOptionsConverter, ExecutorService service) { HttpGetOptionsListToGetOptions httpGetOptionsConverter, ExecutorService service) {
this.dateService = checkNotNull(dateService, "dateService"); this.dateService = checkNotNull(dateService, "dateService");
this.encryptionService = checkNotNull(encryptionService, "encryptionService");
this.containerToBlobs = checkNotNull(containerToBlobs, "containerToBlobs"); this.containerToBlobs = checkNotNull(containerToBlobs, "containerToBlobs");
this.blobProvider = checkNotNull(blobProvider, "blobProvider"); this.blobProvider = checkNotNull(blobProvider, "blobProvider");
this.getDirectoryStrategy = checkNotNull(getDirectoryStrategy, "getDirectoryStrategy"); this.getDirectoryStrategy = checkNotNull(getDirectoryStrategy, "getDirectoryStrategy");
@ -514,8 +516,8 @@ public class StubAsyncBlobStore implements AsyncBlobStore {
object.getMetadata().setSize(data.length); object.getMetadata().setSize(data.length);
MutableBlobMetadata newMd = copy(object.getMetadata()); MutableBlobMetadata newMd = copy(object.getMetadata());
newMd.setLastModified(new Date()); newMd.setLastModified(new Date());
final byte[] md5 = HttpUtils.md5(data); final byte[] md5 = encryptionService.md5(data);
final String eTag = HttpUtils.toHexString(md5); final String eTag = encryptionService.toHexString(md5);
newMd.setETag(eTag); newMd.setETag(eTag);
newMd.setContentMD5(md5); newMd.setContentMD5(md5);
newMd.setContentType(object.getMetadata().getContentType()); newMd.setContentType(object.getMetadata().getContentType());

View File

@ -94,11 +94,6 @@
<version>7.0.0pre3</version> <version>7.0.0pre3</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15</artifactId>
<version>1.44</version>
</dependency>
<dependency> <dependency>
<groupId>com.google.code.gson</groupId> <groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId> <artifactId>gson</artifactId>

View File

@ -23,13 +23,10 @@
*/ */
package org.jclouds.http; package org.jclouds.http;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState; import static com.google.common.base.Preconditions.checkState;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.File; import java.io.File;
import java.io.FileInputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
@ -37,9 +34,6 @@ import java.io.UnsupportedEncodingException;
import java.net.URI; import java.net.URI;
import java.net.URLDecoder; import java.net.URLDecoder;
import java.net.URLEncoder; import java.net.URLEncoder;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
@ -49,16 +43,7 @@ import java.util.regex.Pattern;
import javax.annotation.Resource; import javax.annotation.Resource;
import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;
import org.apache.commons.io.output.ByteArrayOutputStream;
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.macs.HMac;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.util.encoders.Base64;
import org.jclouds.logging.Logger; import org.jclouds.logging.Logger;
import org.jclouds.util.Utils;
import com.google.common.base.Function; import com.google.common.base.Function;
import com.google.common.base.Joiner; import com.google.common.base.Joiner;
@ -73,6 +58,18 @@ public class HttpUtils {
public static final Pattern URI_PATTERN = Pattern.compile("([a-z0-9]+)://([^:]*):(.*)@(.*)"); public static final Pattern URI_PATTERN = Pattern.compile("([a-z0-9]+)://([^:]*):(.*)@(.*)");
public static final Pattern PATTERN_THAT_BREAKS_URI = Pattern.compile("[a-z0-9]+://.*/.*@.*"); // slash public static final Pattern PATTERN_THAT_BREAKS_URI = Pattern.compile("[a-z0-9]+://.*/.*@.*"); // slash
public static Long calculateSize(Object data) {
Long size = null;
if (data instanceof byte[]) {
size = new Long(((byte[]) data).length);
} else if (data instanceof String) {
size = new Long(((String) data).length());
} else if (data instanceof File) {
size = ((File) data).length();
}
return size;
}
@Resource @Resource
protected static Logger logger = Logger.NULL; protected static Logger logger = Logger.NULL;
@ -198,25 +195,6 @@ public class HttpUtils {
public static final Pattern IP_PATTERN = Pattern public static final Pattern IP_PATTERN = Pattern
.compile("b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).)" .compile("b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).)"
+ "{3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)b"); + "{3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)b");
static 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' };
public static String toHexString(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);
}
}
public static void logRequest(Logger logger, HttpRequest request, String prefix) { public static void logRequest(Logger logger, HttpRequest request, String prefix) {
if (logger.isDebugEnabled()) { if (logger.isDebugEnabled()) {
@ -237,165 +215,6 @@ public class HttpUtils {
} }
} }
public static byte[] fromHexString(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;
}
public static String hmacSha256Base64(String toEncode, byte[] key)
throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeyException {
Digest digest = new SHA256Digest();
return hmacBase64(toEncode, key, digest);
}
private static String hmacBase64(String toEncode, byte[] key, Digest digest) {
byte[] resBuf = hmac(toEncode, key, digest);
return toBase64String(resBuf);
}
public static byte[] hmac(String toEncode, byte[] key, Digest digest) {
HMac hmac = new HMac(digest);
byte[] resBuf = new byte[hmac.getMacSize()];
byte[] plainBytes = Utils.encodeString(toEncode);
byte[] keyBytes = key;
hmac.init(new KeyParameter(keyBytes));
hmac.update(plainBytes, 0, plainBytes.length);
hmac.doFinal(resBuf, 0);
return resBuf;
}
public static String hmacSha1Base64(String toEncode, byte[] key)
throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeyException {
Digest digest = new SHA1Digest();
return hmacBase64(toEncode, key, digest);
}
public static String md5Hex(byte[] toEncode) throws NoSuchAlgorithmException,
NoSuchProviderException, InvalidKeyException, UnsupportedEncodingException {
byte[] resBuf = md5(toEncode);
return toHexString(resBuf);
}
public static String md5Base64(byte[] toEncode) throws NoSuchAlgorithmException,
NoSuchProviderException, InvalidKeyException {
byte[] resBuf = md5(toEncode);
return toBase64String(resBuf);
}
public static byte[] md5(byte[] plainBytes) {
MD5Digest eTag = new MD5Digest();
byte[] resBuf = new byte[eTag.getDigestSize()];
eTag.update(plainBytes, 0, plainBytes.length);
eTag.doFinal(resBuf, 0);
return resBuf;
}
public static byte[] md5(File toEncode) {
MD5Digest eTag = new MD5Digest();
byte[] resBuf = new byte[eTag.getDigestSize()];
byte[] buffer = new byte[1024];
int numRead = -1;
InputStream i = null;
try {
i = new FileInputStream(toEncode);
do {
numRead = i.read(buffer);
if (numRead > 0) {
eTag.update(buffer, 0, numRead);
}
} while (numRead != -1);
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
IOUtils.closeQuietly(i);
}
eTag.doFinal(resBuf, 0);
return resBuf;
}
public static String toBase64String(byte[] resBuf) {
return new String(Base64.encode(resBuf));
}
public static Long calculateSize(Object data) {
Long size = null;
if (data instanceof byte[]) {
size = new Long(((byte[]) data).length);
} else if (data instanceof String) {
size = new Long(((String) data).length());
} else if (data instanceof File) {
size = ((File) data).length();
}
return size;
}
/**
* @throws IOException
*/
public static byte[] md5(Object data) {
checkNotNull(data, "data must be set before calling generateETag()");
byte[] md5 = null;
if (data == null) {
} else if (data instanceof byte[]) {
md5 = md5((byte[]) data);
} else if (data instanceof String) {
md5 = md5(((String) data).getBytes());
} else if (data instanceof File) {
md5 = md5(((File) data));
} else if (data instanceof InputStream) {
md5 = generateMD5Result(((InputStream) data)).md5;
} else {
throw new UnsupportedOperationException("Content not supported " + data.getClass());
}
return md5;
}
public static MD5InputStreamResult generateMD5Result(InputStream toEncode) {
MD5Digest eTag = new MD5Digest();
byte[] resBuf = new byte[eTag.getDigestSize()];
byte[] buffer = new byte[1024];
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) {
throw new RuntimeException(e);
} finally {
IOUtils.closeQuietly(out);
IOUtils.closeQuietly(toEncode);
}
eTag.doFinal(resBuf, 0);
return new MD5InputStreamResult(out.toByteArray(), resBuf, length);
}
public static class MD5InputStreamResult {
public final byte[] data;
public final byte[] md5;
public final long length;
MD5InputStreamResult(byte[] data, byte[] eTag, long length) {
this.data = checkNotNull(data, "data");
this.md5 = checkNotNull(eTag, "eTag");
checkArgument(length >= 0, "length cannot me negative");
this.length = length;
}
}
public static void copy(InputStream input, OutputStream output) throws IOException { public static void copy(InputStream input, OutputStream output) throws IOException {
byte[] buffer = new byte[1024]; byte[] buffer = new byte[1024];
long length = 0; long length = 0;
@ -425,8 +244,4 @@ public class HttpUtils {
return buffer.toString(); return buffer.toString();
} }
public static byte[] fromBase64String(String encoded) {
return Base64.decode(encoded);
}
} }

View File

@ -35,7 +35,7 @@ import javax.ws.rs.core.HttpHeaders;
import org.jclouds.http.HttpException; import org.jclouds.http.HttpException;
import org.jclouds.http.HttpRequest; import org.jclouds.http.HttpRequest;
import org.jclouds.http.HttpRequestFilter; import org.jclouds.http.HttpRequestFilter;
import org.jclouds.http.HttpUtils; import org.jclouds.util.EncryptionService;
/** /**
* Uses Basic Authentication to sign the request. * Uses Basic Authentication to sign the request.
@ -47,12 +47,14 @@ import org.jclouds.http.HttpUtils;
@Singleton @Singleton
public class BasicAuthentication implements HttpRequestFilter { public class BasicAuthentication implements HttpRequestFilter {
private List<String> credentialList; private final List<String> credentialList;
public BasicAuthentication(String user, String password) throws UnsupportedEncodingException { public BasicAuthentication(String user, String password, EncryptionService encryptionService)
throws UnsupportedEncodingException {
this.credentialList = Collections.singletonList("Basic " this.credentialList = Collections.singletonList("Basic "
+ HttpUtils.toBase64String(String.format("%s:%s", checkNotNull(user, "user"), + encryptionService.toBase64String(String.format("%s:%s",
checkNotNull(password, "password")).getBytes("UTF-8"))); checkNotNull(user, "user"), checkNotNull(password, "password")).getBytes(
"UTF-8")));
} }
public void filter(HttpRequest request) throws HttpException { public void filter(HttpRequest request) throws HttpException {

View File

@ -27,17 +27,18 @@ import javax.annotation.Resource;
import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;
import org.jclouds.http.HttpResponse; import org.jclouds.http.HttpResponse;
import org.jclouds.http.HttpUtils;
import org.jclouds.logging.Logger; import org.jclouds.logging.Logger;
import org.jclouds.rest.InvocationContext; import org.jclouds.rest.InvocationContext;
import org.jclouds.rest.internal.GeneratedHttpRequest; import org.jclouds.rest.internal.GeneratedHttpRequest;
import org.jclouds.util.internal.Base64;
import com.google.common.base.Function; import com.google.common.base.Function;
/** /**
* @author Adrian Cole * @author Adrian Cole
*/ */
public class ParseContentMD5FromHeaders implements Function<HttpResponse, byte[]>, InvocationContext { public class ParseContentMD5FromHeaders implements Function<HttpResponse, byte[]>,
InvocationContext {
public static class NoContentMD5Exception extends RuntimeException { public static class NoContentMD5Exception extends RuntimeException {
@ -69,7 +70,7 @@ public class ParseContentMD5FromHeaders implements Function<HttpResponse, byte[]
IOUtils.closeQuietly(from.getContent()); IOUtils.closeQuietly(from.getContent());
String contentMD5 = from.getFirstHeaderOrNull("Content-MD5"); String contentMD5 = from.getFirstHeaderOrNull("Content-MD5");
if (contentMD5 != null) { if (contentMD5 != null) {
return HttpUtils.fromBase64String(contentMD5); return Base64.decode(contentMD5);
} }
throw new NoContentMD5Exception(request, from); throw new NoContentMD5Exception(request, from);
} }

View File

@ -0,0 +1,89 @@
/**
*
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*/
package org.jclouds.util;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import java.io.File;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import org.jclouds.util.internal.JCEEncryptionService;
import com.google.inject.ImplementedBy;
/**
*
* @author Adrian Cole
*/
@ImplementedBy(JCEEncryptionService.class)
public interface EncryptionService {
String toHexString(byte[] raw);
byte[] fromHexString(String hex);
String hmacSha256Base64(String toEncode, byte[] key) throws NoSuchAlgorithmException,
NoSuchProviderException, InvalidKeyException;
String hmacSha1Base64(String toEncode, byte[] key) throws NoSuchAlgorithmException,
NoSuchProviderException, InvalidKeyException;
String md5Hex(byte[] toEncode) throws NoSuchAlgorithmException, NoSuchProviderException,
InvalidKeyException, UnsupportedEncodingException;
String md5Base64(byte[] toEncode) throws NoSuchAlgorithmException, NoSuchProviderException,
InvalidKeyException;
byte[] md5(byte[] plainBytes);
byte[] md5(File toEncode);
String toBase64String(byte[] resBuf);
byte[] md5(Object data);
MD5InputStreamResult generateMD5Result(InputStream toEncode);
public static class MD5InputStreamResult {
public final byte[] data;
public final byte[] md5;
public final long length;
public MD5InputStreamResult(byte[] data, byte[] eTag, long length) {
this.data = checkNotNull(data, "data");
this.md5 = checkNotNull(eTag, "eTag");
checkArgument(length >= 0, "length cannot me negative");
this.length = length;
}
}
byte[] fromBase64String(String encoded);
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,85 @@
package org.jclouds.util.internal;
import static com.google.common.base.Preconditions.checkNotNull;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import org.jclouds.util.EncryptionService;
/**
*
* @author Adrian Cole
*/
public abstract class BaseEncryptionService implements EncryptionService {
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' };
public String toHexString(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);
}
}
public byte[] fromHexString(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;
}
public String md5Hex(byte[] toEncode) throws NoSuchAlgorithmException, NoSuchProviderException,
InvalidKeyException, UnsupportedEncodingException {
byte[] resBuf = md5(toEncode);
return toHexString(resBuf);
}
public String md5Base64(byte[] toEncode) throws NoSuchAlgorithmException,
NoSuchProviderException, InvalidKeyException {
byte[] resBuf = md5(toEncode);
return toBase64String(resBuf);
}
/**
* @throws IOException
*/
public byte[] md5(Object data) {
checkNotNull(data, "data must be set before calling generateETag()");
byte[] md5 = null;
if (data == null) {
} else if (data instanceof byte[]) {
md5 = md5((byte[]) data);
} else if (data instanceof String) {
md5 = md5(((String) data).getBytes());
} else if (data instanceof File) {
md5 = md5(((File) data));
} else if (data instanceof InputStream) {
md5 = generateMD5Result(((InputStream) data)).md5;
} else {
throw new UnsupportedOperationException("Content not supported " + data.getClass());
}
return md5;
}
}

View File

@ -0,0 +1,125 @@
package org.jclouds.util.internal;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.io.IOUtils;
import org.apache.commons.io.output.ByteArrayOutputStream;
/**
*
* @author Adrian Cole
*/
public class JCEEncryptionService extends BaseEncryptionService {
public String hmacSha256Base64(String toEncode, byte[] key) throws NoSuchAlgorithmException,
NoSuchProviderException, InvalidKeyException {
return hmacBase64(toEncode, key, "HmacSHA256");
}
private String hmacBase64(String toEncode, byte[] key, String algorithm) {
byte[] resBuf = hmac(toEncode, key, algorithm);
return toBase64String(resBuf);
}
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());
}
public String hmacSha1Base64(String toEncode, byte[] key) throws NoSuchAlgorithmException,
NoSuchProviderException, InvalidKeyException {
return hmacBase64(toEncode, key, "HmacSHA1");
}
public byte[] md5(byte[] plainBytes) {
MessageDigest eTag = getDigest();
eTag.update(plainBytes, 0, plainBytes.length);
return eTag.digest();
}
public byte[] md5(File toEncode) {
MessageDigest eTag = getDigest();
byte[] buffer = new byte[1024];
int numRead = -1;
InputStream i = null;
try {
i = new FileInputStream(toEncode);
do {
numRead = i.read(buffer);
if (numRead > 0) {
eTag.update(buffer, 0, numRead);
}
} while (numRead != -1);
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
IOUtils.closeQuietly(i);
}
return eTag.digest();
}
public String toBase64String(byte[] resBuf) {
return Base64.encodeBytes(resBuf);
}
public MD5InputStreamResult generateMD5Result(InputStream toEncode) {
MessageDigest eTag = getDigest();
byte[] buffer = new byte[1024];
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) {
throw new RuntimeException(e);
} finally {
IOUtils.closeQuietly(out);
IOUtils.closeQuietly(toEncode);
}
return new MD5InputStreamResult(out.toByteArray(), eTag.digest(), length);
}
private MessageDigest getDigest() {
MessageDigest eTag;
try {
eTag = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException("Could not find the MD5 algorithm", e);
}
return eTag;
}
public byte[] fromBase64String(String encoded) {
return Base64.decode(encoded);
}
}

View File

@ -0,0 +1,172 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*/
package org.jclouds.util.internal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.SimpleTimeZone;
import net.jcip.annotations.GuardedBy;
import net.jcip.annotations.ThreadSafe;
import org.jclouds.util.DateService;
/**
*
* uses {@link SimpleDateFormat} internally.
*
* @author Adrian Cole
* @author James Murty
*/
@ThreadSafe
public class SimpleDateFormatDateService implements DateService {
/*
* Use default Java Date/SimpleDateFormat classes for date manipulation, but be *very* careful to
* guard against the lack of thread safety.
*/
@GuardedBy("this")
private static final SimpleDateFormat iso8601SecondsSimpleDateFormat = new SimpleDateFormat(
"yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US);
@GuardedBy("this")
private static final SimpleDateFormat iso8601SimpleDateFormat = new SimpleDateFormat(
"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.US);
@GuardedBy("this")
private static final SimpleDateFormat rfc822SimpleDateFormat = new SimpleDateFormat(
"EEE, dd MMM yyyy HH:mm:ss z", Locale.US);
@GuardedBy("this")
private static final SimpleDateFormat cSimpleDateFormat = new SimpleDateFormat(
"EEE MMM dd HH:mm:ss '+0000' yyyy", Locale.US);
static {
iso8601SimpleDateFormat.setTimeZone(new SimpleTimeZone(0, "GMT"));
iso8601SecondsSimpleDateFormat.setTimeZone(new SimpleTimeZone(0, "GMT"));
rfc822SimpleDateFormat.setTimeZone(new SimpleTimeZone(0, "GMT"));
cSimpleDateFormat.setTimeZone(new SimpleTimeZone(0, "GMT"));
}
public final Date fromSeconds(long seconds) {
return new Date(seconds * 1000);
}
public final String cDateFormat(Date date) {
synchronized (cSimpleDateFormat) {
return cSimpleDateFormat.format(date);
}
}
public final String cDateFormat() {
return cDateFormat(new Date());
}
public final Date cDateParse(String toParse) {
synchronized (cSimpleDateFormat) {
try {
return cSimpleDateFormat.parse(toParse);
} catch (ParseException e) {
throw new RuntimeException(e);
}
}
}
public final String rfc822DateFormat(Date date) {
synchronized (rfc822SimpleDateFormat) {
return rfc822SimpleDateFormat.format(date);
}
}
public final String rfc822DateFormat() {
return rfc822DateFormat(new Date());
}
public final Date rfc822DateParse(String toParse) {
synchronized (rfc822SimpleDateFormat) {
try {
return rfc822SimpleDateFormat.parse(toParse);
} catch (ParseException e) {
throw new RuntimeException(e);
}
}
}
public final String iso8601SecondsDateFormat() {
return iso8601SecondsDateFormat(new Date());
}
public final String iso8601DateFormat(Date date) {
synchronized (iso8601SimpleDateFormat) {
return iso8601SimpleDateFormat.format(date);
}
}
public final String iso8601DateFormat() {
return iso8601DateFormat(new Date());
}
public final Date iso8601DateParse(String toParse) {
toParse = trimNanosToMillis(toParse);
synchronized (iso8601SimpleDateFormat) {
try {
return iso8601SimpleDateFormat.parse(toParse);
} catch (ParseException e) {
throw new RuntimeException(e);
}
}
}
private String trimNanosToMillis(String toParse) {
if (toParse.matches(".*[0-9][0-9][0-9][0-9][0-9][0-9]"))
toParse = toParse.substring(0, toParse.length() - 3) + 'Z';
return toParse;
}
private String trimTZ(String toParse) {
if (toParse.length() == 25 && toParse.matches(".*[0-2][0-9]:00"))
toParse = toParse.substring(0, toParse.length() - 6) + 'Z';
return toParse;
}
public final Date iso8601SecondsDateParse(String toParse) {
toParse = trimTZ(toParse);
synchronized (iso8601SecondsSimpleDateFormat) {
try {
return iso8601SecondsSimpleDateFormat.parse(toParse);
} catch (ParseException e) {
throw new RuntimeException(e);
}
}
}
@Override
public String iso8601SecondsDateFormat(Date date) {
synchronized (iso8601SecondsSimpleDateFormat) {
return iso8601SecondsSimpleDateFormat.format(date);
}
}
}

View File

@ -31,6 +31,7 @@ import java.net.URI;
import javax.ws.rs.core.HttpHeaders; import javax.ws.rs.core.HttpHeaders;
import org.jclouds.http.HttpRequest; import org.jclouds.http.HttpRequest;
import org.jclouds.util.internal.JCEEncryptionService;
import org.testng.annotations.Test; import org.testng.annotations.Test;
/** /**
@ -45,7 +46,7 @@ public class BasicAuthenticationTest {
public void testAuth() throws UnsupportedEncodingException { public void testAuth() throws UnsupportedEncodingException {
BasicAuthentication filter = new BasicAuthentication(USER, PASSWORD); BasicAuthentication filter = new BasicAuthentication(USER, PASSWORD, new JCEEncryptionService());
HttpRequest request = new HttpRequest("GET", URI.create("http://localhost")); HttpRequest request = new HttpRequest("GET", URI.create("http://localhost"));
filter.filter(request); filter.filter(request);
assertEquals(request.getFirstHeaderOrNull(HttpHeaders.AUTHORIZATION), assertEquals(request.getFirstHeaderOrNull(HttpHeaders.AUTHORIZATION),

View File

@ -39,9 +39,9 @@ import java.util.concurrent.TimeUnit;
import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;
import org.jclouds.concurrent.WithinThreadExecutorService; import org.jclouds.concurrent.WithinThreadExecutorService;
import org.jclouds.http.HttpUtils;
import org.jclouds.http.internal.HttpWire;
import org.jclouds.logging.Logger; import org.jclouds.logging.Logger;
import org.jclouds.util.EncryptionService;
import org.jclouds.util.internal.JCEEncryptionService;
import org.testng.annotations.Test; import org.testng.annotations.Test;
/** /**
@ -54,6 +54,8 @@ public class WireLiveTest {
private static final String sysHttpStreamUrl = System.getProperty("jclouds.wire.httpstream.url"); private static final String sysHttpStreamUrl = System.getProperty("jclouds.wire.httpstream.url");
private static final String sysHttpStreamMd5 = System.getProperty("jclouds.wire.httpstream.md5"); private static final String sysHttpStreamMd5 = System.getProperty("jclouds.wire.httpstream.md5");
private static final EncryptionService encryptionService = new JCEEncryptionService();
private static class ConnectionTester implements Callable<Void> { private static class ConnectionTester implements Callable<Void> {
private final InputStream fromServer; private final InputStream fromServer;
@ -66,9 +68,9 @@ public class WireLiveTest {
InputStream in = wire.input(fromServer); InputStream in = wire.input(fromServer);
ByteArrayOutputStream out = new ByteArrayOutputStream(); ByteArrayOutputStream out = new ByteArrayOutputStream();
IOUtils.copy(in, out); IOUtils.copy(in, out);
byte[] compare = HttpUtils.md5(new ByteArrayInputStream(out.toByteArray())); byte[] compare = encryptionService.md5(new ByteArrayInputStream(out.toByteArray()));
Thread.sleep(100); Thread.sleep(100);
assertEquals(HttpUtils.toHexString(compare), checkNotNull(sysHttpStreamMd5, assertEquals(encryptionService.toHexString(compare), checkNotNull(sysHttpStreamMd5,
sysHttpStreamMd5)); sysHttpStreamMd5));
assertEquals(((BufferLogger) wire.getWireLog()).buff.toString().getBytes().length, 3331484); assertEquals(((BufferLogger) wire.getWireLog()).buff.toString().getBytes().length, 3331484);
return null; return null;
@ -148,9 +150,10 @@ public class WireLiveTest {
URLConnection connection = url.openConnection(); URLConnection connection = url.openConnection();
HttpWire wire = setUp(); HttpWire wire = setUp();
InputStream in = wire.input(connection.getInputStream()); InputStream in = wire.input(connection.getInputStream());
byte[] compare = HttpUtils.md5(in); byte[] compare = encryptionService.md5(in);
Thread.sleep(100); Thread.sleep(100);
assertEquals(HttpUtils.toHexString(compare), checkNotNull(sysHttpStreamMd5, sysHttpStreamMd5)); assertEquals(encryptionService.toHexString(compare), checkNotNull(sysHttpStreamMd5,
sysHttpStreamMd5));
assertEquals(((BufferLogger) wire.getWireLog()).buff.toString().getBytes().length, 3331484); assertEquals(((BufferLogger) wire.getWireLog()).buff.toString().getBytes().length, 3331484);
} }
@ -169,9 +172,10 @@ public class WireLiveTest {
URLConnection connection = url.openConnection(); URLConnection connection = url.openConnection();
HttpWire wire = setUpSynch(); HttpWire wire = setUpSynch();
InputStream in = wire.input(connection.getInputStream()); InputStream in = wire.input(connection.getInputStream());
byte[] compare = HttpUtils.md5(in); byte[] compare = encryptionService.md5(in);
Thread.sleep(100); Thread.sleep(100);
assertEquals(HttpUtils.toHexString(compare), checkNotNull(sysHttpStreamMd5, sysHttpStreamMd5)); assertEquals(encryptionService.toHexString(compare), checkNotNull(sysHttpStreamMd5,
sysHttpStreamMd5));
assertEquals(((BufferLogger) wire.getWireLog()).buff.toString().getBytes().length, 3331484); assertEquals(((BufferLogger) wire.getWireLog()).buff.toString().getBytes().length, 3331484);
} }

View File

@ -0,0 +1,148 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*/
package org.jclouds.util;
import static org.testng.Assert.assertEquals;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.util.concurrent.Callable;
import java.util.concurrent.CompletionService;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorCompletionService;
import org.jclouds.PerformanceTest;
import org.jclouds.util.internal.Base64;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import com.google.inject.Guice;
import com.google.inject.Injector;
/**
* This tests the performance of Digest commands.
*
* @author Adrian Cole
*/
@Test(groups = "performance", sequential = true, testName = "jclouds.encryptionService")
public class EncryptionServiceTest extends PerformanceTest {
protected EncryptionService encryptionService;
@BeforeTest
protected void createEncryptionService() {
Injector i = Guice.createInjector();
encryptionService = i.getInstance(EncryptionService.class);
}
@Test(dataProvider = "hmacsha1")
void testDigestSerialResponseTime(byte[] key, String message, String base64Digest)
throws NoSuchProviderException, NoSuchAlgorithmException, InvalidKeyException {
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 {
CompletionService<Boolean> completer = new ExecutorCompletionService<Boolean>(exec);
for (int i = 0; i < 10000; i++)
completer.submit(new Callable<Boolean>() {
public Boolean call() throws Exception {
testHmacSha1Base64(key, message, base64Digest);
return true;
}
});
for (int i = 0; i < 10000; i++)
assert completer.take().get();
}
@DataProvider(name = "eTag")
public Object[][] createMD5Data() {
return base64MD5MessageDigest;
}
public final static Object[][] base64MD5MessageDigest = {
{ "apple", "1f3870be274f6c49b3e31a0c6728957f" },
{ "bear", "893b56e3cfe153fb770a120b83bac20c" },
{ "candy", "c48ba993d35c3abe0380f91738fe2a34" },
{ "dogma", "95eb470e4faee302e9cd3063b1923dab" },
{ "emma", "00a809937eddc44521da9521269e75c6" } };
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("qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqo="),
"Test Using Larger Than Block-Size Key - Hash Key First",
"qkrl4VJy0A6VcFY3zoo7Ve1AIRI=" },
{
Base64
.decode("qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqo="),
"Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data",
"6OmdD0UjfXhta7qnllx4CLv/GpE=" } };
@DataProvider(name = "hmacsha1")
public Object[][] createData1() {
return base64KeyMessageDigest;
}
@Test(dataProvider = "hmacsha1")
public void testHmacSha1Base64(byte[] key, String message, String base64Digest)
throws NoSuchProviderException, NoSuchAlgorithmException, InvalidKeyException {
String b64 = encryptionService.hmacSha1Base64(message, key);
assertEquals(b64, base64Digest);
}
@Test(dataProvider = "eTag")
public void testMD5Digest(String message, String base64Digest) throws NoSuchProviderException,
NoSuchAlgorithmException, InvalidKeyException, UnsupportedEncodingException {
String b64 = encryptionService.md5Hex(message.getBytes());
assertEquals(base64Digest, b64);
}
byte[] bytes = { 0, 1, 2, 4, 8, 16, 32, 64 };
String hex = "0001020408102040";
public void testHexStringEncode() throws UnsupportedEncodingException {
assertEquals(encryptionService.toHexString(bytes), hex);
}
public void testHexStringDecode() throws UnsupportedEncodingException {
assertEquals(encryptionService.fromHexString(hex), bytes);
}
public void testHexStringDecodeOx() throws UnsupportedEncodingException {
assertEquals(encryptionService.fromHexString("0x" + hex), bytes);
}
}

View File

@ -25,20 +25,10 @@ package org.jclouds.util;
import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertEquals;
import java.io.UnsupportedEncodingException;
import java.net.URI; import java.net.URI;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.util.concurrent.Callable;
import java.util.concurrent.CompletionService;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorCompletionService;
import org.bouncycastle.util.encoders.Base64;
import org.jclouds.PerformanceTest; import org.jclouds.PerformanceTest;
import org.jclouds.http.HttpUtils; import org.jclouds.http.HttpUtils;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test; import org.testng.annotations.Test;
/** /**
@ -101,92 +91,4 @@ public class HttpUtilsTest extends PerformanceTest {
.create("https://jclouds.blob.core.windows.net/jclouds-getpath/write-tests/file1%25.txt")); .create("https://jclouds.blob.core.windows.net/jclouds-getpath/write-tests/file1%25.txt"));
} }
@Test(dataProvider = "hmacsha1")
void testBouncyCastleDigestSerialResponseTime(byte[] key, String message, String base64Digest)
throws NoSuchProviderException, NoSuchAlgorithmException, InvalidKeyException {
for (int i = 0; i < 10000; i++)
testBouncyCastleHmacSha1Base64(key, message, base64Digest);
}
@Test(dataProvider = "hmacsha1")
void testBouncyCastleDigestParallelResponseTime(final byte[] key, final String message,
final String base64Digest) throws NoSuchProviderException, NoSuchAlgorithmException,
InvalidKeyException, InterruptedException, ExecutionException {
CompletionService<Boolean> completer = new ExecutorCompletionService<Boolean>(exec);
for (int i = 0; i < 10000; i++)
completer.submit(new Callable<Boolean>() {
public Boolean call() throws Exception {
testBouncyCastleHmacSha1Base64(key, message, base64Digest);
return true;
}
});
for (int i = 0; i < 10000; i++)
assert completer.take().get();
}
@DataProvider(name = "eTag")
public Object[][] createMD5Data() {
return base64MD5MessageDigest;
}
public final static Object[][] base64MD5MessageDigest = {
{ "apple", "1f3870be274f6c49b3e31a0c6728957f" },
{ "bear", "893b56e3cfe153fb770a120b83bac20c" },
{ "candy", "c48ba993d35c3abe0380f91738fe2a34" },
{ "dogma", "95eb470e4faee302e9cd3063b1923dab" },
{ "emma", "00a809937eddc44521da9521269e75c6" } };
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("qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqo="),
"Test Using Larger Than Block-Size Key - Hash Key First",
"qkrl4VJy0A6VcFY3zoo7Ve1AIRI=" },
{
Base64
.decode("qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqo="),
"Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data",
"6OmdD0UjfXhta7qnllx4CLv/GpE=" } };
@DataProvider(name = "hmacsha1")
public Object[][] createData1() {
return base64KeyMessageDigest;
}
@Test(dataProvider = "hmacsha1")
public void testBouncyCastleHmacSha1Base64(byte[] key, String message, String base64Digest)
throws NoSuchProviderException, NoSuchAlgorithmException, InvalidKeyException {
String b64 = HttpUtils.hmacSha1Base64(message, key);
assertEquals(b64, base64Digest);
}
@Test(dataProvider = "eTag")
public void testBouncyCastleMD5Digest(String message, String base64Digest)
throws NoSuchProviderException, NoSuchAlgorithmException, InvalidKeyException,
UnsupportedEncodingException {
String b64 = HttpUtils.md5Hex(message.getBytes());
assertEquals(base64Digest, b64);
}
byte[] bytes = { 0, 1, 2, 4, 8, 16, 32, 64 };
String hex = "0001020408102040";
public void testHexStringEncode() throws UnsupportedEncodingException {
assertEquals(HttpUtils.toHexString(bytes), hex);
}
public void testHexStringDecode() throws UnsupportedEncodingException {
assertEquals(HttpUtils.fromHexString(hex), bytes);
}
public void testHexStringDecodeOx() throws UnsupportedEncodingException {
assertEquals(HttpUtils.fromHexString("0x" + hex), bytes);
}
} }

View File

@ -0,0 +1,46 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
$HeadURL$
$Revision$
$Date$
Copyright (C) 2009 Adrian Cole <adrian@jclouds.org>
====================================================================
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0.html
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.
====================================================================
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.jclouds</groupId>
<artifactId>jclouds-extensions-project</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>jclouds-bouncycastle</artifactId>
<name>jclouds bouncycastle EncryptionService Module</name>
<description>jclouds bouncycastle EncryptionService Module</description>
<dependencies>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15</artifactId>
<version>1.44</version>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,120 @@
package org.jclouds.util.internal;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import org.apache.commons.io.IOUtils;
import org.apache.commons.io.output.ByteArrayOutputStream;
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.macs.HMac;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.util.encoders.Base64;
import org.jclouds.util.Utils;
/**
*
* @author Adrian Cole
*/
public class BouncyCastleEncryptionService extends BaseEncryptionService {
public String hmacSha256Base64(String toEncode, byte[] key) throws NoSuchAlgorithmException,
NoSuchProviderException, InvalidKeyException {
Digest digest = new SHA256Digest();
return hmacBase64(toEncode, key, digest);
}
private String hmacBase64(String toEncode, byte[] key, Digest digest) {
byte[] resBuf = hmac(toEncode, key, digest);
return toBase64String(resBuf);
}
public byte[] hmac(String toEncode, byte[] key, Digest digest) {
HMac hmac = new HMac(digest);
byte[] resBuf = new byte[hmac.getMacSize()];
byte[] plainBytes = Utils.encodeString(toEncode);
byte[] keyBytes = key;
hmac.init(new KeyParameter(keyBytes));
hmac.update(plainBytes, 0, plainBytes.length);
hmac.doFinal(resBuf, 0);
return resBuf;
}
public String hmacSha1Base64(String toEncode, byte[] key) throws NoSuchAlgorithmException,
NoSuchProviderException, InvalidKeyException {
Digest digest = new SHA1Digest();
return hmacBase64(toEncode, key, digest);
}
public byte[] md5(byte[] plainBytes) {
MD5Digest eTag = new MD5Digest();
byte[] resBuf = new byte[eTag.getDigestSize()];
eTag.update(plainBytes, 0, plainBytes.length);
eTag.doFinal(resBuf, 0);
return resBuf;
}
public byte[] md5(File toEncode) {
MD5Digest eTag = new MD5Digest();
byte[] resBuf = new byte[eTag.getDigestSize()];
byte[] buffer = new byte[1024];
int numRead = -1;
InputStream i = null;
try {
i = new FileInputStream(toEncode);
do {
numRead = i.read(buffer);
if (numRead > 0) {
eTag.update(buffer, 0, numRead);
}
} while (numRead != -1);
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
IOUtils.closeQuietly(i);
}
eTag.doFinal(resBuf, 0);
return resBuf;
}
public String toBase64String(byte[] resBuf) {
return new String(Base64.encode(resBuf));
}
public MD5InputStreamResult generateMD5Result(InputStream toEncode) {
MD5Digest eTag = new MD5Digest();
byte[] resBuf = new byte[eTag.getDigestSize()];
byte[] buffer = new byte[1024];
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) {
throw new RuntimeException(e);
} finally {
IOUtils.closeQuietly(out);
IOUtils.closeQuietly(toEncode);
}
eTag.doFinal(resBuf, 0);
return new MD5InputStreamResult(out.toByteArray(), resBuf, length);
}
public byte[] fromBase64String(String encoded) {
return Base64.decode(encoded);
}
}

View File

@ -0,0 +1,90 @@
/**
*
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*/
package org.jclouds.util.internal;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import java.io.File;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import org.bouncycastle.crypto.Digest;
/**
*
* @author Adrian Cole
*/
public interface EncryptionService {
String toHexString(byte[] raw);
byte[] fromHexString(String hex);
String hmacSha256Base64(String toEncode, byte[] key) throws NoSuchAlgorithmException,
NoSuchProviderException, InvalidKeyException;
byte[] hmac(String toEncode, byte[] key, Digest digest);
String hmacSha1Base64(String toEncode, byte[] key) throws NoSuchAlgorithmException,
NoSuchProviderException, InvalidKeyException;
String md5Hex(byte[] toEncode) throws NoSuchAlgorithmException, NoSuchProviderException,
InvalidKeyException, UnsupportedEncodingException;
String md5Base64(byte[] toEncode) throws NoSuchAlgorithmException, NoSuchProviderException,
InvalidKeyException;
byte[] md5(byte[] plainBytes);
byte[] md5(File toEncode);
String toBase64String(byte[] resBuf);
Long calculateSize(Object data);
byte[] md5(Object data);
MD5InputStreamResult generateMD5Result(InputStream toEncode);
public static class MD5InputStreamResult {
public final byte[] data;
public final byte[] md5;
public final long length;
MD5InputStreamResult(byte[] data, byte[] eTag, long length) {
this.data = checkNotNull(data, "data");
this.md5 = checkNotNull(eTag, "eTag");
checkArgument(length >= 0, "length cannot me negative");
this.length = length;
}
}
byte[] fromBase64String(String encoded);
}

View File

@ -0,0 +1,23 @@
package org.jclouds.util.internal;
import org.jclouds.util.EncryptionServiceTest;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
import com.google.inject.Guice;
import com.google.inject.Injector;
/**
* This tests the performance of Digest commands.
*
* @author Adrian Cole
*/
@Test(groups = "performance", sequential = true, testName = "jclouds.BouncyCastleEncryptionServiceTest")
public class BouncyCastleEncryptionServiceTest extends EncryptionServiceTest {
@BeforeTest
protected void createEncryptionService() {
Injector i = Guice.createInjector();
encryptionService = i.getInstance(BouncyCastleEncryptionService.class);
}
}

View File

@ -40,6 +40,7 @@
<module>gae</module> <module>gae</module>
<module>httpnio</module> <module>httpnio</module>
<module>joda</module> <module>joda</module>
<module>bouncycastle</module>
<module>log4j</module> <module>log4j</module>
<module>ssh</module> <module>ssh</module>
</modules> </modules>

View File

@ -54,6 +54,7 @@ import org.jclouds.mezeo.pcs2.handlers.PCSClientErrorRetryHandler;
import org.jclouds.mezeo.pcs2.reference.PCSConstants; import org.jclouds.mezeo.pcs2.reference.PCSConstants;
import org.jclouds.rest.ConfiguresRestClient; import org.jclouds.rest.ConfiguresRestClient;
import org.jclouds.rest.RestClientFactory; import org.jclouds.rest.RestClientFactory;
import org.jclouds.util.EncryptionService;
import com.google.inject.AbstractModule; import com.google.inject.AbstractModule;
import com.google.inject.Provides; import com.google.inject.Provides;
@ -78,9 +79,9 @@ public class PCSRestClientModule extends AbstractModule {
@Singleton @Singleton
public BasicAuthentication provideBasicAuthentication( public BasicAuthentication provideBasicAuthentication(
@Named(PCSConstants.PROPERTY_PCS2_USER) String user, @Named(PCSConstants.PROPERTY_PCS2_USER) String user,
@Named(PCSConstants.PROPERTY_PCS2_PASSWORD) String password) @Named(PCSConstants.PROPERTY_PCS2_PASSWORD) String password,
throws UnsupportedEncodingException { EncryptionService encryptionService) throws UnsupportedEncodingException {
return new BasicAuthentication(user, password); return new BasicAuthentication(user, password, encryptionService);
} }
@Provides @Provides

View File

@ -59,6 +59,7 @@ import org.jclouds.mezeo.pcs2.xml.FileHandler;
import org.jclouds.rest.RestClientTest; import org.jclouds.rest.RestClientTest;
import org.jclouds.rest.internal.GeneratedHttpRequest; import org.jclouds.rest.internal.GeneratedHttpRequest;
import org.jclouds.rest.internal.RestAnnotationProcessor; import org.jclouds.rest.internal.RestAnnotationProcessor;
import org.jclouds.util.EncryptionService;
import org.testng.annotations.BeforeClass; import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test; import org.testng.annotations.Test;
@ -303,9 +304,9 @@ public class PCSClientTest extends RestClientTest<PCSAsyncClient> {
@SuppressWarnings("unused") @SuppressWarnings("unused")
@Provides @Provides
@Singleton @Singleton
public BasicAuthentication provideBasicAuthentication() public BasicAuthentication provideBasicAuthentication(EncryptionService encryptionService)
throws UnsupportedEncodingException { throws UnsupportedEncodingException {
return new BasicAuthentication("foo", "bar"); return new BasicAuthentication("foo", "bar", encryptionService);
} }
}; };

View File

@ -41,6 +41,7 @@ import org.jclouds.logging.Logger.LoggerFactory;
import org.jclouds.mezeo.pcs2.PCSCloud.Response; import org.jclouds.mezeo.pcs2.PCSCloud.Response;
import org.jclouds.rest.RestClientFactory; import org.jclouds.rest.RestClientFactory;
import org.jclouds.rest.config.RestModule; import org.jclouds.rest.config.RestModule;
import org.jclouds.util.EncryptionService;
import org.testng.annotations.BeforeClass; import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test; import org.testng.annotations.Test;
@ -94,9 +95,9 @@ public class PCSCloudLiveTest {
@SuppressWarnings("unused") @SuppressWarnings("unused")
@Provides @Provides
@Singleton @Singleton
public BasicAuthentication provideBasicAuthentication() public BasicAuthentication provideBasicAuthentication(EncryptionService encryptionService)
throws UnsupportedEncodingException { throws UnsupportedEncodingException {
return new BasicAuthentication(user, password); return new BasicAuthentication(user, password, encryptionService);
} }
@SuppressWarnings("unused") @SuppressWarnings("unused")

View File

@ -42,6 +42,7 @@ import org.jclouds.mezeo.pcs2.xml.CloudXlinkHandler;
import org.jclouds.rest.config.RestModule; import org.jclouds.rest.config.RestModule;
import org.jclouds.rest.internal.GeneratedHttpRequest; import org.jclouds.rest.internal.GeneratedHttpRequest;
import org.jclouds.rest.internal.RestAnnotationProcessor; import org.jclouds.rest.internal.RestAnnotationProcessor;
import org.jclouds.util.EncryptionService;
import org.testng.annotations.BeforeClass; import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test; import org.testng.annotations.Test;
@ -66,7 +67,8 @@ public class PCSCloudTest {
assertEquals(httpMethod.getRequestLine(), "GET http://localhost:8080/ HTTP/1.1"); assertEquals(httpMethod.getRequestLine(), "GET http://localhost:8080/ HTTP/1.1");
assertEquals(httpMethod.getHeaders().size(), 0); assertEquals(httpMethod.getHeaders().size(), 0);
assertEquals(processor.createResponseParser(method, httpMethod).getClass(), ParseSax.class); assertEquals(processor.createResponseParser(method, httpMethod).getClass(), ParseSax.class);
assertEquals(RestAnnotationProcessor.getSaxResponseParserClassOrNull(method), CloudXlinkHandler.class); assertEquals(RestAnnotationProcessor.getSaxResponseParserClassOrNull(method),
CloudXlinkHandler.class);
assertEquals(httpMethod.getFilters().size(), 1); assertEquals(httpMethod.getFilters().size(), 1);
assertEquals(httpMethod.getFilters().get(0).getClass(), BasicAuthentication.class); assertEquals(httpMethod.getFilters().get(0).getClass(), BasicAuthentication.class);
assertEquals(processor.createExceptionParserOrNullIfNotFound(method), null); assertEquals(processor.createExceptionParserOrNullIfNotFound(method), null);
@ -92,9 +94,9 @@ public class PCSCloudTest {
@SuppressWarnings("unused") @SuppressWarnings("unused")
@Provides @Provides
@Singleton @Singleton
public BasicAuthentication provideBasicAuthentication() public BasicAuthentication provideBasicAuthentication(EncryptionService encryptionService)
throws UnsupportedEncodingException { throws UnsupportedEncodingException {
return new BasicAuthentication("foo", "bar"); return new BasicAuthentication("foo", "bar", encryptionService);
} }
}, new RestModule(), new ExecutorServiceModule(new WithinThreadExecutorService()), }, new RestModule(), new ExecutorServiceModule(new WithinThreadExecutorService()),
new JavaUrlHttpCommandExecutorServiceModule()); new JavaUrlHttpCommandExecutorServiceModule());

View File

@ -34,9 +34,9 @@ import java.util.concurrent.TimeoutException;
import org.jclouds.blobstore.domain.Blob; import org.jclouds.blobstore.domain.Blob;
import org.jclouds.blobstore.integration.internal.BaseBlobStoreIntegrationTest; import org.jclouds.blobstore.integration.internal.BaseBlobStoreIntegrationTest;
import org.jclouds.http.HttpUtils;
import org.jclouds.logging.log4j.config.Log4JLoggingModule; import org.jclouds.logging.log4j.config.Log4JLoggingModule;
import org.jclouds.nirvanix.sdn.domain.UploadInfo; import org.jclouds.nirvanix.sdn.domain.UploadInfo;
import org.jclouds.util.internal.Base64;
import org.testng.annotations.BeforeGroups; import org.testng.annotations.BeforeGroups;
import org.testng.annotations.Test; import org.testng.annotations.Test;
@ -85,7 +85,7 @@ public class SDNClientLiveTest {
connection.upload(uploadInfo.getHost(), uploadInfo.getToken(), containerName, blob); connection.upload(uploadInfo.getHost(), uploadInfo.getToken(), containerName, blob);
Map<String, String> metadata = connection.getMetadata(containerName + "/test.txt"); Map<String, String> metadata = connection.getMetadata(containerName + "/test.txt");
assertEquals(metadata.get("MD5"), HttpUtils.toBase64String(md5)); assertEquals(metadata.get("MD5"), Base64.encodeBytes(md5));
String content = connection.getFile(containerName + "/test.txt"); String content = connection.getFile(containerName + "/test.txt");
assertEquals(content, "value"); assertEquals(content, "value");
@ -94,7 +94,7 @@ public class SDNClientLiveTest {
connection.setMetadata(containerName + "/test.txt", metadata); connection.setMetadata(containerName + "/test.txt", metadata);
metadata = connection.getMetadata(containerName + "/test.txt"); metadata = connection.getMetadata(containerName + "/test.txt");
assertEquals(metadata.get("MD5"), HttpUtils.toBase64String(md5)); assertEquals(metadata.get("MD5"), Base64.encodeBytes(md5));
} }
} }

View File

@ -31,19 +31,22 @@ import javax.ws.rs.core.HttpHeaders;
import org.jclouds.blobstore.binders.BindBlobToEntityAndUserMetadataToHeadersWithPrefix; import org.jclouds.blobstore.binders.BindBlobToEntityAndUserMetadataToHeadersWithPrefix;
import org.jclouds.http.HttpRequest; import org.jclouds.http.HttpRequest;
import org.jclouds.http.HttpUtils;
import org.jclouds.rackspace.cloudfiles.blobstore.functions.ObjectToBlob; import org.jclouds.rackspace.cloudfiles.blobstore.functions.ObjectToBlob;
import org.jclouds.rackspace.cloudfiles.domain.CFObject; import org.jclouds.rackspace.cloudfiles.domain.CFObject;
import org.jclouds.rackspace.cloudfiles.reference.CloudFilesConstants; import org.jclouds.rackspace.cloudfiles.reference.CloudFilesConstants;
import org.jclouds.util.EncryptionService;
public class BindCFObjectToEntity extends BindBlobToEntityAndUserMetadataToHeadersWithPrefix { public class BindCFObjectToEntity extends BindBlobToEntityAndUserMetadataToHeadersWithPrefix {
private final ObjectToBlob object2Blob; private final ObjectToBlob object2Blob;
private final EncryptionService encryptionService;
@Inject @Inject
public BindCFObjectToEntity(ObjectToBlob object2Blob, public BindCFObjectToEntity(ObjectToBlob object2Blob,
@Named(CloudFilesConstants.PROPERTY_CLOUDFILES_METADATA_PREFIX) String prefix) { @Named(CloudFilesConstants.PROPERTY_CLOUDFILES_METADATA_PREFIX) String prefix,
super(prefix); EncryptionService encryptionService) {
super(prefix, encryptionService);
this.object2Blob = object2Blob; this.object2Blob = object2Blob;
this.encryptionService = encryptionService;
} }
public void bindToRequest(HttpRequest request, Object entity) { public void bindToRequest(HttpRequest request, Object entity) {
@ -60,7 +63,7 @@ public class BindCFObjectToEntity extends BindBlobToEntityAndUserMetadataToHeade
super.bindToRequest(request, object2Blob.apply(object)); super.bindToRequest(request, object2Blob.apply(object));
if (object.getInfo().getHash() != null) { if (object.getInfo().getHash() != null) {
request.getHeaders().put(HttpHeaders.ETAG, request.getHeaders().put(HttpHeaders.ETAG,
HttpUtils.toHexString(object.getInfo().getHash())); encryptionService.toHexString(object.getInfo().getHash()));
request.getHeaders().removeAll("Content-MD5"); request.getHeaders().removeAll("Content-MD5");
} }

View File

@ -30,9 +30,9 @@ import org.jclouds.blobstore.domain.MutableBlobMetadata;
import org.jclouds.blobstore.domain.ResourceType; import org.jclouds.blobstore.domain.ResourceType;
import org.jclouds.blobstore.domain.internal.MutableBlobMetadataImpl; import org.jclouds.blobstore.domain.internal.MutableBlobMetadataImpl;
import org.jclouds.blobstore.strategy.IsDirectoryStrategy; import org.jclouds.blobstore.strategy.IsDirectoryStrategy;
import org.jclouds.http.HttpUtils;
import org.jclouds.rackspace.cloudfiles.domain.MutableObjectInfoWithMetadata; import org.jclouds.rackspace.cloudfiles.domain.MutableObjectInfoWithMetadata;
import org.jclouds.rackspace.cloudfiles.domain.ObjectInfo; import org.jclouds.rackspace.cloudfiles.domain.ObjectInfo;
import org.jclouds.util.EncryptionService;
import com.google.common.base.Function; import com.google.common.base.Function;
@ -42,10 +42,13 @@ import com.google.common.base.Function;
@Singleton @Singleton
public class ObjectToBlobMetadata implements Function<ObjectInfo, MutableBlobMetadata> { public class ObjectToBlobMetadata implements Function<ObjectInfo, MutableBlobMetadata> {
private final IsDirectoryStrategy isDirectoryStrategy; private final IsDirectoryStrategy isDirectoryStrategy;
private final EncryptionService encryptionService;
@Inject @Inject
public ObjectToBlobMetadata(IsDirectoryStrategy isDirectoryStrategy) { public ObjectToBlobMetadata(IsDirectoryStrategy isDirectoryStrategy,
EncryptionService encryptionService) {
this.isDirectoryStrategy = isDirectoryStrategy; this.isDirectoryStrategy = isDirectoryStrategy;
this.encryptionService = encryptionService;
} }
public MutableBlobMetadata apply(ObjectInfo from) { public MutableBlobMetadata apply(ObjectInfo from) {
@ -54,7 +57,7 @@ public class ObjectToBlobMetadata implements Function<ObjectInfo, MutableBlobMet
if (from.getContentType() != null) if (from.getContentType() != null)
to.setContentType(from.getContentType()); to.setContentType(from.getContentType());
if (from.getHash() != null) if (from.getHash() != null)
to.setETag(HttpUtils.toHexString(from.getHash())); to.setETag(encryptionService.toHexString(from.getHash()));
to.setName(from.getName()); to.setName(from.getName());
if (from.getBytes() != null) if (from.getBytes() != null)
to.setSize(from.getBytes()); to.setSize(from.getBytes());

View File

@ -23,14 +23,15 @@
*/ */
package org.jclouds.rackspace.cloudfiles.blobstore.functions; package org.jclouds.rackspace.cloudfiles.blobstore.functions;
import javax.inject.Inject;
import javax.inject.Singleton; import javax.inject.Singleton;
import org.jclouds.blobstore.domain.BlobMetadata; import org.jclouds.blobstore.domain.BlobMetadata;
import org.jclouds.blobstore.domain.ResourceMetadata; import org.jclouds.blobstore.domain.ResourceMetadata;
import org.jclouds.blobstore.domain.ResourceType; import org.jclouds.blobstore.domain.ResourceType;
import org.jclouds.http.HttpUtils;
import org.jclouds.rackspace.cloudfiles.domain.MutableObjectInfoWithMetadata; import org.jclouds.rackspace.cloudfiles.domain.MutableObjectInfoWithMetadata;
import org.jclouds.rackspace.cloudfiles.domain.internal.MutableObjectInfoWithMetadataImpl; import org.jclouds.rackspace.cloudfiles.domain.internal.MutableObjectInfoWithMetadataImpl;
import org.jclouds.util.EncryptionService;
import com.google.common.base.Function; import com.google.common.base.Function;
@ -38,7 +39,15 @@ import com.google.common.base.Function;
* @author Adrian Cole * @author Adrian Cole
*/ */
@Singleton @Singleton
public class ResourceToObjectInfo implements Function<ResourceMetadata, MutableObjectInfoWithMetadata> { public class ResourceToObjectInfo implements
Function<ResourceMetadata, MutableObjectInfoWithMetadata> {
private final EncryptionService encryptionService;
@Inject
public ResourceToObjectInfo(EncryptionService encryptionService) {
this.encryptionService = encryptionService;
}
public MutableObjectInfoWithMetadata apply(ResourceMetadata base) { public MutableObjectInfoWithMetadata apply(ResourceMetadata base) {
MutableObjectInfoWithMetadata to = new MutableObjectInfoWithMetadataImpl(); MutableObjectInfoWithMetadata to = new MutableObjectInfoWithMetadataImpl();
if (base.getType() == ResourceType.BLOB) { if (base.getType() == ResourceType.BLOB) {
@ -48,7 +57,7 @@ public class ResourceToObjectInfo implements Function<ResourceMetadata, MutableO
to.setContentType("application/directory"); to.setContentType("application/directory");
} }
if (base.getETag() != null && to.getHash() == null) if (base.getETag() != null && to.getHash() == null)
to.setHash(HttpUtils.fromHexString(base.getETag())); to.setHash(encryptionService.fromHexString(base.getETag()));
to.setName(base.getName()); to.setName(base.getName());
to.setLastModified(base.getLastModified()); to.setLastModified(base.getLastModified());
if (base.getSize() != null) if (base.getSize() != null)

View File

@ -28,11 +28,11 @@ import javax.inject.Inject;
import org.jclouds.blobstore.domain.BlobMetadata; import org.jclouds.blobstore.domain.BlobMetadata;
import org.jclouds.blobstore.functions.ParseSystemAndUserMetadataFromHeaders; import org.jclouds.blobstore.functions.ParseSystemAndUserMetadataFromHeaders;
import org.jclouds.http.HttpResponse; import org.jclouds.http.HttpResponse;
import org.jclouds.http.HttpUtils;
import org.jclouds.rackspace.cloudfiles.blobstore.functions.ResourceToObjectInfo; import org.jclouds.rackspace.cloudfiles.blobstore.functions.ResourceToObjectInfo;
import org.jclouds.rackspace.cloudfiles.domain.MutableObjectInfoWithMetadata; import org.jclouds.rackspace.cloudfiles.domain.MutableObjectInfoWithMetadata;
import org.jclouds.rest.InvocationContext; import org.jclouds.rest.InvocationContext;
import org.jclouds.rest.internal.GeneratedHttpRequest; import org.jclouds.rest.internal.GeneratedHttpRequest;
import org.jclouds.util.EncryptionService;
import com.google.common.base.Function; import com.google.common.base.Function;
@ -45,12 +45,14 @@ public class ParseObjectInfoFromHeaders implements
Function<HttpResponse, MutableObjectInfoWithMetadata>, InvocationContext { Function<HttpResponse, MutableObjectInfoWithMetadata>, InvocationContext {
private final ParseSystemAndUserMetadataFromHeaders blobMetadataParser; private final ParseSystemAndUserMetadataFromHeaders blobMetadataParser;
private final ResourceToObjectInfo blobToObjectInfo; private final ResourceToObjectInfo blobToObjectInfo;
private final EncryptionService encryptionService;
@Inject @Inject
public ParseObjectInfoFromHeaders(ParseSystemAndUserMetadataFromHeaders blobMetadataParser, public ParseObjectInfoFromHeaders(ParseSystemAndUserMetadataFromHeaders blobMetadataParser,
ResourceToObjectInfo blobToObjectInfo) { ResourceToObjectInfo blobToObjectInfo, EncryptionService encryptionService) {
this.blobMetadataParser = blobMetadataParser; this.blobMetadataParser = blobMetadataParser;
this.blobToObjectInfo = blobToObjectInfo; this.blobToObjectInfo = blobToObjectInfo;
this.encryptionService = encryptionService;
} }
/** /**
@ -61,7 +63,7 @@ public class ParseObjectInfoFromHeaders implements
MutableObjectInfoWithMetadata to = blobToObjectInfo.apply(base); MutableObjectInfoWithMetadata to = blobToObjectInfo.apply(base);
String eTagHeader = from.getFirstHeaderOrNull("Etag"); String eTagHeader = from.getFirstHeaderOrNull("Etag");
if (eTagHeader != null) { if (eTagHeader != null) {
to.setHash(HttpUtils.fromHexString(eTagHeader.replaceAll("\"", ""))); to.setHash(encryptionService.fromHexString(eTagHeader.replaceAll("\"", "")));
} }
return to; return to;
} }

View File

@ -37,12 +37,12 @@ import javax.inject.Inject;
import org.jclouds.blobstore.domain.ListContainerResponse; import org.jclouds.blobstore.domain.ListContainerResponse;
import org.jclouds.blobstore.domain.internal.ListContainerResponseImpl; import org.jclouds.blobstore.domain.internal.ListContainerResponseImpl;
import org.jclouds.http.HttpUtils;
import org.jclouds.http.functions.ParseJson; import org.jclouds.http.functions.ParseJson;
import org.jclouds.rackspace.cloudfiles.domain.ObjectInfo; import org.jclouds.rackspace.cloudfiles.domain.ObjectInfo;
import org.jclouds.rackspace.cloudfiles.options.ListContainerOptions; import org.jclouds.rackspace.cloudfiles.options.ListContainerOptions;
import org.jclouds.rest.InvocationContext; import org.jclouds.rest.InvocationContext;
import org.jclouds.rest.internal.GeneratedHttpRequest; import org.jclouds.rest.internal.GeneratedHttpRequest;
import org.jclouds.util.EncryptionService;
import com.google.common.base.Function; import com.google.common.base.Function;
import com.google.common.collect.Iterables; import com.google.common.collect.Iterables;
@ -59,10 +59,12 @@ public class ParseObjectInfoListFromJsonResponse extends
ParseJson<ListContainerResponse<ObjectInfo>> implements InvocationContext { ParseJson<ListContainerResponse<ObjectInfo>> implements InvocationContext {
private GeneratedHttpRequest<?> request; private GeneratedHttpRequest<?> request;
private static EncryptionService encryptionService;
@Inject @Inject
public ParseObjectInfoListFromJsonResponse(Gson gson) { public ParseObjectInfoListFromJsonResponse(Gson gson, EncryptionService encryptionService) {
super(gson); super(gson);
ParseObjectInfoListFromJsonResponse.encryptionService = encryptionService;
} }
public static class ObjectInfoImpl implements ObjectInfo { public static class ObjectInfoImpl implements ObjectInfo {
@ -85,7 +87,7 @@ public class ParseObjectInfoListFromJsonResponse extends
} }
public byte[] getHash() { public byte[] getHash() {
return HttpUtils.fromHexString(hash); return encryptionService.fromHexString(hash);
} }
public Date getLastModified() { public Date getLastModified() {

View File

@ -33,9 +33,9 @@ import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import org.jclouds.http.HttpRequest; import org.jclouds.http.HttpRequest;
import org.jclouds.http.HttpUtils;
import org.jclouds.rackspace.cloudservers.domain.Addresses; import org.jclouds.rackspace.cloudservers.domain.Addresses;
import org.jclouds.rest.binders.BindToJsonEntity; import org.jclouds.rest.binders.BindToJsonEntity;
import org.jclouds.util.internal.Base64;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import com.google.inject.internal.Lists; import com.google.inject.internal.Lists;
@ -54,7 +54,7 @@ public class CreateServerOptions extends BindToJsonEntity {
public File(String path, byte[] contents) { public File(String path, byte[] contents) {
this.path = checkNotNull(path, "path"); this.path = checkNotNull(path, "path");
this.contents = HttpUtils.toBase64String(checkNotNull(contents, "contents")); this.contents = Base64.encodeBytes(checkNotNull(contents, "contents"));
checkArgument(path.getBytes().length < 255, String.format( checkArgument(path.getBytes().length < 255, String.format(
"maximum length of path is 255 bytes. Path specified %s is %d bytes", path, path "maximum length of path is 255 bytes. Path specified %s is %d bytes", path, path
.getBytes().length)); .getBytes().length));

View File

@ -44,7 +44,6 @@ import org.jclouds.blobstore.KeyNotFoundException;
import org.jclouds.blobstore.domain.ListResponse; import org.jclouds.blobstore.domain.ListResponse;
import org.jclouds.blobstore.integration.internal.BaseBlobStoreIntegrationTest; import org.jclouds.blobstore.integration.internal.BaseBlobStoreIntegrationTest;
import org.jclouds.http.HttpResponseException; import org.jclouds.http.HttpResponseException;
import org.jclouds.http.HttpUtils;
import org.jclouds.http.options.GetOptions; import org.jclouds.http.options.GetOptions;
import org.jclouds.rackspace.cloudfiles.domain.AccountMetadata; import org.jclouds.rackspace.cloudfiles.domain.AccountMetadata;
import org.jclouds.rackspace.cloudfiles.domain.CFObject; import org.jclouds.rackspace.cloudfiles.domain.CFObject;
@ -54,6 +53,8 @@ import org.jclouds.rackspace.cloudfiles.domain.MutableObjectInfoWithMetadata;
import org.jclouds.rackspace.cloudfiles.domain.ObjectInfo; import org.jclouds.rackspace.cloudfiles.domain.ObjectInfo;
import org.jclouds.rackspace.cloudfiles.options.ListCdnContainerOptions; import org.jclouds.rackspace.cloudfiles.options.ListCdnContainerOptions;
import org.jclouds.rackspace.cloudfiles.options.ListContainerOptions; import org.jclouds.rackspace.cloudfiles.options.ListContainerOptions;
import org.jclouds.util.EncryptionService;
import org.jclouds.util.internal.JCEEncryptionService;
import org.testng.annotations.Test; import org.testng.annotations.Test;
import com.google.common.base.Predicate; import com.google.common.base.Predicate;
@ -68,6 +69,7 @@ import com.google.common.collect.Maps;
@Test(groups = "live", testName = "cloudfiles.CloudFilesClientLiveTest") @Test(groups = "live", testName = "cloudfiles.CloudFilesClientLiveTest")
public class CloudFilesClientLiveTest extends public class CloudFilesClientLiveTest extends
BaseBlobStoreIntegrationTest<CloudFilesAsyncClient, CloudFilesClient> { BaseBlobStoreIntegrationTest<CloudFilesAsyncClient, CloudFilesClient> {
private static final EncryptionService encryptionService = new JCEEncryptionService();
/** /**
* this method overrides containerName to ensure it isn't found * this method overrides containerName to ensure it isn't found
@ -307,7 +309,8 @@ public class CloudFilesClientLiveTest extends
CFObject object = newCFObject(data, key); CFObject object = newCFObject(data, key);
byte[] md5 = object.getInfo().getHash(); byte[] md5 = object.getInfo().getHash();
String newEtag = context.getApi().putObject(containerName, object); String newEtag = context.getApi().putObject(containerName, object);
assertEquals(HttpUtils.toHexString(md5), HttpUtils.toHexString(object.getInfo().getHash())); assertEquals(encryptionService.toHexString(md5), encryptionService.toHexString(object
.getInfo().getHash()));
// Test HEAD of missing object // Test HEAD of missing object
try { try {
@ -322,8 +325,9 @@ public class CloudFilesClientLiveTest extends
// TODO assertEquals(metadata.getName(), object.getMetadata().getName()); // TODO assertEquals(metadata.getName(), object.getMetadata().getName());
assertEquals(metadata.getBytes(), new Long(data.length())); assertEquals(metadata.getBytes(), new Long(data.length()));
assertEquals(metadata.getContentType(), "text/plain"); assertEquals(metadata.getContentType(), "text/plain");
assertEquals(HttpUtils.toHexString(md5), HttpUtils.toHexString(object.getInfo().getHash())); assertEquals(encryptionService.toHexString(md5), encryptionService.toHexString(object
assertEquals(metadata.getHash(), HttpUtils.fromHexString(newEtag)); .getInfo().getHash()));
assertEquals(metadata.getHash(), encryptionService.fromHexString(newEtag));
assertEquals(metadata.getMetadata().entrySet().size(), 1); assertEquals(metadata.getMetadata().entrySet().size(), 1);
assertEquals(metadata.getMetadata().get("metadata"), "metadata-value"); assertEquals(metadata.getMetadata().get("metadata"), "metadata-value");
@ -346,9 +350,9 @@ public class CloudFilesClientLiveTest extends
// TODO assertEquals(getBlob.getName(), object.getMetadata().getName()); // TODO assertEquals(getBlob.getName(), object.getMetadata().getName());
assertEquals(getBlob.getContentLength(), new Long(data.length())); assertEquals(getBlob.getContentLength(), new Long(data.length()));
assertEquals(getBlob.getInfo().getContentType(), "text/plain"); assertEquals(getBlob.getInfo().getContentType(), "text/plain");
assertEquals(HttpUtils.toHexString(md5), HttpUtils assertEquals(encryptionService.toHexString(md5), encryptionService.toHexString(getBlob
.toHexString(getBlob.getInfo().getHash())); .getInfo().getHash()));
assertEquals(HttpUtils.fromHexString(newEtag), getBlob.getInfo().getHash()); assertEquals(encryptionService.fromHexString(newEtag), getBlob.getInfo().getHash());
assertEquals(getBlob.getInfo().getMetadata().entrySet().size(), 2); assertEquals(getBlob.getInfo().getMetadata().entrySet().size(), 2);
assertEquals(getBlob.getInfo().getMetadata().get("new-metadata-1"), "value-1"); assertEquals(getBlob.getInfo().getMetadata().get("new-metadata-1"), "value-1");
assertEquals(getBlob.getInfo().getMetadata().get("new-metadata-2"), "value-2"); assertEquals(getBlob.getInfo().getMetadata().get("new-metadata-2"), "value-2");
@ -356,7 +360,7 @@ public class CloudFilesClientLiveTest extends
// Test PUT with invalid ETag (as if object's data was corrupted in transit) // Test PUT with invalid ETag (as if object's data was corrupted in transit)
String correctEtag = newEtag; String correctEtag = newEtag;
String incorrectEtag = "0" + correctEtag.substring(1); String incorrectEtag = "0" + correctEtag.substring(1);
object.getInfo().setHash(HttpUtils.fromHexString(incorrectEtag)); object.getInfo().setHash(encryptionService.fromHexString(incorrectEtag));
try { try {
context.getApi().putObject(containerName, object); context.getApi().putObject(containerName, object);
} catch (HttpResponseException e) { } catch (HttpResponseException e) {
@ -369,8 +373,8 @@ public class CloudFilesClientLiveTest extends
blob.getInfo().setName("chunked-object"); blob.getInfo().setName("chunked-object");
blob.setData(bais); blob.setData(bais);
newEtag = context.getApi().putObject(containerName, blob); newEtag = context.getApi().putObject(containerName, blob);
assertEquals(HttpUtils.toHexString(md5), HttpUtils assertEquals(encryptionService.toHexString(md5), encryptionService.toHexString(getBlob
.toHexString(getBlob.getInfo().getHash())); .getInfo().getHash()));
// Test GET with options // Test GET with options
// Non-matching ETag // Non-matching ETag
@ -384,7 +388,7 @@ public class CloudFilesClientLiveTest extends
// Matching ETag // Matching ETag
getBlob = context.getApi().getObject(containerName, object.getInfo().getName(), getBlob = context.getApi().getObject(containerName, object.getInfo().getName(),
GetOptions.Builder.ifETagMatches(newEtag)); GetOptions.Builder.ifETagMatches(newEtag));
assertEquals(getBlob.getInfo().getHash(), HttpUtils.fromHexString(newEtag)); assertEquals(getBlob.getInfo().getHash(), encryptionService.fromHexString(newEtag));
getBlob = context.getApi().getObject(containerName, object.getInfo().getName(), getBlob = context.getApi().getObject(containerName, object.getInfo().getName(),
GetOptions.Builder.startAt(8)); GetOptions.Builder.startAt(8));
assertEquals(IOUtils.toString((InputStream) getBlob.getData()), data.substring(8)); assertEquals(IOUtils.toString((InputStream) getBlob.getData()), data.substring(8));

View File

@ -23,23 +23,27 @@
*/ */
package org.jclouds.rimuhosting.miro; package org.jclouds.rimuhosting.miro;
import com.google.inject.AbstractModule; import static org.testng.Assert.assertEquals;
import com.google.inject.Module;
import com.google.inject.Provides; import java.io.IOException;
import com.google.inject.TypeLiteral; import java.io.UnsupportedEncodingException;
import java.net.URI;
import javax.inject.Singleton;
import org.jclouds.http.filters.BasicAuthentication; import org.jclouds.http.filters.BasicAuthentication;
import org.jclouds.logging.Logger; import org.jclouds.logging.Logger;
import org.jclouds.logging.Logger.LoggerFactory; import org.jclouds.logging.Logger.LoggerFactory;
import org.jclouds.rest.RestClientTest; import org.jclouds.rest.RestClientTest;
import org.jclouds.rest.internal.GeneratedHttpRequest; import org.jclouds.rest.internal.GeneratedHttpRequest;
import org.jclouds.rest.internal.RestAnnotationProcessor; import org.jclouds.rest.internal.RestAnnotationProcessor;
import static org.testng.Assert.assertEquals; import org.jclouds.util.EncryptionService;
import org.testng.annotations.Test; import org.testng.annotations.Test;
import javax.inject.Singleton; import com.google.inject.AbstractModule;
import java.io.IOException; import com.google.inject.Module;
import java.io.UnsupportedEncodingException; import com.google.inject.Provides;
import java.net.URI; import com.google.inject.TypeLiteral;
/** /**
* Tests annotation parsing of {@code RimuHostingAsyncClient} * Tests annotation parsing of {@code RimuHostingAsyncClient}
@ -50,18 +54,19 @@ import java.net.URI;
public class RimuHostingAsyncClientTest extends RestClientTest<RimuHostingAsyncClient> { public class RimuHostingAsyncClientTest extends RestClientTest<RimuHostingAsyncClient> {
public void testGetMyMentions() throws SecurityException, NoSuchMethodException, IOException { public void testGetMyMentions() throws SecurityException, NoSuchMethodException, IOException {
/* Method method = RimuHostingAsyncClient.class.getMethod("TODO: insert test method name"); /*
GeneratedHttpRequest<RimuHostingAsyncClient> httpMethod = processor.createRequest(method); * Method method = RimuHostingAsyncClient.class.getMethod("TODO: insert test method name");
* GeneratedHttpRequest<RimuHostingAsyncClient> httpMethod = processor.createRequest(method);
assertRequestLineEquals(httpMethod, "TODO: insert expected request"); *
assertHeadersEqual(httpMethod, ""); * assertRequestLineEquals(httpMethod, "TODO: insert expected request");
assertEntityEquals(httpMethod, null); * assertHeadersEqual(httpMethod, ""); assertEntityEquals(httpMethod, null);
*
assertResponseParserClassEquals(method, httpMethod, ParseStatusesFromJsonResponse.class); * assertResponseParserClassEquals(method, httpMethod, ParseStatusesFromJsonResponse.class);
assertSaxResponseParserClassEquals(method, null); * assertSaxResponseParserClassEquals(method, null); assertExceptionParserClassEquals(method,
assertExceptionParserClassEquals(method, null); * null);
*
checkFilters(httpMethod);*/ * checkFilters(httpMethod);
*/
} }
@Override @Override
@ -93,9 +98,9 @@ public class RimuHostingAsyncClientTest extends RestClientTest<RimuHostingAsyncC
@SuppressWarnings("unused") @SuppressWarnings("unused")
@Provides @Provides
@Singleton @Singleton
public BasicAuthentication provideBasicAuthentication() public BasicAuthentication provideBasicAuthentication(EncryptionService encryptionService)
throws UnsupportedEncodingException { throws UnsupportedEncodingException {
return new BasicAuthentication("foo", "bar"); return new BasicAuthentication("foo", "bar", encryptionService);
} }
}; };

View File

@ -38,6 +38,7 @@ import org.jclouds.twitter.Twitter;
import org.jclouds.twitter.TwitterAsyncClient; import org.jclouds.twitter.TwitterAsyncClient;
import org.jclouds.twitter.TwitterClient; import org.jclouds.twitter.TwitterClient;
import org.jclouds.twitter.reference.TwitterConstants; import org.jclouds.twitter.reference.TwitterConstants;
import org.jclouds.util.EncryptionService;
import com.google.inject.AbstractModule; import com.google.inject.AbstractModule;
import com.google.inject.Provides; import com.google.inject.Provides;
@ -61,9 +62,9 @@ public class TwitterRestClientModule extends AbstractModule {
@Singleton @Singleton
public BasicAuthentication provideBasicAuthentication( public BasicAuthentication provideBasicAuthentication(
@Named(TwitterConstants.PROPERTY_TWITTER_USER) String user, @Named(TwitterConstants.PROPERTY_TWITTER_USER) String user,
@Named(TwitterConstants.PROPERTY_TWITTER_PASSWORD) String password) @Named(TwitterConstants.PROPERTY_TWITTER_PASSWORD) String password,
throws UnsupportedEncodingException { EncryptionService encryptionService) throws UnsupportedEncodingException {
return new BasicAuthentication(user, password); return new BasicAuthentication(user, password, encryptionService);
} }
@Provides @Provides

View File

@ -39,6 +39,7 @@ import org.jclouds.rest.RestClientTest;
import org.jclouds.rest.internal.GeneratedHttpRequest; import org.jclouds.rest.internal.GeneratedHttpRequest;
import org.jclouds.rest.internal.RestAnnotationProcessor; import org.jclouds.rest.internal.RestAnnotationProcessor;
import org.jclouds.twitter.functions.ParseStatusesFromJsonResponse; import org.jclouds.twitter.functions.ParseStatusesFromJsonResponse;
import org.jclouds.util.EncryptionService;
import org.testng.annotations.Test; import org.testng.annotations.Test;
import com.google.inject.AbstractModule; import com.google.inject.AbstractModule;
@ -98,9 +99,9 @@ public class TwitterClientTest extends RestClientTest<TwitterAsyncClient> {
@SuppressWarnings("unused") @SuppressWarnings("unused")
@Provides @Provides
@Singleton @Singleton
public BasicAuthentication provideBasicAuthentication() public BasicAuthentication provideBasicAuthentication(EncryptionService encryptionService)
throws UnsupportedEncodingException { throws UnsupportedEncodingException {
return new BasicAuthentication("foo", "bar"); return new BasicAuthentication("foo", "bar", encryptionService);
} }
}; };

View File

@ -43,6 +43,7 @@ import org.jclouds.http.RequiresHttp;
import org.jclouds.http.filters.BasicAuthentication; import org.jclouds.http.filters.BasicAuthentication;
import org.jclouds.rest.ConfiguresRestClient; import org.jclouds.rest.ConfiguresRestClient;
import org.jclouds.rest.RestClientFactory; import org.jclouds.rest.RestClientFactory;
import org.jclouds.util.EncryptionService;
import org.jclouds.util.Utils; import org.jclouds.util.Utils;
import org.jclouds.vcloud.VCloudDiscovery; import org.jclouds.vcloud.VCloudDiscovery;
import org.jclouds.vcloud.VCloudLogin; import org.jclouds.vcloud.VCloudLogin;
@ -147,8 +148,9 @@ public class VCloudDiscoveryRestClientModule extends AbstractModule {
@Provides @Provides
@Singleton @Singleton
public BasicAuthentication provideBasicAuthentication(@Named(PROPERTY_VCLOUD_USER) String user, public BasicAuthentication provideBasicAuthentication(@Named(PROPERTY_VCLOUD_USER) String user,
@Named(PROPERTY_VCLOUD_KEY) String key) throws UnsupportedEncodingException { @Named(PROPERTY_VCLOUD_KEY) String key, EncryptionService encryptionService)
return new BasicAuthentication(user, key); throws UnsupportedEncodingException {
return new BasicAuthentication(user, key, encryptionService);
} }
} }

View File

@ -38,6 +38,7 @@ import org.jclouds.logging.Logger.LoggerFactory;
import org.jclouds.rest.RestClientTest; import org.jclouds.rest.RestClientTest;
import org.jclouds.rest.internal.GeneratedHttpRequest; import org.jclouds.rest.internal.GeneratedHttpRequest;
import org.jclouds.rest.internal.RestAnnotationProcessor; import org.jclouds.rest.internal.RestAnnotationProcessor;
import org.jclouds.util.internal.JCEEncryptionService;
import org.jclouds.vcloud.functions.ParseLoginResponseFromHeaders; import org.jclouds.vcloud.functions.ParseLoginResponseFromHeaders;
import org.testng.annotations.Test; import org.testng.annotations.Test;
@ -58,7 +59,8 @@ public class VCloudLoginTest extends RestClientTest<VCloudLogin> {
GeneratedHttpRequest<VCloudLogin> httpMethod = processor.createRequest(method); GeneratedHttpRequest<VCloudLogin> httpMethod = processor.createRequest(method);
assertEquals(httpMethod.getRequestLine(), "POST http://localhost:8080/login HTTP/1.1"); assertEquals(httpMethod.getRequestLine(), "POST http://localhost:8080/login HTTP/1.1");
assertHeadersEqual(httpMethod, HttpHeaders.ACCEPT + ": application/vnd.vmware.vcloud.organizationList+xml\n"); assertHeadersEqual(httpMethod, HttpHeaders.ACCEPT
+ ": application/vnd.vmware.vcloud.organizationList+xml\n");
assertEntityEquals(httpMethod, null); assertEntityEquals(httpMethod, null);
assertResponseParserClassEquals(method, httpMethod, ParseLoginResponseFromHeaders.class); assertResponseParserClassEquals(method, httpMethod, ParseLoginResponseFromHeaders.class);
@ -88,7 +90,8 @@ public class VCloudLoginTest extends RestClientTest<VCloudLogin> {
bind(URI.class).annotatedWith(org.jclouds.vcloud.endpoints.VCloudLogin.class) bind(URI.class).annotatedWith(org.jclouds.vcloud.endpoints.VCloudLogin.class)
.toInstance(URI.create("http://localhost:8080/login")); .toInstance(URI.create("http://localhost:8080/login"));
try { try {
bind(BasicAuthentication.class).toInstance(new BasicAuthentication("user", "pass")); bind(BasicAuthentication.class).toInstance(
new BasicAuthentication("user", "pass", new JCEEncryptionService()));
} catch (UnsupportedEncodingException e) { } catch (UnsupportedEncodingException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }