mirror of https://github.com/apache/jclouds.git
refactored encryption service and exposed sha256 routine
This commit is contained in:
parent
2dda46696a
commit
204c093753
|
@ -53,7 +53,7 @@ public class BindAtmosObjectToPayloadAndMetadataToHeaders implements Binder {
|
||||||
|
|
||||||
if (object.getContentMetadata().getContentMD5() != null) {
|
if (object.getContentMetadata().getContentMD5() != null) {
|
||||||
request.getHeaders().put("Content-MD5",
|
request.getHeaders().put("Content-MD5",
|
||||||
encryptionService.toBase64String(object.getContentMetadata().getContentMD5()));
|
encryptionService.base64(object.getContentMetadata().getContentMD5()));
|
||||||
}
|
}
|
||||||
metaBinder.bindToRequest(request, object.getUserMetadata());
|
metaBinder.bindToRequest(request, object.getUserMetadata());
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,7 +77,7 @@ public class SignRequest implements HttpRequestFilter {
|
||||||
@TimeStamp Provider<String> timeStampProvider, EncryptionService encryptionService) {
|
@TimeStamp Provider<String> timeStampProvider, EncryptionService encryptionService) {
|
||||||
this.signatureWire = signatureWire;
|
this.signatureWire = signatureWire;
|
||||||
this.uid = uid;
|
this.uid = uid;
|
||||||
this.key = encryptionService.fromBase64String(encodedKey);
|
this.key = encryptionService.fromBase64(encodedKey);
|
||||||
this.timeStampProvider = timeStampProvider;
|
this.timeStampProvider = timeStampProvider;
|
||||||
this.encryptionService = encryptionService;
|
this.encryptionService = encryptionService;
|
||||||
}
|
}
|
||||||
|
@ -119,7 +119,7 @@ public class SignRequest implements HttpRequestFilter {
|
||||||
public String signString(String toSign) {
|
public String signString(String toSign) {
|
||||||
String signature;
|
String signature;
|
||||||
try {
|
try {
|
||||||
signature = encryptionService.hmacSha1Base64(toSign, key);
|
signature = encryptionService.base64(encryptionService.hmacSha1(toSign, key));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new HttpException("error signing request", e);
|
throw new HttpException("error signing request", e);
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,7 +60,7 @@ public class ParseSystemMetadataFromHeaders implements Function<HttpResponse, Sy
|
||||||
metaMap.put(entrySplit[0], entrySplit[1]);
|
metaMap.put(entrySplit[0], entrySplit[1]);
|
||||||
}
|
}
|
||||||
assert metaMap.size() >= 12 : String.format("Should be 12 entries in %s", metaMap);
|
assert metaMap.size() >= 12 : String.format("Should be 12 entries in %s", metaMap);
|
||||||
byte[] md5 = metaMap.containsKey("content-md5") ? encryptionService.fromHexString(metaMap
|
byte[] md5 = metaMap.containsKey("content-md5") ? encryptionService.fromHex(metaMap
|
||||||
.get("content-md5")) : null;
|
.get("content-md5")) : null;
|
||||||
return new SystemMetadata(md5, dateService.iso8601SecondsDateParse(checkNotNull(metaMap
|
return new SystemMetadata(md5, dateService.iso8601SecondsDateParse(checkNotNull(metaMap
|
||||||
.get("atime"), "atime")), dateService.iso8601SecondsDateParse(checkNotNull(metaMap
|
.get("atime"), "atime")), dateService.iso8601SecondsDateParse(checkNotNull(metaMap
|
||||||
|
|
|
@ -73,7 +73,7 @@ public class AtmosStorageUtils {
|
||||||
deleteAndEnsureGone(sync, path);
|
deleteAndEnsureGone(sync, path);
|
||||||
if (blob.getMetadata().getContentMD5() != null)
|
if (blob.getMetadata().getContentMD5() != null)
|
||||||
blob.getMetadata().getUserMetadata().put("content-md5",
|
blob.getMetadata().getUserMetadata().put("content-md5",
|
||||||
encryptionService.toHexString(blob.getMetadata().getContentMD5()));
|
encryptionService.hex(blob.getMetadata().getContentMD5()));
|
||||||
sync.createFile(container, blob2Object.apply(blob));
|
sync.createFile(container, blob2Object.apply(blob));
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,7 +55,7 @@ public class ParseSystemMetadataFromHeadersTest {
|
||||||
+ "gid=rootr, objectid=4980cdb2b010109b04a44f7bb83f5f04ad354c638ae5, "
|
+ "gid=rootr, objectid=4980cdb2b010109b04a44f7bb83f5f04ad354c638ae5, "
|
||||||
+ "objname=e913e09366364e9ba384b8fead643d43, size=4096, nlink=1, policyname=default");
|
+ "objname=e913e09366364e9ba384b8fead643d43, size=4096, nlink=1, policyname=default");
|
||||||
SystemMetadata expected = new SystemMetadata(encryptionService
|
SystemMetadata expected = new SystemMetadata(encryptionService
|
||||||
.fromHexString("1f3870be274f6c49b3e31a0c6728957f"),
|
.fromHex("1f3870be274f6c49b3e31a0c6728957f"),
|
||||||
|
|
||||||
dateService.iso8601SecondsDateParse("2009-10-12T16:09:42Z"), dateService
|
dateService.iso8601SecondsDateParse("2009-10-12T16:09:42Z"), dateService
|
||||||
.iso8601SecondsDateParse("2009-10-19T04:37:00Z"), "rootr", dateService
|
.iso8601SecondsDateParse("2009-10-19T04:37:00Z"), "rootr", dateService
|
||||||
|
|
|
@ -47,6 +47,6 @@ public class ConvertUnencodedBytesToBase64EncodedString implements Function<Obje
|
||||||
byte[] unencodedData = (byte[]) from;
|
byte[] unencodedData = (byte[]) from;
|
||||||
checkArgument(checkNotNull(unencodedData, "unencodedData").length <= 16 * 1024,
|
checkArgument(checkNotNull(unencodedData, "unencodedData").length <= 16 * 1024,
|
||||||
"userData cannot be larger than 16kb");
|
"userData cannot be larger than 16kb");
|
||||||
return encryptionService.toBase64String(unencodedData);
|
return encryptionService.base64(unencodedData);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -37,7 +37,7 @@ public class UnencodeStringValueHandler extends StringValueHandler {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getResult() {
|
public String getResult() {
|
||||||
return super.getResult() == null ? null : new String(encryptionService.fromBase64String(super
|
return super.getResult() == null ? null : new String(encryptionService.fromBase64(super
|
||||||
.getResult()), Charsets.UTF_8);
|
.getResult()), Charsets.UTF_8);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -151,7 +151,8 @@ public class FormSigner implements HttpRequestFilter, RequestSigner {
|
||||||
public String sign(String stringToSign) {
|
public String sign(String stringToSign) {
|
||||||
String signature;
|
String signature;
|
||||||
try {
|
try {
|
||||||
signature = encryptionService.hmacSha256Base64(stringToSign, secretKey.getBytes());
|
signature = encryptionService.base64(encryptionService.hmacSha256(stringToSign,
|
||||||
|
secretKey.getBytes()));
|
||||||
if (signatureWire.enabled())
|
if (signatureWire.enabled())
|
||||||
signatureWire.input(Utils.toInputStream(signature));
|
signatureWire.input(Utils.toInputStream(signature));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
|
|
@ -128,7 +128,8 @@ public class RequestAuthorizeSignature implements HttpRequestFilter, RequestSign
|
||||||
public String sign(String toSign) {
|
public String sign(String toSign) {
|
||||||
String signature;
|
String signature;
|
||||||
try {
|
try {
|
||||||
signature = encryptionService.hmacSha1Base64(toSign, secretKey.getBytes());
|
signature = encryptionService.base64(encryptionService.hmacSha1(toSign, secretKey
|
||||||
|
.getBytes()));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new HttpException("error signing request", e);
|
throw new HttpException("error signing request", e);
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,7 +64,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(encryptionService.fromHexString(Utils.replaceAll(to.getETag(), '"', "")));
|
to.setContentMD5(encryptionService.fromHex(Utils.replaceAll(to.getETag(), '"', "")));
|
||||||
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));
|
||||||
|
|
|
@ -72,8 +72,8 @@ public class ListBucketHandler extends ParseSax.HandlerWithResult<ListBucketResp
|
||||||
}
|
}
|
||||||
|
|
||||||
public ListBucketResponse getResult() {
|
public ListBucketResponse getResult() {
|
||||||
return new ListBucketResponseImpl(bucketName, contents, prefix, marker, nextMarker, maxResults,
|
return new ListBucketResponseImpl(bucketName, contents, prefix, marker, nextMarker,
|
||||||
delimiter, isTruncated, commonPrefixes);
|
maxResults, delimiter, isTruncated, commonPrefixes);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean inCommonPrefixes;
|
private boolean inCommonPrefixes;
|
||||||
|
@ -102,7 +102,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 = encryptionService.fromHexString(Utils.replaceAll(currentETag,'"', ""));
|
currentMD5 = encryptionService.fromHex(Utils.replaceAll(currentETag, '"', ""));
|
||||||
} 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")) {
|
||||||
|
|
|
@ -48,7 +48,7 @@ public class MD5Handler extends ParseSax.HandlerWithResult<byte[]> {
|
||||||
public void endElement(String uri, String name, String qName) {
|
public void endElement(String uri, String name, String qName) {
|
||||||
if (qName.equals("MD5OfMessageBody")) {
|
if (qName.equals("MD5OfMessageBody")) {
|
||||||
String md5Hex = currentText.toString().trim();
|
String md5Hex = currentText.toString().trim();
|
||||||
this.md5 = encryptionService.fromHexString(md5Hex);
|
this.md5 = encryptionService.fromHex(md5Hex);
|
||||||
}
|
}
|
||||||
currentText = new StringBuilder();
|
currentText = new StringBuilder();
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,7 +54,7 @@ public class RegexMD5Handler implements Function<HttpResponse, byte[]> {
|
||||||
try {
|
try {
|
||||||
Matcher matcher = pattern.matcher(Utils.toStringAndClose(response.getContent()));
|
Matcher matcher = pattern.matcher(Utils.toStringAndClose(response.getContent()));
|
||||||
if (matcher.find()) {
|
if (matcher.find()) {
|
||||||
value = encryptionService.fromHexString(matcher.group(1));
|
value = encryptionService.fromHex(matcher.group(1));
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
Throwables.propagate(e);
|
Throwables.propagate(e);
|
||||||
|
|
|
@ -104,7 +104,7 @@ public class ParseObjectMetadataFromHeadersTest {
|
||||||
expects.setCacheControl("cacheControl");
|
expects.setCacheControl("cacheControl");
|
||||||
expects.setContentDisposition("contentDisposition");
|
expects.setContentDisposition("contentDisposition");
|
||||||
expects.setContentEncoding("encoding");
|
expects.setContentEncoding("encoding");
|
||||||
expects.setContentMD5(encryptionService.fromHexString("abc"));
|
expects.setContentMD5(encryptionService.fromHex("abc"));
|
||||||
expects.setContentType("type");
|
expects.setContentType("type");
|
||||||
expects.setETag("\"abc\"");
|
expects.setETag("\"abc\"");
|
||||||
expects.setKey("key");
|
expects.setKey("key");
|
||||||
|
|
|
@ -65,54 +65,54 @@ public class ListBucketHandlerTest extends BaseHandlerTest {
|
||||||
(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\"", encryptionService
|
"\"c82e6a0025c31c5de5947fda62ac51ab\"", encryptionService
|
||||||
.fromHexString("c82e6a0025c31c5de5947fda62ac51ab"), 8,
|
.fromHex("c82e6a0025c31c5de5947fda62ac51ab"), 8, owner,
|
||||||
owner, StorageClass.STANDARD),
|
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\"", encryptionService
|
"\"944fab2c5a9a6bacf07db5e688310d7a\"", encryptionService
|
||||||
.fromHexString("944fab2c5a9a6bacf07db5e688310d7a"), 8,
|
.fromHex("944fab2c5a9a6bacf07db5e688310d7a"), 8, owner,
|
||||||
owner, StorageClass.STANDARD),
|
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\"", encryptionService
|
"\"a227b8888045c8fd159fb495214000f0\"", encryptionService
|
||||||
.fromHexString("a227b8888045c8fd159fb495214000f0"), 8,
|
.fromHex("a227b8888045c8fd159fb495214000f0"), 8, owner,
|
||||||
owner, StorageClass.STANDARD),
|
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\"", encryptionService
|
"\"c9caa76c3dec53e2a192608ce73eef03\"", encryptionService
|
||||||
.fromHexString("c9caa76c3dec53e2a192608ce73eef03"), 8,
|
.fromHex("c9caa76c3dec53e2a192608ce73eef03"), 8, owner,
|
||||||
owner, StorageClass.STANDARD),
|
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\"", encryptionService
|
"\"1ce5d0dcc6154a647ea90c7bdf82a224\"", encryptionService
|
||||||
.fromHexString("1ce5d0dcc6154a647ea90c7bdf82a224"), 8,
|
.fromHex("1ce5d0dcc6154a647ea90c7bdf82a224"), 8, owner,
|
||||||
owner, StorageClass.STANDARD),
|
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\"", encryptionService
|
"\"79433524d87462ee05708a8ef894ed55\"", encryptionService
|
||||||
.fromHexString("79433524d87462ee05708a8ef894ed55"), 8,
|
.fromHex("79433524d87462ee05708a8ef894ed55"), 8, owner,
|
||||||
owner, StorageClass.STANDARD),
|
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\"", encryptionService
|
"\"dd00a060b28ddca8bc5a21a49e306f67\"", encryptionService
|
||||||
.fromHexString("dd00a060b28ddca8bc5a21a49e306f67"), 8,
|
.fromHex("dd00a060b28ddca8bc5a21a49e306f67"), 8, owner,
|
||||||
owner, StorageClass.STANDARD),
|
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\"", encryptionService
|
"\"8cd06eca6e819a927b07a285d750b100\"", encryptionService
|
||||||
.fromHexString("8cd06eca6e819a927b07a285d750b100"), 8,
|
.fromHex("8cd06eca6e819a927b07a285d750b100"), 8, owner,
|
||||||
owner, StorageClass.STANDARD),
|
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\"", encryptionService
|
"\"174495094d0633b92cbe46603eee6bad\"", encryptionService
|
||||||
.fromHexString("174495094d0633b92cbe46603eee6bad"), 8,
|
.fromHex("174495094d0633b92cbe46603eee6bad"), 8, owner,
|
||||||
owner, StorageClass.STANDARD),
|
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\"", encryptionService
|
"\"cd8a19b26fea8a827276df0ad11c580d\"", encryptionService
|
||||||
.fromHexString("cd8a19b26fea8a827276df0ad11c580d"), 8,
|
.fromHex("cd8a19b26fea8a827276df0ad11c580d"), 8, owner,
|
||||||
owner, StorageClass.STANDARD)), "apps/", null, null, 1000, null,
|
StorageClass.STANDARD)), "apps/", null, null, 1000, null, false,
|
||||||
false, new TreeSet<String>());
|
new TreeSet<String>());
|
||||||
|
|
||||||
ListBucketResponse result = (ListBucketResponse) factory.create(
|
ListBucketResponse result = (ListBucketResponse) factory.create(
|
||||||
injector.getInstance(ListBucketHandler.class)).parse(is);
|
injector.getInstance(ListBucketHandler.class)).parse(is);
|
||||||
|
|
|
@ -35,6 +35,7 @@ import org.jclouds.encryption.internal.JCEEncryptionService;
|
||||||
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
|
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
|
||||||
import org.jclouds.rest.RestContext;
|
import org.jclouds.rest.RestContext;
|
||||||
import org.jclouds.rest.RestContextFactory;
|
import org.jclouds.rest.RestContextFactory;
|
||||||
|
import org.jclouds.util.Utils;
|
||||||
import org.testng.annotations.AfterTest;
|
import org.testng.annotations.AfterTest;
|
||||||
import org.testng.annotations.BeforeGroups;
|
import org.testng.annotations.BeforeGroups;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
@ -61,8 +62,10 @@ public class SQSClientLiveTest {
|
||||||
|
|
||||||
@BeforeGroups(groups = { "live" })
|
@BeforeGroups(groups = { "live" })
|
||||||
public void setupClient() throws IOException {
|
public void setupClient() throws IOException {
|
||||||
String identity = checkNotNull(System.getProperty("jclouds.test.identity"), "jclouds.test.identity");
|
String identity = checkNotNull(System.getProperty("jclouds.test.identity"),
|
||||||
String credential = checkNotNull(System.getProperty("jclouds.test.credential"), "jclouds.test.credential");
|
"jclouds.test.identity");
|
||||||
|
String credential = checkNotNull(System.getProperty("jclouds.test.credential"),
|
||||||
|
"jclouds.test.credential");
|
||||||
|
|
||||||
context = new RestContextFactory().createContext("sqs", identity, credential, ImmutableSet
|
context = new RestContextFactory().createContext("sqs", identity, credential, ImmutableSet
|
||||||
.<Module> of(new Log4JLoggingModule()));
|
.<Module> of(new Log4JLoggingModule()));
|
||||||
|
@ -126,7 +129,7 @@ public class SQSClientLiveTest {
|
||||||
@Test(dependsOnMethods = "testCreateQueue")
|
@Test(dependsOnMethods = "testCreateQueue")
|
||||||
void testSendMessage() throws InterruptedException {
|
void testSendMessage() throws InterruptedException {
|
||||||
String message = "hardyharhar";
|
String message = "hardyharhar";
|
||||||
byte[] md5 = encryptionService.md5(message.getBytes());
|
byte[] md5 = encryptionService.md5(Utils.toInputStream(message));
|
||||||
for (Queue queue : queues) {
|
for (Queue queue : queues) {
|
||||||
assertEquals(client.sendMessage(queue, message), md5);
|
assertEquals(client.sendMessage(queue, message), md5);
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,7 +78,7 @@ public class BindAzureBlobToPayload implements Binder {
|
||||||
|
|
||||||
if (object.getProperties().getContentMD5() != null) {
|
if (object.getProperties().getContentMD5() != null) {
|
||||||
request.getHeaders().put("Content-MD5",
|
request.getHeaders().put("Content-MD5",
|
||||||
encryptionService.toBase64String(object.getProperties().getContentMD5()));
|
encryptionService.base64(object.getProperties().getContentMD5()));
|
||||||
}
|
}
|
||||||
if (object.getProperties().getContentLanguage() != null) {
|
if (object.getProperties().getContentLanguage() != null) {
|
||||||
request.getHeaders().put(HttpHeaders.CONTENT_LANGUAGE,
|
request.getHeaders().put(HttpHeaders.CONTENT_LANGUAGE,
|
||||||
|
|
|
@ -166,7 +166,7 @@ public class ContainerNameEnumerationResultsHandler extends
|
||||||
currentSize = Long.parseLong(currentText.toString().trim());
|
currentSize = Long.parseLong(currentText.toString().trim());
|
||||||
} else if (qName.equals("Content-MD5")) {
|
} else if (qName.equals("Content-MD5")) {
|
||||||
if (!currentText.toString().trim().equals(""))
|
if (!currentText.toString().trim().equals(""))
|
||||||
currentContentMD5 = encryptionService.fromBase64String(currentText.toString().trim());
|
currentContentMD5 = encryptionService.fromBase64(currentText.toString().trim());
|
||||||
} else if (qName.equals("Content-Type")) {
|
} else if (qName.equals("Content-Type")) {
|
||||||
currentContentType = currentText.toString().trim();
|
currentContentType = currentText.toString().trim();
|
||||||
} else if (qName.equals("Content-Encoding")) {
|
} else if (qName.equals("Content-Encoding")) {
|
||||||
|
|
|
@ -74,7 +74,7 @@ public class SharedKeyLiteAuthentication implements HttpRequestFilter {
|
||||||
this.encryptionService = encryptionService;
|
this.encryptionService = encryptionService;
|
||||||
this.signatureWire = signatureWire;
|
this.signatureWire = signatureWire;
|
||||||
this.identity = identity;
|
this.identity = identity;
|
||||||
this.key = encryptionService.fromBase64String(encodedKey);
|
this.key = encryptionService.fromBase64(encodedKey);
|
||||||
this.timeStampProvider = timeStampProvider;
|
this.timeStampProvider = timeStampProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,7 +110,7 @@ public class SharedKeyLiteAuthentication implements HttpRequestFilter {
|
||||||
public String signString(String toSign) {
|
public String signString(String toSign) {
|
||||||
String signature;
|
String signature;
|
||||||
try {
|
try {
|
||||||
signature = encryptionService.hmacSha256Base64(toSign, key);
|
signature = encryptionService.base64(encryptionService.hmacSha256(toSign, key));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new HttpException("error signing request", e);
|
throw new HttpException("error signing request", e);
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,7 +74,8 @@ public class AzureBlobClientLiveTest {
|
||||||
identity = System.getProperty("jclouds.test.identity");
|
identity = System.getProperty("jclouds.test.identity");
|
||||||
String credential = System.getProperty("jclouds.test.credential");
|
String credential = System.getProperty("jclouds.test.credential");
|
||||||
client = (AzureBlobClient) new BlobStoreContextFactory().createContext("azureblob", identity,
|
client = (AzureBlobClient) new BlobStoreContextFactory().createContext("azureblob", identity,
|
||||||
credential, ImmutableSet.<Module> of(new Log4JLoggingModule())).getProviderSpecificContext().getApi();
|
credential, ImmutableSet.<Module> of(new Log4JLoggingModule()))
|
||||||
|
.getProviderSpecificContext().getApi();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -236,8 +237,8 @@ public class AzureBlobClientLiveTest {
|
||||||
object.getProperties().getMetadata().put("mykey", "metadata-value");
|
object.getProperties().getMetadata().put("mykey", "metadata-value");
|
||||||
byte[] md5 = object.getProperties().getContentMD5();
|
byte[] md5 = object.getProperties().getContentMD5();
|
||||||
String newEtag = client.putBlob(privateContainer, object);
|
String newEtag = client.putBlob(privateContainer, object);
|
||||||
assertEquals(encryptionService.toHexString(md5), encryptionService.toHexString(object
|
assertEquals(encryptionService.hex(md5), encryptionService.hex(object.getProperties()
|
||||||
.getProperties().getContentMD5()));
|
.getContentMD5()));
|
||||||
|
|
||||||
// Test HEAD of missing object
|
// Test HEAD of missing object
|
||||||
assert client.getBlobProperties(privateContainer, "non-existent-object") == null;
|
assert client.getBlobProperties(privateContainer, "non-existent-object") == null;
|
||||||
|
@ -254,8 +255,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(encryptionService.toHexString(md5), encryptionService.toHexString(object
|
assertEquals(encryptionService.hex(md5), encryptionService.hex(object.getProperties()
|
||||||
.getProperties().getContentMD5()));
|
.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("mykey"), "metadata-value");
|
assertEquals(metadata.getMetadata().get("mykey"), "metadata-value");
|
||||||
|
@ -276,8 +277,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(encryptionService.toHexString(md5), encryptionService.toHexString(getBlob
|
assertEquals(encryptionService.hex(md5), encryptionService.hex(getBlob.getProperties()
|
||||||
.getProperties().getContentMD5()));
|
.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);
|
||||||
|
@ -318,8 +319,8 @@ public class AzureBlobClientLiveTest {
|
||||||
object.setPayload(bais);
|
object.setPayload(bais);
|
||||||
object.setContentLength(new Long(data.getBytes().length));
|
object.setContentLength(new Long(data.getBytes().length));
|
||||||
newEtag = client.putBlob(privateContainer, object);
|
newEtag = client.putBlob(privateContainer, object);
|
||||||
assertEquals(encryptionService.toHexString(md5), encryptionService.toHexString(getBlob
|
assertEquals(encryptionService.hex(md5), encryptionService.hex(getBlob.getProperties()
|
||||||
.getProperties().getContentMD5()));
|
.getContentMD5()));
|
||||||
|
|
||||||
// Test GET with options
|
// Test GET with options
|
||||||
// Non-matching ETag
|
// Non-matching ETag
|
||||||
|
|
|
@ -20,15 +20,26 @@ package org.jclouds.blobstore;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
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 static com.google.common.base.Throwables.getCausalChain;
|
||||||
|
import static com.google.common.base.Throwables.propagate;
|
||||||
|
import static com.google.common.collect.Iterables.filter;
|
||||||
|
import static com.google.common.collect.Iterables.find;
|
||||||
|
import static com.google.common.collect.Iterables.size;
|
||||||
|
import static com.google.common.collect.Iterables.transform;
|
||||||
|
import static com.google.common.collect.Lists.newArrayList;
|
||||||
|
import static com.google.common.collect.Lists.partition;
|
||||||
|
import static com.google.common.collect.Maps.newHashMap;
|
||||||
|
import static com.google.common.collect.Sets.filter;
|
||||||
|
import static com.google.common.collect.Sets.newTreeSet;
|
||||||
|
import static com.google.common.io.ByteStreams.toByteArray;
|
||||||
|
import static com.google.common.io.Closeables.closeQuietly;
|
||||||
import static com.google.common.util.concurrent.Futures.immediateFailedFuture;
|
import static com.google.common.util.concurrent.Futures.immediateFailedFuture;
|
||||||
import static com.google.common.util.concurrent.Futures.immediateFuture;
|
import static com.google.common.util.concurrent.Futures.immediateFuture;
|
||||||
|
import static org.jclouds.http.Payloads.newByteArrayPayload;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.ObjectInput;
|
import java.io.ObjectInput;
|
||||||
import java.io.ObjectInputStream;
|
import java.io.ObjectInputStream;
|
||||||
import java.io.ObjectOutput;
|
import java.io.ObjectOutput;
|
||||||
|
@ -74,17 +85,12 @@ 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.Payload;
|
||||||
import org.jclouds.http.options.HttpRequestOptions;
|
import org.jclouds.http.options.HttpRequestOptions;
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
import com.google.common.base.Predicate;
|
import com.google.common.base.Predicate;
|
||||||
import com.google.common.base.Throwables;
|
|
||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
import com.google.common.collect.Lists;
|
|
||||||
import com.google.common.collect.Maps;
|
|
||||||
import com.google.common.collect.Sets;
|
|
||||||
import com.google.common.io.ByteStreams;
|
|
||||||
import com.google.common.io.Closeables;
|
|
||||||
import com.google.common.util.concurrent.ListenableFuture;
|
import com.google.common.util.concurrent.ListenableFuture;
|
||||||
import com.google.inject.internal.Nullable;
|
import com.google.inject.internal.Nullable;
|
||||||
|
|
||||||
|
@ -125,27 +131,6 @@ public class TransientAsyncBlobStore extends BaseAsyncBlobStore {
|
||||||
getContainerToBlobs().put("stub", new ConcurrentHashMap<String, Blob>());
|
getContainerToBlobs().put("stub", new ConcurrentHashMap<String, Blob>());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @throws java.io.IOException
|
|
||||||
*/
|
|
||||||
public static byte[] toByteArray(Object data) throws IOException {
|
|
||||||
checkNotNull(data, "data must be set before calling generateETag()");
|
|
||||||
byte[] bytes = null;
|
|
||||||
if (data == null || data instanceof byte[]) {
|
|
||||||
bytes = (byte[]) data;
|
|
||||||
} else if (data instanceof String) {
|
|
||||||
bytes = ((String) data).getBytes();
|
|
||||||
} else if (data instanceof File || data instanceof InputStream) {
|
|
||||||
InputStream io = (data instanceof InputStream) ? (InputStream) data : new FileInputStream(
|
|
||||||
(File) data);
|
|
||||||
bytes = ByteStreams.toByteArray(io);
|
|
||||||
Closeables.closeQuietly(io);
|
|
||||||
} else {
|
|
||||||
throw new UnsupportedOperationException("Content not supported " + data.getClass());
|
|
||||||
}
|
|
||||||
return bytes;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* default maxResults is 1000
|
* default maxResults is 1000
|
||||||
*/
|
*/
|
||||||
|
@ -157,39 +142,38 @@ public class TransientAsyncBlobStore extends BaseAsyncBlobStore {
|
||||||
if (realContents == null)
|
if (realContents == null)
|
||||||
return immediateFailedFuture(cnfe(container));
|
return immediateFailedFuture(cnfe(container));
|
||||||
|
|
||||||
SortedSet<StorageMetadata> contents = Sets.newTreeSet(Iterables.transform(realContents
|
SortedSet<StorageMetadata> contents = newTreeSet(transform(realContents.keySet(),
|
||||||
.keySet(), new Function<String, StorageMetadata>() {
|
new Function<String, StorageMetadata>() {
|
||||||
public StorageMetadata apply(String key) {
|
public StorageMetadata apply(String key) {
|
||||||
Blob oldBlob = realContents.get(key);
|
Blob oldBlob = realContents.get(key);
|
||||||
checkState(oldBlob != null, "blob " + key
|
checkState(oldBlob != null, "blob " + key
|
||||||
+ " is not present although it was in the list of " + container);
|
+ " is not present although it was in the list of " + container);
|
||||||
checkState(oldBlob.getMetadata() != null, "blob " + container + "/" + key
|
checkState(oldBlob.getMetadata() != null, "blob " + container + "/" + key
|
||||||
+ " has no metadata");
|
+ " has no metadata");
|
||||||
MutableBlobMetadata md = copy(oldBlob.getMetadata());
|
MutableBlobMetadata md = copy(oldBlob.getMetadata());
|
||||||
String directoryName = ifDirectoryReturnName.execute(md);
|
String directoryName = ifDirectoryReturnName.execute(md);
|
||||||
if (directoryName != null) {
|
if (directoryName != null) {
|
||||||
md.setName(directoryName);
|
md.setName(directoryName);
|
||||||
md.setType(StorageType.RELATIVE_PATH);
|
md.setType(StorageType.RELATIVE_PATH);
|
||||||
}
|
}
|
||||||
return md;
|
return md;
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
if (options.getMarker() != null) {
|
if (options.getMarker() != null) {
|
||||||
final String finalMarker = options.getMarker();
|
final String finalMarker = options.getMarker();
|
||||||
StorageMetadata lastMarkerMetadata = Iterables.find(contents,
|
StorageMetadata lastMarkerMetadata = find(contents, new Predicate<StorageMetadata>() {
|
||||||
new Predicate<StorageMetadata>() {
|
public boolean apply(StorageMetadata metadata) {
|
||||||
public boolean apply(StorageMetadata metadata) {
|
return metadata.getName().equals(finalMarker);
|
||||||
return metadata.getName().equals(finalMarker);
|
}
|
||||||
}
|
});
|
||||||
});
|
|
||||||
contents = contents.tailSet(lastMarkerMetadata);
|
contents = contents.tailSet(lastMarkerMetadata);
|
||||||
contents.remove(lastMarkerMetadata);
|
contents.remove(lastMarkerMetadata);
|
||||||
}
|
}
|
||||||
|
|
||||||
final String prefix = options.getDir();
|
final String prefix = options.getDir();
|
||||||
if (prefix != null) {
|
if (prefix != null) {
|
||||||
contents = Sets.newTreeSet(Iterables.filter(contents, new Predicate<StorageMetadata>() {
|
contents = newTreeSet(filter(contents, new Predicate<StorageMetadata>() {
|
||||||
public boolean apply(StorageMetadata o) {
|
public boolean apply(StorageMetadata o) {
|
||||||
return (o != null && o.getName().startsWith(prefix) && !o.getName().equals(prefix));
|
return (o != null && o.getName().startsWith(prefix) && !o.getName().equals(prefix));
|
||||||
}
|
}
|
||||||
|
@ -212,15 +196,15 @@ public class TransientAsyncBlobStore extends BaseAsyncBlobStore {
|
||||||
final String delimiter = options.isRecursive() ? null : "/";
|
final String delimiter = options.isRecursive() ? null : "/";
|
||||||
if (delimiter != null) {
|
if (delimiter != null) {
|
||||||
SortedSet<String> commonPrefixes = null;
|
SortedSet<String> commonPrefixes = null;
|
||||||
Iterable<String> iterable = Iterables.transform(contents, new CommonPrefixes(
|
Iterable<String> iterable = transform(contents, new CommonPrefixes(prefix != null ? prefix
|
||||||
prefix != null ? prefix : null, delimiter));
|
: null, delimiter));
|
||||||
commonPrefixes = iterable != null ? Sets.newTreeSet(iterable) : new TreeSet<String>();
|
commonPrefixes = iterable != null ? newTreeSet(iterable) : new TreeSet<String>();
|
||||||
commonPrefixes.remove(CommonPrefixes.NO_PREFIX);
|
commonPrefixes.remove(CommonPrefixes.NO_PREFIX);
|
||||||
|
|
||||||
contents = Sets.newTreeSet(Iterables.filter(contents, new DelimiterFilter(
|
contents = newTreeSet(filter(contents, new DelimiterFilter(prefix != null ? prefix : null,
|
||||||
prefix != null ? prefix : null, delimiter)));
|
delimiter)));
|
||||||
|
|
||||||
Iterables.<StorageMetadata> addAll(contents, Iterables.transform(commonPrefixes,
|
Iterables.<StorageMetadata> addAll(contents, transform(commonPrefixes,
|
||||||
new Function<String, StorageMetadata>() {
|
new Function<String, StorageMetadata>() {
|
||||||
public StorageMetadata apply(String o) {
|
public StorageMetadata apply(String o) {
|
||||||
MutableStorageMetadata md = new MutableStorageMetadataImpl();
|
MutableStorageMetadata md = new MutableStorageMetadataImpl();
|
||||||
|
@ -258,14 +242,14 @@ public class TransientAsyncBlobStore extends BaseAsyncBlobStore {
|
||||||
convertUserMetadataKeysToLowercase(metadata);
|
convertUserMetadataKeysToLowercase(metadata);
|
||||||
return metadata;
|
return metadata;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Throwables.propagate(e);
|
propagate(e);
|
||||||
assert false : "exception should have propagated: " + e;
|
assert false : "exception should have propagated: " + e;
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void convertUserMetadataKeysToLowercase(MutableBlobMetadata metadata) {
|
private static void convertUserMetadataKeysToLowercase(MutableBlobMetadata metadata) {
|
||||||
Map<String, String> lowerCaseUserMetadata = Maps.newHashMap();
|
Map<String, String> lowerCaseUserMetadata = newHashMap();
|
||||||
for (Entry<String, String> entry : metadata.getUserMetadata().entrySet()) {
|
for (Entry<String, String> entry : metadata.getUserMetadata().entrySet()) {
|
||||||
lowerCaseUserMetadata.put(entry.getKey().toLowerCase(), entry.getValue());
|
lowerCaseUserMetadata.put(entry.getKey().toLowerCase(), entry.getValue());
|
||||||
}
|
}
|
||||||
|
@ -333,16 +317,16 @@ public class TransientAsyncBlobStore extends BaseAsyncBlobStore {
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public ListenableFuture<? extends PageSet<? extends StorageMetadata>> list() {
|
public ListenableFuture<? extends PageSet<? extends StorageMetadata>> list() {
|
||||||
return immediateFuture(new PageSetImpl<StorageMetadata>(Iterables.transform(
|
return immediateFuture(new PageSetImpl<StorageMetadata>(transform(getContainerToBlobs()
|
||||||
getContainerToBlobs().keySet(), new Function<String, StorageMetadata>() {
|
.keySet(), new Function<String, StorageMetadata>() {
|
||||||
public StorageMetadata apply(String name) {
|
public StorageMetadata apply(String name) {
|
||||||
MutableStorageMetadata cmd = create();
|
MutableStorageMetadata cmd = create();
|
||||||
cmd.setName(name);
|
cmd.setName(name);
|
||||||
cmd.setType(StorageType.CONTAINER);
|
cmd.setType(StorageType.CONTAINER);
|
||||||
cmd.setLocation(getContainerToLocation().get(name));
|
cmd.setLocation(getContainerToLocation().get(name));
|
||||||
return cmd;
|
return cmd;
|
||||||
}
|
}
|
||||||
}), null));
|
}), null));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected MutableStorageMetadata create() {
|
protected MutableStorageMetadata create() {
|
||||||
|
@ -423,8 +407,8 @@ public class TransientAsyncBlobStore extends BaseAsyncBlobStore {
|
||||||
|
|
||||||
public static <T extends Comparable<?>> SortedSet<T> firstSliceOfSize(Iterable<T> elements,
|
public static <T extends Comparable<?>> SortedSet<T> firstSliceOfSize(Iterable<T> elements,
|
||||||
int size) {
|
int size) {
|
||||||
List<List<T>> slices = Lists.partition(Lists.newArrayList(elements), size);
|
List<List<T>> slices = partition(newArrayList(elements), size);
|
||||||
return Sets.newTreeSet(slices.get(0));
|
return newTreeSet(slices.get(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static HttpResponseException returnResponseException(int code) {
|
public static HttpResponseException returnResponseException(int code) {
|
||||||
|
@ -472,40 +456,44 @@ public class TransientAsyncBlobStore extends BaseAsyncBlobStore {
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public ListenableFuture<String> putBlob(final String containerName, final Blob object) {
|
public ListenableFuture<String> putBlob(String containerName, Blob object) {
|
||||||
Map<String, Blob> container = getContainerToBlobs().get(containerName);
|
Map<String, Blob> container = getContainerToBlobs().get(containerName);
|
||||||
if (container == null) {
|
if (container == null) {
|
||||||
new RuntimeException("containerName not found: " + containerName);
|
new RuntimeException("containerName not found: " + containerName);
|
||||||
}
|
}
|
||||||
try {
|
Payload payload = object.getPayload();
|
||||||
byte[] data = toByteArray(object.getPayload().getRawContent());
|
if (!payload.isRepeatable()) {
|
||||||
object.getMetadata().setSize(data.length);
|
try {
|
||||||
MutableBlobMetadata newMd = copy(object.getMetadata());
|
payload = newByteArrayPayload(toByteArray(payload.getInput()));
|
||||||
newMd.setLastModified(new Date());
|
} catch (IOException e) {
|
||||||
final byte[] md5 = encryptionService.md5(data);
|
propagate(e);
|
||||||
final String eTag = encryptionService.toHexString(md5);
|
} finally {
|
||||||
newMd.setETag(eTag);
|
closeQuietly(payload.getInput());
|
||||||
newMd.setContentMD5(md5);
|
|
||||||
newMd.setContentType(object.getMetadata().getContentType());
|
|
||||||
|
|
||||||
Blob blob = blobFactory.create(newMd);
|
|
||||||
blob.setPayload(data);
|
|
||||||
container.put(blob.getMetadata().getName(), blob);
|
|
||||||
|
|
||||||
// Set HTTP headers to match metadata
|
|
||||||
blob.getAllHeaders().put(HttpHeaders.LAST_MODIFIED,
|
|
||||||
dateService.rfc822DateFormat(newMd.getLastModified()));
|
|
||||||
blob.getAllHeaders().put(HttpHeaders.ETAG, eTag);
|
|
||||||
blob.getAllHeaders().put(HttpHeaders.CONTENT_TYPE, newMd.getContentType());
|
|
||||||
blob.getAllHeaders().put(HttpHeaders.CONTENT_LENGTH, newMd.getSize() + "");
|
|
||||||
for (Entry<String, String> userMD : newMd.getUserMetadata().entrySet()) {
|
|
||||||
blob.getAllHeaders().put(userMD.getKey(), userMD.getValue());
|
|
||||||
}
|
}
|
||||||
return immediateFuture(eTag);
|
|
||||||
} catch (IOException e) {
|
|
||||||
return immediateFailedFuture(new RuntimeException(e));
|
|
||||||
}
|
}
|
||||||
|
object.getMetadata().setSize(payload.calculateSize());
|
||||||
|
MutableBlobMetadata newMd = copy(object.getMetadata());
|
||||||
|
newMd.setLastModified(new Date());
|
||||||
|
byte[] md5 = encryptionService.md5(payload.getInput());
|
||||||
|
String eTag = encryptionService.hex(md5);
|
||||||
|
newMd.setETag(eTag);
|
||||||
|
newMd.setContentMD5(md5);
|
||||||
|
newMd.setContentType(object.getMetadata().getContentType());
|
||||||
|
|
||||||
|
Blob blob = blobFactory.create(newMd);
|
||||||
|
blob.setPayload(payload);
|
||||||
|
container.put(blob.getMetadata().getName(), blob);
|
||||||
|
|
||||||
|
// Set HTTP headers to match metadata
|
||||||
|
blob.getAllHeaders().put(HttpHeaders.LAST_MODIFIED,
|
||||||
|
dateService.rfc822DateFormat(newMd.getLastModified()));
|
||||||
|
blob.getAllHeaders().put(HttpHeaders.ETAG, eTag);
|
||||||
|
blob.getAllHeaders().put(HttpHeaders.CONTENT_TYPE, newMd.getContentType());
|
||||||
|
blob.getAllHeaders().put(HttpHeaders.CONTENT_LENGTH, newMd.getSize() + "");
|
||||||
|
for (Entry<String, String> userMD : newMd.getUserMetadata().entrySet()) {
|
||||||
|
blob.getAllHeaders().put(userMD.getKey(), userMD.getValue());
|
||||||
|
}
|
||||||
|
return immediateFuture(eTag);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -567,7 +555,7 @@ public class TransientAsyncBlobStore extends BaseAsyncBlobStore {
|
||||||
if (options.getRanges() != null && options.getRanges().size() > 0) {
|
if (options.getRanges() != null && options.getRanges().size() > 0) {
|
||||||
byte[] data;
|
byte[] data;
|
||||||
try {
|
try {
|
||||||
data = ByteStreams.toByteArray(returnVal.getPayload().getInput());
|
data = toByteArray(returnVal.getPayload().getInput());
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
return immediateFailedFuture(new RuntimeException(e));
|
return immediateFailedFuture(new RuntimeException(e));
|
||||||
}
|
}
|
||||||
|
@ -608,8 +596,7 @@ public class TransientAsyncBlobStore extends BaseAsyncBlobStore {
|
||||||
Blob blob = getBlob(container, key).get();
|
Blob blob = getBlob(container, key).get();
|
||||||
return immediateFuture(blob != null ? (BlobMetadata) copy(blob.getMetadata()) : null);
|
return immediateFuture(blob != null ? (BlobMetadata) copy(blob.getMetadata()) : null);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
if (Iterables.size(Iterables.filter(Throwables.getCausalChain(e),
|
if (size(filter(getCausalChain(e), KeyNotFoundException.class)) >= 1)
|
||||||
KeyNotFoundException.class)) >= 1)
|
|
||||||
return immediateFuture(null);
|
return immediateFuture(null);
|
||||||
return immediateFailedFuture(e);
|
return immediateFailedFuture(e);
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,7 +53,7 @@ public class BindBlobToPayload implements Binder {
|
||||||
|
|
||||||
if (object.getMetadata().getContentMD5() != null) {
|
if (object.getMetadata().getContentMD5() != null) {
|
||||||
request.getHeaders().put("Content-MD5",
|
request.getHeaders().put("Content-MD5",
|
||||||
encryptionService.toBase64String(object.getMetadata().getContentMD5()));
|
encryptionService.base64(object.getMetadata().getContentMD5()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,33 +0,0 @@
|
||||||
/**
|
|
||||||
*
|
|
||||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
|
||||||
*
|
|
||||||
* ====================================================================
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
* ====================================================================
|
|
||||||
*/
|
|
||||||
package org.jclouds.blobstore.functions;
|
|
||||||
|
|
||||||
import org.jclouds.blobstore.functions.impl.JCEGenerateMD5;
|
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
|
||||||
import com.google.inject.ImplementedBy;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author Adrian Cole
|
|
||||||
*/
|
|
||||||
@ImplementedBy(JCEGenerateMD5.class)
|
|
||||||
public interface GenerateMD5 extends Function<Object, byte[]> {
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,36 +0,0 @@
|
||||||
/**
|
|
||||||
*
|
|
||||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
|
||||||
*
|
|
||||||
* ====================================================================
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
* ====================================================================
|
|
||||||
*/
|
|
||||||
package org.jclouds.blobstore.functions;
|
|
||||||
|
|
||||||
import java.io.InputStream;
|
|
||||||
|
|
||||||
import org.jclouds.blobstore.domain.MD5InputStreamResult;
|
|
||||||
import org.jclouds.blobstore.functions.impl.JCEGenerateMD5Result;
|
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
|
||||||
import com.google.inject.ImplementedBy;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author Adrian Cole
|
|
||||||
*/
|
|
||||||
@ImplementedBy(JCEGenerateMD5Result.class)
|
|
||||||
public interface GenerateMD5Result extends Function<InputStream, MD5InputStreamResult> {
|
|
||||||
|
|
||||||
}
|
|
|
@ -114,7 +114,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(encryptionService.fromBase64String(contentMD5));
|
metadata.setContentMD5(encryptionService.fromBase64(contentMD5));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,39 +0,0 @@
|
||||||
/**
|
|
||||||
*
|
|
||||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
|
||||||
*
|
|
||||||
* ====================================================================
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
* ====================================================================
|
|
||||||
*/
|
|
||||||
package org.jclouds.blobstore.functions.impl;
|
|
||||||
|
|
||||||
import javax.inject.Singleton;
|
|
||||||
|
|
||||||
import org.jclouds.blobstore.functions.GenerateMD5;
|
|
||||||
import org.jclouds.encryption.EncryptionService;
|
|
||||||
import org.jclouds.encryption.internal.JCEEncryptionService;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author Adrian Cole
|
|
||||||
*/
|
|
||||||
@Singleton
|
|
||||||
public class JCEGenerateMD5 implements GenerateMD5 {
|
|
||||||
private static final EncryptionService encryptionService = new JCEEncryptionService();
|
|
||||||
|
|
||||||
public byte[] apply(Object from) {
|
|
||||||
return encryptionService.md5(from);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,43 +0,0 @@
|
||||||
/**
|
|
||||||
*
|
|
||||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
|
||||||
*
|
|
||||||
* ====================================================================
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
* ====================================================================
|
|
||||||
*/
|
|
||||||
package org.jclouds.blobstore.functions.impl;
|
|
||||||
|
|
||||||
import java.io.InputStream;
|
|
||||||
|
|
||||||
import javax.inject.Singleton;
|
|
||||||
|
|
||||||
import org.jclouds.blobstore.domain.MD5InputStreamResult;
|
|
||||||
import org.jclouds.blobstore.functions.GenerateMD5Result;
|
|
||||||
import org.jclouds.encryption.EncryptionService;
|
|
||||||
import org.jclouds.encryption.internal.JCEEncryptionService;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author Adrian Cole
|
|
||||||
*/
|
|
||||||
@Singleton
|
|
||||||
public class JCEGenerateMD5Result implements GenerateMD5Result {
|
|
||||||
private static final EncryptionService encryptionService = new JCEEncryptionService();
|
|
||||||
|
|
||||||
public MD5InputStreamResult apply(InputStream toEncode) {
|
|
||||||
org.jclouds.encryption.EncryptionService.MD5InputStreamResult result = encryptionService
|
|
||||||
.generateMD5Result(toEncode);
|
|
||||||
return new MD5InputStreamResult(result.data, result.md5, result.length);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -83,7 +83,7 @@ public class BaseBlobIntegrationTest extends BaseBlobStoreIntegrationTest {
|
||||||
@Override
|
@Override
|
||||||
public void setUpResourcesOnThisThread(ITestContext testContext) throws Exception {
|
public void setUpResourcesOnThisThread(ITestContext testContext) throws Exception {
|
||||||
encryptionService = Guice.createInjector().getInstance(EncryptionService.class);
|
encryptionService = Guice.createInjector().getInstance(EncryptionService.class);
|
||||||
MD5InputStreamResult result = encryptionService.generateMD5Result(getTestDataSupplier()
|
MD5InputStreamResult result = encryptionService.md5Result(getTestDataSupplier()
|
||||||
.getInput());
|
.getInput());
|
||||||
oneHundredOneConstitutions = result.data;
|
oneHundredOneConstitutions = result.data;
|
||||||
oneHundredOneConstitutionsMD5 = result.md5;
|
oneHundredOneConstitutionsMD5 = result.md5;
|
||||||
|
@ -440,7 +440,8 @@ public class BaseBlobIntegrationTest 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(new JCEEncryptionService().md5(TEST_STRING.getBytes()));
|
object.getMetadata().setContentMD5(
|
||||||
|
new JCEEncryptionService().md5(Utils.toInputStream(TEST_STRING)));
|
||||||
String containerName = getContainerName();
|
String containerName = getContainerName();
|
||||||
try {
|
try {
|
||||||
assertNull(context.getBlobStore().blobMetadata(containerName, "powderpuff"));
|
assertNull(context.getBlobStore().blobMetadata(containerName, "powderpuff"));
|
||||||
|
@ -469,7 +470,8 @@ public class BaseBlobIntegrationTest 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(), new JCEEncryptionService().md5(TEST_STRING.getBytes()));
|
assertEquals(metadata.getContentMD5(), new JCEEncryptionService().md5(Utils
|
||||||
|
.toInputStream(TEST_STRING)));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -59,7 +59,7 @@ public class BaseBlobLiveTest extends BaseBlobStoreIntegrationTest {
|
||||||
String key = "hello";
|
String key = "hello";
|
||||||
|
|
||||||
URL url = new URL(httpStreamUrl);
|
URL url = new URL(httpStreamUrl);
|
||||||
byte[] md5 = new JCEEncryptionService().fromHexString(httpStreamETag);
|
byte[] md5 = new JCEEncryptionService().fromHex(httpStreamETag);
|
||||||
|
|
||||||
URLConnection connection = url.openConnection();
|
URLConnection connection = url.openConnection();
|
||||||
int length = connection.getContentLength();
|
int length = connection.getContentLength();
|
||||||
|
|
|
@ -18,9 +18,12 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.blobstore.integration.internal;
|
package org.jclouds.blobstore.integration.internal;
|
||||||
|
|
||||||
|
import static com.google.common.base.Throwables.propagateIfPossible;
|
||||||
|
import static com.google.common.collect.Iterables.get;
|
||||||
import static org.jclouds.blobstore.options.ListContainerOptions.Builder.afterMarker;
|
import static org.jclouds.blobstore.options.ListContainerOptions.Builder.afterMarker;
|
||||||
import static org.jclouds.blobstore.options.ListContainerOptions.Builder.inDirectory;
|
import static org.jclouds.blobstore.options.ListContainerOptions.Builder.inDirectory;
|
||||||
import static org.jclouds.blobstore.options.ListContainerOptions.Builder.maxResults;
|
import static org.jclouds.blobstore.options.ListContainerOptions.Builder.maxResults;
|
||||||
|
import static org.jclouds.util.Utils.toInputStream;
|
||||||
import static org.testng.Assert.assertEquals;
|
import static org.testng.Assert.assertEquals;
|
||||||
|
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
|
@ -37,9 +40,6 @@ import org.jclouds.blobstore.domain.StorageMetadata;
|
||||||
import org.jclouds.encryption.internal.JCEEncryptionService;
|
import org.jclouds.encryption.internal.JCEEncryptionService;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
import com.google.common.base.Throwables;
|
|
||||||
import com.google.common.collect.Iterables;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
|
@ -80,7 +80,8 @@ public class BaseContainerIntegrationTest 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(new JCEEncryptionService().md5(TEST_STRING.getBytes()));
|
object.getMetadata()
|
||||||
|
.setContentMD5(new JCEEncryptionService().md5(toInputStream(TEST_STRING)));
|
||||||
String containerName = getContainerName();
|
String containerName = getContainerName();
|
||||||
try {
|
try {
|
||||||
addBlobToContainer(containerName, object);
|
addBlobToContainer(containerName, object);
|
||||||
|
@ -89,13 +90,13 @@ public class BaseContainerIntegrationTest extends BaseBlobStoreIntegrationTest {
|
||||||
PageSet<? extends StorageMetadata> container = context.getBlobStore().list(containerName,
|
PageSet<? extends StorageMetadata> container = context.getBlobStore().list(containerName,
|
||||||
maxResults(1).withDetails());
|
maxResults(1).withDetails());
|
||||||
|
|
||||||
BlobMetadata metadata = BlobMetadata.class.cast(Iterables.get(container, 0));
|
BlobMetadata metadata = BlobMetadata.class.cast(get(container, 0));
|
||||||
|
|
||||||
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(), new JCEEncryptionService().md5(TEST_STRING
|
assertEquals(metadata.getContentMD5(), new JCEEncryptionService()
|
||||||
.getBytes()));
|
.md5(toInputStream(TEST_STRING)));
|
||||||
} finally {
|
} finally {
|
||||||
returnContainer(containerName);
|
returnContainer(containerName);
|
||||||
}
|
}
|
||||||
|
@ -304,7 +305,7 @@ public class BaseContainerIntegrationTest extends BaseBlobStoreIntegrationTest {
|
||||||
assert !context.getBlobStore().containerExists(containerName) : "container "
|
assert !context.getBlobStore().containerExists(containerName) : "container "
|
||||||
+ containerName + " still exists";
|
+ containerName + " still exists";
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Throwables.propagateIfPossible(e);
|
propagateIfPossible(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -134,7 +134,8 @@ public class SignedHeaderAuth implements HttpRequestFilter {
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
String hashPath(String path) {
|
String hashPath(String path) {
|
||||||
try {
|
try {
|
||||||
return encryptionService.sha1Base64(Utils.toInputStream(canonicalPath(path)));
|
return encryptionService.base64(encryptionService.sha1(Utils
|
||||||
|
.toInputStream(canonicalPath(path))));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Throwables.propagateIfPossible(e);
|
Throwables.propagateIfPossible(e);
|
||||||
throw new HttpException("error creating sigature for path: " + path, e);
|
throw new HttpException("error creating sigature for path: " + path, e);
|
||||||
|
@ -159,7 +160,7 @@ public class SignedHeaderAuth implements HttpRequestFilter {
|
||||||
checkArgument(payload != null, "payload was null");
|
checkArgument(payload != null, "payload was null");
|
||||||
checkArgument(payload.isRepeatable(), "payload must be repeatable: " + payload);
|
checkArgument(payload.isRepeatable(), "payload must be repeatable: " + payload);
|
||||||
try {
|
try {
|
||||||
return encryptionService.sha1Base64(payload.getInput());
|
return encryptionService.base64(encryptionService.sha1(payload.getInput()));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Throwables.propagateIfPossible(e);
|
Throwables.propagateIfPossible(e);
|
||||||
throw new HttpException("error creating sigature for payload: " + payload, e);
|
throw new HttpException("error creating sigature for payload: " + payload, e);
|
||||||
|
@ -187,8 +188,8 @@ public class SignedHeaderAuth implements HttpRequestFilter {
|
||||||
|
|
||||||
public String sign(String toSign) {
|
public String sign(String toSign) {
|
||||||
try {
|
try {
|
||||||
byte[] encrypted = encryptionService.rsaPrivateEncrypt(toSign, privateKey);
|
byte[] encrypted = encryptionService.rsaSign(toSign, privateKey);
|
||||||
return encryptionService.toBase64String(encrypted);
|
return encryptionService.base64(encrypted);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new HttpException("error signing request", e);
|
throw new HttpException("error signing request", e);
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@ import static org.testng.Assert.assertNotNull;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
@ -36,7 +37,6 @@ import org.jclouds.chef.domain.Resource;
|
||||||
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
|
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
|
||||||
import org.jclouds.rest.RestContext;
|
import org.jclouds.rest.RestContext;
|
||||||
import org.jclouds.rest.RestContextFactory;
|
import org.jclouds.rest.RestContextFactory;
|
||||||
import org.jclouds.util.Utils;
|
|
||||||
import org.testng.annotations.AfterClass;
|
import org.testng.annotations.AfterClass;
|
||||||
import org.testng.annotations.BeforeClass;
|
import org.testng.annotations.BeforeClass;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
@ -135,7 +135,13 @@ public class ChefClientLiveTest {
|
||||||
cookbookO.getRecipes()).addAll(cookbookO.getResources()).addAll(
|
cookbookO.getRecipes()).addAll(cookbookO.getResources()).addAll(
|
||||||
cookbookO.getRootFiles()).addAll(cookbookO.getTemplates()).build()) {
|
cookbookO.getRootFiles()).addAll(cookbookO.getTemplates()).build()) {
|
||||||
try {
|
try {
|
||||||
Utils.toStringAndClose(adminConnection.utils().http().get(resource.getUrl()));
|
|
||||||
|
InputStream stream = adminConnection.utils().http().get(resource.getUrl());
|
||||||
|
byte[] md5 = adminConnection.utils().encryption().sha256(stream);
|
||||||
|
String md5Hex = adminConnection.utils().encryption().hex(md5);
|
||||||
|
assert md5Hex.equals(resource.getChecksum()) : String.format(
|
||||||
|
"hex for %s was: %s should be %s ", resource, md5Hex, resource
|
||||||
|
.getChecksum());
|
||||||
} catch (NullPointerException e) {
|
} catch (NullPointerException e) {
|
||||||
assert false : "resource not found: " + resource;
|
assert false : "resource not found: " + resource;
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,15 +24,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
import java.io.FilterOutputStream;
|
import java.io.FilterOutputStream;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.io.UnsupportedEncodingException;
|
|
||||||
import java.security.InvalidKeyException;
|
|
||||||
import java.security.Key;
|
import java.security.Key;
|
||||||
import java.security.NoSuchAlgorithmException;
|
|
||||||
import java.security.NoSuchProviderException;
|
|
||||||
|
|
||||||
import javax.crypto.BadPaddingException;
|
|
||||||
import javax.crypto.IllegalBlockSizeException;
|
|
||||||
import javax.crypto.NoSuchPaddingException;
|
|
||||||
|
|
||||||
import org.jclouds.encryption.internal.JCEEncryptionService;
|
import org.jclouds.encryption.internal.JCEEncryptionService;
|
||||||
|
|
||||||
|
@ -44,35 +36,27 @@ import com.google.inject.ImplementedBy;
|
||||||
*/
|
*/
|
||||||
@ImplementedBy(JCEEncryptionService.class)
|
@ImplementedBy(JCEEncryptionService.class)
|
||||||
public interface EncryptionService {
|
public interface EncryptionService {
|
||||||
|
String base64(byte[] toEncode);
|
||||||
|
|
||||||
String toHexString(byte[] raw);
|
byte[] fromBase64(String encoded);
|
||||||
|
|
||||||
byte[] fromHexString(String hex);
|
String hex(byte[] toEncode);
|
||||||
|
|
||||||
String hmacSha256Base64(String toEncode, byte[] key) throws NoSuchAlgorithmException,
|
byte[] fromHex(String encoded);
|
||||||
NoSuchProviderException, InvalidKeyException;
|
|
||||||
|
|
||||||
String sha1Base64(InputStream toEncode) throws NoSuchAlgorithmException, NoSuchProviderException,
|
byte[] rsaSign(String toSign, Key privateKey);
|
||||||
InvalidKeyException;
|
|
||||||
|
|
||||||
String hmacSha1Base64(String toEncode, byte[] key) throws NoSuchAlgorithmException,
|
byte[] hmacSha256(String toEncode, byte[] key);
|
||||||
NoSuchProviderException, InvalidKeyException;
|
|
||||||
|
|
||||||
String md5Hex(byte[] toEncode) throws NoSuchAlgorithmException, NoSuchProviderException,
|
byte[] hmacSha1(String toEncode, byte[] key);
|
||||||
InvalidKeyException, UnsupportedEncodingException;
|
|
||||||
|
|
||||||
String md5Base64(byte[] toEncode) throws NoSuchAlgorithmException, NoSuchProviderException,
|
byte[] sha1(InputStream toEncode);
|
||||||
InvalidKeyException;
|
|
||||||
|
|
||||||
byte[] md5(byte[] plainBytes);
|
byte[] sha256(InputStream toEncode);
|
||||||
|
|
||||||
byte[] md5(InputStream toEncode);
|
byte[] md5(InputStream toEncode);
|
||||||
|
|
||||||
String toBase64String(byte[] resBuf);
|
MD5InputStreamResult md5Result(InputStream toEncode);
|
||||||
|
|
||||||
byte[] md5(Object data);
|
|
||||||
|
|
||||||
MD5InputStreamResult generateMD5Result(InputStream toEncode);
|
|
||||||
|
|
||||||
MD5OutputStream md5OutputStream(OutputStream out);
|
MD5OutputStream md5OutputStream(OutputStream out);
|
||||||
|
|
||||||
|
@ -89,19 +73,13 @@ public interface EncryptionService {
|
||||||
public final byte[] md5;
|
public final byte[] md5;
|
||||||
public final long length;
|
public final long length;
|
||||||
|
|
||||||
public MD5InputStreamResult(byte[] data, byte[] eTag, long length) {
|
public MD5InputStreamResult(byte[] data, byte[] md5, long length) {
|
||||||
this.data = checkNotNull(data, "data");
|
this.data = checkNotNull(data, "data");
|
||||||
this.md5 = checkNotNull(eTag, "eTag");
|
this.md5 = checkNotNull(md5, "md5");
|
||||||
checkArgument(length >= 0, "length cannot me negative");
|
checkArgument(length >= 0, "length cannot me negative");
|
||||||
this.length = length;
|
this.length = length;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
byte[] fromBase64String(String encoded);
|
|
||||||
|
|
||||||
byte[] rsaPrivateEncrypt(String toSign, Key privateKey) throws NoSuchAlgorithmException,
|
|
||||||
NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException,
|
|
||||||
BadPaddingException;
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -18,22 +18,10 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.encryption.internal;
|
package org.jclouds.encryption.internal;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.FileNotFoundException;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.security.InvalidKeyException;
|
|
||||||
import java.security.NoSuchAlgorithmException;
|
|
||||||
import java.security.NoSuchProviderException;
|
|
||||||
|
|
||||||
import org.jclouds.encryption.EncryptionService;
|
import org.jclouds.encryption.EncryptionService;
|
||||||
|
|
||||||
import com.google.common.base.Throwables;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
|
@ -44,7 +32,8 @@ public abstract class BaseEncryptionService implements EncryptionService {
|
||||||
(byte) '5', (byte) '6', (byte) '7', (byte) '8', (byte) '9', (byte) 'a', (byte) 'b',
|
(byte) '5', (byte) '6', (byte) '7', (byte) '8', (byte) '9', (byte) 'a', (byte) 'b',
|
||||||
(byte) 'c', (byte) 'd', (byte) 'e', (byte) 'f' };
|
(byte) 'c', (byte) 'd', (byte) 'e', (byte) 'f' };
|
||||||
|
|
||||||
public String toHexString(byte[] raw) {
|
@Override
|
||||||
|
public String hex(byte[] raw) {
|
||||||
byte[] hex = new byte[2 * raw.length];
|
byte[] hex = new byte[2 * raw.length];
|
||||||
int index = 0;
|
int index = 0;
|
||||||
|
|
||||||
|
@ -60,7 +49,8 @@ public abstract class BaseEncryptionService implements EncryptionService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] fromHexString(String hex) {
|
@Override
|
||||||
|
public byte[] fromHex(String hex) {
|
||||||
if (hex.startsWith("0x"))
|
if (hex.startsWith("0x"))
|
||||||
hex = hex.substring(2);
|
hex = hex.substring(2);
|
||||||
byte[] bytes = new byte[hex.length() / 2];
|
byte[] bytes = new byte[hex.length() / 2];
|
||||||
|
@ -70,42 +60,4 @@ public abstract class BaseEncryptionService implements EncryptionService {
|
||||||
return bytes;
|
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) {
|
|
||||||
try {
|
|
||||||
md5 = md5(new FileInputStream((File) data));
|
|
||||||
} catch (FileNotFoundException e) {
|
|
||||||
Throwables.propagate(e);
|
|
||||||
}
|
|
||||||
} else if (data instanceof InputStream) {
|
|
||||||
md5 = md5(((InputStream) data));
|
|
||||||
} else {
|
|
||||||
throw new UnsupportedOperationException("Content not supported " + data.getClass());
|
|
||||||
}
|
|
||||||
return md5;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,15 +27,12 @@ import java.security.InvalidKeyException;
|
||||||
import java.security.Key;
|
import java.security.Key;
|
||||||
import java.security.MessageDigest;
|
import java.security.MessageDigest;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.security.NoSuchProviderException;
|
|
||||||
|
|
||||||
import javax.crypto.BadPaddingException;
|
|
||||||
import javax.crypto.Cipher;
|
import javax.crypto.Cipher;
|
||||||
import javax.crypto.IllegalBlockSizeException;
|
|
||||||
import javax.crypto.Mac;
|
import javax.crypto.Mac;
|
||||||
import javax.crypto.NoSuchPaddingException;
|
|
||||||
import javax.crypto.spec.SecretKeySpec;
|
import javax.crypto.spec.SecretKeySpec;
|
||||||
|
|
||||||
|
import com.google.common.base.Throwables;
|
||||||
import com.google.common.io.Closeables;
|
import com.google.common.io.Closeables;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -44,14 +41,14 @@ import com.google.common.io.Closeables;
|
||||||
*/
|
*/
|
||||||
public class JCEEncryptionService extends BaseEncryptionService {
|
public class JCEEncryptionService extends BaseEncryptionService {
|
||||||
|
|
||||||
public String hmacSha256Base64(String toEncode, byte[] key) throws NoSuchAlgorithmException,
|
@Override
|
||||||
NoSuchProviderException, InvalidKeyException {
|
public byte[] hmacSha256(String toEncode, byte[] key) {
|
||||||
return hmacBase64(toEncode, key, "HmacSHA256");
|
return hmac(toEncode, key, "HmacSHA256");
|
||||||
}
|
}
|
||||||
|
|
||||||
private String hmacBase64(String toEncode, byte[] key, String algorithm) {
|
@Override
|
||||||
byte[] resBuf = hmac(toEncode, key, algorithm);
|
public byte[] hmacSha1(String toEncode, byte[] key) {
|
||||||
return toBase64String(resBuf);
|
return hmac(toEncode, key, "HmacSHA1");
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] hmac(String toEncode, byte[] key, String algorithm) {
|
public byte[] hmac(String toEncode, byte[] key, String algorithm) {
|
||||||
|
@ -71,17 +68,7 @@ public class JCEEncryptionService extends BaseEncryptionService {
|
||||||
return mac.doFinal(toEncode.getBytes());
|
return mac.doFinal(toEncode.getBytes());
|
||||||
}
|
}
|
||||||
|
|
||||||
public String hmacSha1Base64(String toEncode, byte[] key) throws NoSuchAlgorithmException,
|
@Override
|
||||||
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(InputStream toEncode) {
|
public byte[] md5(InputStream toEncode) {
|
||||||
MessageDigest eTag = getDigest();
|
MessageDigest eTag = getDigest();
|
||||||
byte[] buffer = new byte[1024];
|
byte[] buffer = new byte[1024];
|
||||||
|
@ -101,11 +88,18 @@ public class JCEEncryptionService extends BaseEncryptionService {
|
||||||
return eTag.digest();
|
return eTag.digest();
|
||||||
}
|
}
|
||||||
|
|
||||||
public String toBase64String(byte[] resBuf) {
|
@Override
|
||||||
|
public String base64(byte[] resBuf) {
|
||||||
return Base64.encodeBytes(resBuf, Base64.DONT_BREAK_LINES);
|
return Base64.encodeBytes(resBuf, Base64.DONT_BREAK_LINES);
|
||||||
}
|
}
|
||||||
|
|
||||||
public MD5InputStreamResult generateMD5Result(InputStream toEncode) {
|
@Override
|
||||||
|
public byte[] fromBase64(String encoded) {
|
||||||
|
return Base64.decode(encoded);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MD5InputStreamResult md5Result(InputStream toEncode) {
|
||||||
MessageDigest eTag = getDigest();
|
MessageDigest eTag = getDigest();
|
||||||
byte[] buffer = new byte[1024];
|
byte[] buffer = new byte[1024];
|
||||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||||
|
@ -129,7 +123,7 @@ public class JCEEncryptionService extends BaseEncryptionService {
|
||||||
return new MD5InputStreamResult(out.toByteArray(), eTag.digest(), length);
|
return new MD5InputStreamResult(out.toByteArray(), eTag.digest(), length);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static MessageDigest getDigest() {
|
private static MessageDigest getDigest() {
|
||||||
MessageDigest eTag;
|
MessageDigest eTag;
|
||||||
try {
|
try {
|
||||||
eTag = MessageDigest.getInstance("MD5");
|
eTag = MessageDigest.getInstance("MD5");
|
||||||
|
@ -139,16 +133,12 @@ public class JCEEncryptionService extends BaseEncryptionService {
|
||||||
return eTag;
|
return eTag;
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] fromBase64String(String encoded) {
|
|
||||||
return Base64.decode(encoded);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MD5OutputStream md5OutputStream(OutputStream out) {
|
public MD5OutputStream md5OutputStream(OutputStream out) {
|
||||||
return new JCEMD5OutputStream(out);
|
return new JCEMD5OutputStream(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class JCEMD5OutputStream extends MD5OutputStream {
|
private static class JCEMD5OutputStream extends MD5OutputStream {
|
||||||
public JCEMD5OutputStream(OutputStream out) {
|
public JCEMD5OutputStream(OutputStream out) {
|
||||||
super(new DigestOutputStream(out, getDigest()));
|
super(new DigestOutputStream(out, getDigest()));
|
||||||
}
|
}
|
||||||
|
@ -161,9 +151,23 @@ public class JCEEncryptionService extends BaseEncryptionService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String sha1Base64(InputStream plainBytes) throws NoSuchAlgorithmException,
|
public byte[] sha1(InputStream plainBytes) {
|
||||||
NoSuchProviderException, InvalidKeyException {
|
return digest(plainBytes, "SHA1");
|
||||||
MessageDigest sha1 = MessageDigest.getInstance("SHA1");
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] sha256(InputStream plainBytes) {
|
||||||
|
return digest(plainBytes, "SHA256");
|
||||||
|
}
|
||||||
|
|
||||||
|
private byte[] digest(InputStream plainBytes, String algorithm) {
|
||||||
|
MessageDigest digest;
|
||||||
|
try {
|
||||||
|
digest = MessageDigest.getInstance(algorithm);
|
||||||
|
} catch (NoSuchAlgorithmException e1) {
|
||||||
|
Throwables.propagate(e1);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
byte[] buffer = new byte[1024];
|
byte[] buffer = new byte[1024];
|
||||||
long length = 0;
|
long length = 0;
|
||||||
int numRead = -1;
|
int numRead = -1;
|
||||||
|
@ -172,7 +176,7 @@ public class JCEEncryptionService extends BaseEncryptionService {
|
||||||
numRead = plainBytes.read(buffer);
|
numRead = plainBytes.read(buffer);
|
||||||
if (numRead > 0) {
|
if (numRead > 0) {
|
||||||
length += numRead;
|
length += numRead;
|
||||||
sha1.update(buffer, 0, numRead);
|
digest.update(buffer, 0, numRead);
|
||||||
}
|
}
|
||||||
} while (numRead != -1);
|
} while (numRead != -1);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
@ -181,15 +185,20 @@ public class JCEEncryptionService extends BaseEncryptionService {
|
||||||
Closeables.closeQuietly(plainBytes);
|
Closeables.closeQuietly(plainBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
return toBase64String(sha1.digest());
|
return digest.digest();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public byte[] rsaPrivateEncrypt(String toSign, Key key) throws NoSuchAlgorithmException,
|
public byte[] rsaSign(String toSign, Key key) {
|
||||||
NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException,
|
Cipher cipher;
|
||||||
BadPaddingException {
|
try {
|
||||||
Cipher cipher = Cipher.getInstance("RSA");
|
cipher = Cipher.getInstance("RSA");
|
||||||
cipher.init(Cipher.ENCRYPT_MODE, key);
|
cipher.init(Cipher.ENCRYPT_MODE, key);
|
||||||
return cipher.doFinal(toSign.getBytes());
|
return cipher.doFinal(toSign.getBytes());
|
||||||
|
} catch (Exception e) {
|
||||||
|
Throwables.propagate(e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,9 +54,8 @@ public class BasicAuthentication implements HttpRequestFilter {
|
||||||
@Named(PROPERTY_CREDENTIAL) String password, EncryptionService encryptionService)
|
@Named(PROPERTY_CREDENTIAL) String password, EncryptionService encryptionService)
|
||||||
throws UnsupportedEncodingException {
|
throws UnsupportedEncodingException {
|
||||||
this.credentialList = ImmutableSet.of("Basic "
|
this.credentialList = ImmutableSet.of("Basic "
|
||||||
+ encryptionService.toBase64String(String.format("%s:%s",
|
+ encryptionService.base64(String.format("%s:%s", checkNotNull(user, "user"),
|
||||||
checkNotNull(user, "user"), checkNotNull(password, "password")).getBytes(
|
checkNotNull(password, "password")).getBytes("UTF-8")));
|
||||||
"UTF-8")));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void filter(HttpRequest request) throws HttpException {
|
public void filter(HttpRequest request) throws HttpException {
|
||||||
|
|
|
@ -31,7 +31,6 @@ import org.jclouds.encryption.EncryptionService.MD5InputStreamResult;
|
||||||
import org.jclouds.http.Payload;
|
import org.jclouds.http.Payload;
|
||||||
import org.jclouds.http.PayloadEnclosing;
|
import org.jclouds.http.PayloadEnclosing;
|
||||||
import org.jclouds.http.Payloads;
|
import org.jclouds.http.Payloads;
|
||||||
import org.jclouds.http.payloads.InputStreamPayload;
|
|
||||||
|
|
||||||
import com.google.common.io.Closeables;
|
import com.google.common.io.Closeables;
|
||||||
|
|
||||||
|
@ -55,14 +54,13 @@ public abstract class BasePayloadEnclosingImpl implements PayloadEnclosing {
|
||||||
@Override
|
@Override
|
||||||
public void generateMD5() {
|
public void generateMD5() {
|
||||||
checkState(payload != null, "payload");
|
checkState(payload != null, "payload");
|
||||||
if (payload instanceof InputStreamPayload) {
|
if (!payload.isRepeatable()) {
|
||||||
MD5InputStreamResult result = encryptionService
|
MD5InputStreamResult result = encryptionService.md5Result(payload.getInput());
|
||||||
.generateMD5Result(((InputStreamPayload) payload).getInput());
|
|
||||||
setContentMD5(result.md5);
|
setContentMD5(result.md5);
|
||||||
setContentLength(result.length);
|
setContentLength(result.length);
|
||||||
setPayload(result.data);
|
setPayload(result.data);
|
||||||
} else {
|
} else {
|
||||||
setContentMD5(encryptionService.md5(payload.getRawContent()));
|
setContentMD5(encryptionService.md5(payload.getInput()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@ package org.jclouds.encryption;
|
||||||
|
|
||||||
import static org.testng.Assert.assertEquals;
|
import static org.testng.Assert.assertEquals;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
|
@ -84,7 +85,7 @@ public class EncryptionServiceTest extends PerformanceTest {
|
||||||
@Test(dataProvider = "hmacsha1")
|
@Test(dataProvider = "hmacsha1")
|
||||||
public void testHmacSha1Base64(byte[] key, String message, String base64Digest)
|
public void testHmacSha1Base64(byte[] key, String message, String base64Digest)
|
||||||
throws NoSuchProviderException, NoSuchAlgorithmException, InvalidKeyException {
|
throws NoSuchProviderException, NoSuchAlgorithmException, InvalidKeyException {
|
||||||
String b64 = encryptionService.hmacSha1Base64(message, key);
|
String b64 = encryptionService.base64(encryptionService.hmacSha1(message, key));
|
||||||
assertEquals(b64, base64Digest);
|
assertEquals(b64, base64Digest);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,14 +127,15 @@ public class EncryptionServiceTest extends PerformanceTest {
|
||||||
@Test(dataProvider = "eTag")
|
@Test(dataProvider = "eTag")
|
||||||
public void testMD5Digest(String message, String hexMD5Digest) throws NoSuchProviderException,
|
public void testMD5Digest(String message, String hexMD5Digest) throws NoSuchProviderException,
|
||||||
NoSuchAlgorithmException, InvalidKeyException, IOException {
|
NoSuchAlgorithmException, InvalidKeyException, IOException {
|
||||||
String b64 = encryptionService.md5Hex(message.getBytes());
|
String b64 = encryptionService.hex(encryptionService.md5(new ByteArrayInputStream(message
|
||||||
|
.getBytes())));
|
||||||
assertEquals(hexMD5Digest, b64);
|
assertEquals(hexMD5Digest, b64);
|
||||||
|
|
||||||
MD5OutputStream outputStream = encryptionService.md5OutputStream(new ByteArrayOutputStream());
|
MD5OutputStream outputStream = encryptionService.md5OutputStream(new ByteArrayOutputStream());
|
||||||
ByteStreams.copy(ByteStreams.newInputStreamSupplier(message.getBytes()).getInput(),
|
ByteStreams.copy(ByteStreams.newInputStreamSupplier(message.getBytes()).getInput(),
|
||||||
outputStream);
|
outputStream);
|
||||||
|
|
||||||
assertEquals(encryptionService.fromHexString(hexMD5Digest), outputStream.getMD5());
|
assertEquals(encryptionService.fromHex(hexMD5Digest), outputStream.getMD5());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -141,14 +143,14 @@ public class EncryptionServiceTest extends PerformanceTest {
|
||||||
String hex = "0001020408102040";
|
String hex = "0001020408102040";
|
||||||
|
|
||||||
public void testHexStringEncode() throws UnsupportedEncodingException {
|
public void testHexStringEncode() throws UnsupportedEncodingException {
|
||||||
assertEquals(encryptionService.toHexString(bytes), hex);
|
assertEquals(encryptionService.hex(bytes), hex);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testHexStringDecode() throws UnsupportedEncodingException {
|
public void testHexStringDecode() throws UnsupportedEncodingException {
|
||||||
assertEquals(encryptionService.fromHexString(hex), bytes);
|
assertEquals(encryptionService.fromHex(hex), bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testHexStringDecodeOx() throws UnsupportedEncodingException {
|
public void testHexStringDecodeOx() throws UnsupportedEncodingException {
|
||||||
assertEquals(encryptionService.fromHexString("0x" + hex), bytes);
|
assertEquals(encryptionService.fromHex("0x" + hex), bytes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,11 +29,11 @@ import java.io.OutputStream;
|
||||||
import java.net.MalformedURLException;
|
import java.net.MalformedURLException;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.security.MessageDigest;
|
import java.security.MessageDigest;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.concurrent.TimeoutException;
|
import java.util.concurrent.TimeoutException;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
import org.jclouds.encryption.internal.JCEEncryptionService;
|
|
||||||
import org.jclouds.http.options.GetOptions;
|
import org.jclouds.http.options.GetOptions;
|
||||||
import org.testng.annotations.BeforeTest;
|
import org.testng.annotations.BeforeTest;
|
||||||
import org.testng.annotations.DataProvider;
|
import org.testng.annotations.DataProvider;
|
||||||
|
@ -43,80 +43,77 @@ import com.google.common.collect.ImmutableMap;
|
||||||
import com.google.common.io.Closeables;
|
import com.google.common.io.Closeables;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests for functionality all HttpCommandExecutorServices must express. These
|
* Tests for functionality all HttpCommandExecutorServices must express. These tests will operate
|
||||||
* tests will operate against an in-memory http engine, so as to ensure
|
* against an in-memory http engine, so as to ensure end-to-end functionality works.
|
||||||
* end-to-end functionality works.
|
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
@Test(threadPoolSize = 10, groups = "integration", sequential = true)
|
@Test(threadPoolSize = 10, groups = "integration", sequential = true)
|
||||||
public abstract class BaseHttpCommandExecutorServiceIntegrationTest extends
|
public abstract class BaseHttpCommandExecutorServiceIntegrationTest extends BaseJettyTest {
|
||||||
BaseJettyTest {
|
|
||||||
|
|
||||||
@Test(invocationCount = 25, timeOut = 5000)
|
@Test(invocationCount = 25, timeOut = 5000)
|
||||||
public void testRequestFilter() throws MalformedURLException,
|
public void testRequestFilter() throws MalformedURLException, ExecutionException,
|
||||||
ExecutionException, InterruptedException, TimeoutException {
|
InterruptedException, TimeoutException {
|
||||||
assertEquals(client.downloadFilter("", "filterme").trim(), "test");
|
assertEquals(client.downloadFilter("", "filterme").trim(), "test");
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: filtering redirect test
|
// TODO: filtering redirect test
|
||||||
|
|
||||||
@Test(invocationCount = 25, timeOut = 5000)
|
@Test(invocationCount = 25, timeOut = 5000)
|
||||||
public void testGetStringWithHeader() throws MalformedURLException,
|
public void testGetStringWithHeader() throws MalformedURLException, ExecutionException,
|
||||||
ExecutionException, InterruptedException, TimeoutException {
|
InterruptedException, TimeoutException {
|
||||||
assertEquals(client.download("", "test").trim(), "test");
|
assertEquals(client.download("", "test").trim(), "test");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(invocationCount = 25, timeOut = 5000)
|
@Test(invocationCount = 25, timeOut = 5000)
|
||||||
public void testGetString() throws MalformedURLException,
|
public void testGetString() throws MalformedURLException, ExecutionException,
|
||||||
ExecutionException, InterruptedException, TimeoutException {
|
InterruptedException, TimeoutException {
|
||||||
assertEquals(client.download("").trim(), XML);
|
assertEquals(client.download("").trim(), XML);
|
||||||
}
|
}
|
||||||
|
|
||||||
@DataProvider(name = "gets")
|
@DataProvider(name = "gets")
|
||||||
public Object[][] createData() {
|
public Object[][] createData() {
|
||||||
return new Object[][] { { "object" }, { "/path" }, { "sp ace" },
|
return new Object[][] { { "object" }, { "/path" }, { "sp ace" }, { "unic₪de" },
|
||||||
{ "unic₪de" }, { "qu?stion" } };
|
{ "qu?stion" } };
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(invocationCount = 25, timeOut = 5000, dataProvider = "gets")
|
@Test(invocationCount = 25, timeOut = 5000, dataProvider = "gets")
|
||||||
public void testGetStringSynch(String uri) throws MalformedURLException,
|
public void testGetStringSynch(String uri) throws MalformedURLException, ExecutionException,
|
||||||
ExecutionException, InterruptedException, TimeoutException {
|
InterruptedException, TimeoutException {
|
||||||
// TODO why need trim?
|
// TODO why need trim?
|
||||||
assertEquals(client.synch(uri).trim(), XML);
|
assertEquals(client.synch(uri).trim(), XML);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(invocationCount = 25, timeOut = 5000)
|
@Test(invocationCount = 25, timeOut = 5000)
|
||||||
public void testGetException() throws MalformedURLException,
|
public void testGetException() throws MalformedURLException, ExecutionException,
|
||||||
ExecutionException, InterruptedException, TimeoutException {
|
InterruptedException, TimeoutException {
|
||||||
assertEquals(client.downloadException("", GetOptions.Builder.tail(1))
|
assertEquals(client.downloadException("", GetOptions.Builder.tail(1)).trim(), "foo");
|
||||||
.trim(), "foo");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(invocationCount = 25, timeOut = 5000)
|
@Test(invocationCount = 25, timeOut = 5000)
|
||||||
public void testGetSynchException() throws MalformedURLException,
|
public void testGetSynchException() throws MalformedURLException, ExecutionException,
|
||||||
ExecutionException, InterruptedException, TimeoutException {
|
InterruptedException, TimeoutException {
|
||||||
assertEquals(client.synchException("", "").trim(), "foo");
|
assertEquals(client.synchException("", "").trim(), "foo");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(invocationCount = 25, timeOut = 5000)
|
@Test(invocationCount = 25, timeOut = 5000)
|
||||||
public void testGetStringRedirect() throws MalformedURLException,
|
public void testGetStringRedirect() throws MalformedURLException, ExecutionException,
|
||||||
ExecutionException, InterruptedException, TimeoutException {
|
InterruptedException, TimeoutException {
|
||||||
assertEquals(client.download("redirect").trim(), XML2);
|
assertEquals(client.download("redirect").trim(), XML2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(invocationCount = 100, timeOut = 5000)
|
@Test(invocationCount = 100, timeOut = 5000)
|
||||||
public void testGetBigFile() throws MalformedURLException,
|
public void testGetBigFile() throws MalformedURLException, ExecutionException,
|
||||||
ExecutionException, InterruptedException, TimeoutException {
|
InterruptedException, TimeoutException {
|
||||||
assertEquals(encryptionService.toBase64String(encryptionService
|
assertEquals(
|
||||||
.md5(context.utils().http().get(
|
encryptionService.base64(encryptionService.md5(context.utils().http().get(
|
||||||
URI.create(String.format("http://localhost:%d/%s", testPort,
|
URI.create(String.format("http://localhost:%d/%s", testPort,
|
||||||
"101constitutions"))))), md5);
|
"101constitutions"))))), md5);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(enabled = false, invocationCount = 25, timeOut = 5000)
|
@Test(enabled = false, invocationCount = 25, timeOut = 5000)
|
||||||
public void testGetStringPermanentRedirect() throws MalformedURLException,
|
public void testGetStringPermanentRedirect() throws MalformedURLException, ExecutionException,
|
||||||
ExecutionException, InterruptedException, TimeoutException {
|
InterruptedException, TimeoutException {
|
||||||
// GetString get = factory.createGetString("permanentredirect");
|
// GetString get = factory.createGetString("permanentredirect");
|
||||||
// assert get != null;
|
// assert get != null;
|
||||||
// client.submit(get);
|
// client.submit(get);
|
||||||
|
@ -126,14 +123,14 @@ public abstract class BaseHttpCommandExecutorServiceIntegrationTest extends
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(invocationCount = 25, timeOut = 5000)
|
@Test(invocationCount = 25, timeOut = 5000)
|
||||||
public void testPost() throws MalformedURLException, ExecutionException,
|
public void testPost() throws MalformedURLException, ExecutionException, InterruptedException,
|
||||||
InterruptedException, TimeoutException {
|
TimeoutException {
|
||||||
assertEquals(client.post("", "foo").trim(), "fooPOST");
|
assertEquals(client.post("", "foo").trim(), "fooPOST");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(invocationCount = 25, timeOut = 10000)
|
@Test(invocationCount = 25, timeOut = 10000)
|
||||||
public void testPostAsInputStream() throws MalformedURLException,
|
public void testPostAsInputStream() throws MalformedURLException, ExecutionException,
|
||||||
ExecutionException, InterruptedException, TimeoutException {
|
InterruptedException, TimeoutException {
|
||||||
try {
|
try {
|
||||||
assertEquals(client.postAsInputStream("", "foo").trim(), "fooPOST");
|
assertEquals(client.postAsInputStream("", "foo").trim(), "fooPOST");
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
@ -142,8 +139,8 @@ public abstract class BaseHttpCommandExecutorServiceIntegrationTest extends
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests sending a big file to the server. Note: this is a heavy test, takes
|
* Tests sending a big file to the server. Note: this is a heavy test, takes several minutes to
|
||||||
* several minutes to finish.
|
* finish.
|
||||||
*
|
*
|
||||||
* @throws java.io.IOException
|
* @throws java.io.IOException
|
||||||
*/
|
*/
|
||||||
|
@ -157,10 +154,14 @@ public abstract class BaseHttpCommandExecutorServiceIntegrationTest extends
|
||||||
f = File.createTempFile(filename, "tmp");
|
f = File.createTempFile(filename, "tmp");
|
||||||
f.deleteOnExit();
|
f.deleteOnExit();
|
||||||
long length = (long) (Runtime.getRuntime().freeMemory() * 1.1);
|
long length = (long) (Runtime.getRuntime().freeMemory() * 1.1);
|
||||||
os = new BufferedOutputStream(
|
os = new BufferedOutputStream(new FileOutputStream(f.getAbsolutePath()));
|
||||||
new FileOutputStream(f.getAbsolutePath()));
|
MessageDigest eTag;
|
||||||
|
try {
|
||||||
|
eTag = MessageDigest.getInstance("MD5");
|
||||||
|
} catch (NoSuchAlgorithmException e) {
|
||||||
|
throw new RuntimeException("Could not find the MD5 algorithm", e);
|
||||||
|
}
|
||||||
|
|
||||||
MessageDigest eTag = JCEEncryptionService.getDigest();
|
|
||||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||||
try {
|
try {
|
||||||
for (long i = 0; i < length; i++) {
|
for (long i = 0; i < length; i++) {
|
||||||
|
@ -175,9 +176,8 @@ public abstract class BaseHttpCommandExecutorServiceIntegrationTest extends
|
||||||
}
|
}
|
||||||
|
|
||||||
// upload and verify the response
|
// upload and verify the response
|
||||||
assertEquals(client.postWithMd5("fileso",
|
assertEquals(client.postWithMd5("fileso", this.encryptionService.base64(eTag.digest()),
|
||||||
this.encryptionService.toBase64String(eTag.digest()), f).trim(),
|
f).trim(), "created");
|
||||||
"created");
|
|
||||||
|
|
||||||
} finally {
|
} finally {
|
||||||
if (os != null)
|
if (os != null)
|
||||||
|
@ -201,40 +201,39 @@ public abstract class BaseHttpCommandExecutorServiceIntegrationTest extends
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(invocationCount = 25, timeOut = 5000)
|
@Test(invocationCount = 25, timeOut = 5000)
|
||||||
public void testPostBinder() throws MalformedURLException,
|
public void testPostBinder() throws MalformedURLException, ExecutionException,
|
||||||
ExecutionException, InterruptedException, TimeoutException {
|
InterruptedException, TimeoutException {
|
||||||
assertEquals(client.postJson("", "foo").trim(), "{\"key\":\"foo\"}POST");
|
assertEquals(client.postJson("", "foo").trim(), "{\"key\":\"foo\"}POST");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(invocationCount = 25, timeOut = 5000)
|
@Test(invocationCount = 25, timeOut = 5000)
|
||||||
public void testPut() throws MalformedURLException, ExecutionException,
|
public void testPut() throws MalformedURLException, ExecutionException, InterruptedException,
|
||||||
InterruptedException, TimeoutException {
|
TimeoutException {
|
||||||
assertEquals(client.upload("", "foo").trim(), "fooPUT");
|
assertEquals(client.upload("", "foo").trim(), "fooPUT");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(invocationCount = 25, timeOut = 5000)
|
@Test(invocationCount = 25, timeOut = 5000)
|
||||||
public void testPutRedirect() throws MalformedURLException,
|
public void testPutRedirect() throws MalformedURLException, ExecutionException,
|
||||||
ExecutionException, InterruptedException, TimeoutException {
|
InterruptedException, TimeoutException {
|
||||||
assertEquals(client.upload("redirect", "foo").trim(), "fooPUTREDIRECT");
|
assertEquals(client.upload("redirect", "foo").trim(), "fooPUTREDIRECT");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(invocationCount = 25, timeOut = 5000)
|
@Test(invocationCount = 25, timeOut = 5000)
|
||||||
public void testKillRobotSlowly() throws MalformedURLException,
|
public void testKillRobotSlowly() throws MalformedURLException, ExecutionException,
|
||||||
ExecutionException, InterruptedException, TimeoutException {
|
InterruptedException, TimeoutException {
|
||||||
assertEquals(client.action("robot", "kill",
|
assertEquals(client.action("robot", "kill", ImmutableMap.of("death", "slow")).trim(),
|
||||||
ImmutableMap.of("death", "slow")).trim(),
|
"robot->kill:{death=slow}");
|
||||||
"robot->kill:{death=slow}");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(invocationCount = 25, timeOut = 5000)
|
@Test(invocationCount = 25, timeOut = 5000)
|
||||||
public void testHead() throws MalformedURLException, ExecutionException,
|
public void testHead() throws MalformedURLException, ExecutionException, InterruptedException,
|
||||||
InterruptedException, TimeoutException {
|
TimeoutException {
|
||||||
assert client.exists("");
|
assert client.exists("");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(invocationCount = 25, timeOut = 5000)
|
@Test(invocationCount = 25, timeOut = 5000)
|
||||||
public void testGetAndParseSax() throws MalformedURLException,
|
public void testGetAndParseSax() throws MalformedURLException, ExecutionException,
|
||||||
ExecutionException, InterruptedException, TimeoutException {
|
InterruptedException, TimeoutException {
|
||||||
assertEquals(client.downloadAndParse(""), "whoppers");
|
assertEquals(client.downloadAndParse(""), "whoppers");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -85,8 +85,8 @@ public abstract class BaseJettyTest {
|
||||||
|
|
||||||
encryptionService = Guice.createInjector().getInstance(EncryptionService.class);
|
encryptionService = Guice.createInjector().getInstance(EncryptionService.class);
|
||||||
|
|
||||||
md5 = encryptionService.md5Base64(ByteStreams.toByteArray(oneHundredOneConstitutions
|
md5 = encryptionService
|
||||||
.getInput()));
|
.base64(encryptionService.md5(oneHundredOneConstitutions.getInput()));
|
||||||
|
|
||||||
Handler server1Handler = new AbstractHandler() {
|
Handler server1Handler = new AbstractHandler() {
|
||||||
public void handle(String target, HttpServletRequest request,
|
public void handle(String target, HttpServletRequest request,
|
||||||
|
|
|
@ -65,7 +65,7 @@ public class WireLiveTest {
|
||||||
ByteStreams.copy(in, out);
|
ByteStreams.copy(in, out);
|
||||||
byte[] compare = encryptionService.md5(new ByteArrayInputStream(out.toByteArray()));
|
byte[] compare = encryptionService.md5(new ByteArrayInputStream(out.toByteArray()));
|
||||||
Thread.sleep(100);
|
Thread.sleep(100);
|
||||||
assertEquals(encryptionService.toHexString(compare), checkNotNull(sysHttpStreamMd5,
|
assertEquals(encryptionService.hex(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;
|
||||||
|
@ -145,7 +145,7 @@ public class WireLiveTest {
|
||||||
InputStream in = wire.input(connection.getInputStream());
|
InputStream in = wire.input(connection.getInputStream());
|
||||||
byte[] compare = encryptionService.md5(in);
|
byte[] compare = encryptionService.md5(in);
|
||||||
Thread.sleep(100);
|
Thread.sleep(100);
|
||||||
assertEquals(encryptionService.toHexString(compare), checkNotNull(sysHttpStreamMd5,
|
assertEquals(encryptionService.hex(compare), checkNotNull(sysHttpStreamMd5,
|
||||||
sysHttpStreamMd5));
|
sysHttpStreamMd5));
|
||||||
assertEquals(((BufferLogger) wire.getWireLog()).buff.toString().getBytes().length, 3331484);
|
assertEquals(((BufferLogger) wire.getWireLog()).buff.toString().getBytes().length, 3331484);
|
||||||
}
|
}
|
||||||
|
@ -168,7 +168,7 @@ public class WireLiveTest {
|
||||||
InputStream in = wire.input(connection.getInputStream());
|
InputStream in = wire.input(connection.getInputStream());
|
||||||
byte[] compare = encryptionService.md5(in);
|
byte[] compare = encryptionService.md5(in);
|
||||||
Thread.sleep(100);
|
Thread.sleep(100);
|
||||||
assertEquals(encryptionService.toHexString(compare), checkNotNull(sysHttpStreamMd5,
|
assertEquals(encryptionService.hex(compare), checkNotNull(sysHttpStreamMd5,
|
||||||
sysHttpStreamMd5));
|
sysHttpStreamMd5));
|
||||||
assertEquals(((BufferLogger) wire.getWireLog()).buff.toString().getBytes().length, 3331484);
|
assertEquals(((BufferLogger) wire.getWireLog()).buff.toString().getBytes().length, 3331484);
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,15 +22,9 @@ import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.security.InvalidKeyException;
|
|
||||||
import java.security.Key;
|
import java.security.Key;
|
||||||
import java.security.NoSuchAlgorithmException;
|
|
||||||
import java.security.NoSuchProviderException;
|
|
||||||
|
|
||||||
import javax.crypto.BadPaddingException;
|
|
||||||
import javax.crypto.Cipher;
|
import javax.crypto.Cipher;
|
||||||
import javax.crypto.IllegalBlockSizeException;
|
|
||||||
import javax.crypto.NoSuchPaddingException;
|
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
import org.bouncycastle.crypto.Digest;
|
import org.bouncycastle.crypto.Digest;
|
||||||
|
@ -44,6 +38,7 @@ import org.bouncycastle.util.encoders.Base64;
|
||||||
import org.jclouds.encryption.internal.BaseEncryptionService;
|
import org.jclouds.encryption.internal.BaseEncryptionService;
|
||||||
import org.jclouds.util.Utils;
|
import org.jclouds.util.Utils;
|
||||||
|
|
||||||
|
import com.google.common.base.Throwables;
|
||||||
import com.google.common.io.Closeables;
|
import com.google.common.io.Closeables;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -52,15 +47,15 @@ import com.google.common.io.Closeables;
|
||||||
*/
|
*/
|
||||||
@Singleton
|
@Singleton
|
||||||
public class BouncyCastleEncryptionService extends BaseEncryptionService {
|
public class BouncyCastleEncryptionService extends BaseEncryptionService {
|
||||||
public String hmacSha256Base64(String toEncode, byte[] key) throws NoSuchAlgorithmException,
|
|
||||||
NoSuchProviderException, InvalidKeyException {
|
@Override
|
||||||
Digest digest = new SHA256Digest();
|
public byte[] hmacSha256(String toEncode, byte[] key) {
|
||||||
return hmacBase64(toEncode, key, digest);
|
return hmac(toEncode, key, new SHA256Digest());
|
||||||
}
|
}
|
||||||
|
|
||||||
private String hmacBase64(String toEncode, byte[] key, Digest digest) {
|
@Override
|
||||||
byte[] resBuf = hmac(toEncode, key, digest);
|
public byte[] hmacSha1(String toEncode, byte[] key) {
|
||||||
return toBase64String(resBuf);
|
return hmac(toEncode, key, new SHA1Digest());
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] hmac(String toEncode, byte[] key, Digest digest) {
|
public byte[] hmac(String toEncode, byte[] key, Digest digest) {
|
||||||
|
@ -74,20 +69,7 @@ public class BouncyCastleEncryptionService extends BaseEncryptionService {
|
||||||
return resBuf;
|
return resBuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String hmacSha1Base64(String toEncode, byte[] key) throws NoSuchAlgorithmException,
|
@Override
|
||||||
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(InputStream toEncode) {
|
public byte[] md5(InputStream toEncode) {
|
||||||
MD5Digest eTag = new MD5Digest();
|
MD5Digest eTag = new MD5Digest();
|
||||||
byte[] resBuf = new byte[eTag.getDigestSize()];
|
byte[] resBuf = new byte[eTag.getDigestSize()];
|
||||||
|
@ -109,11 +91,13 @@ public class BouncyCastleEncryptionService extends BaseEncryptionService {
|
||||||
return resBuf;
|
return resBuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String toBase64String(byte[] resBuf) {
|
@Override
|
||||||
|
public String base64(byte[] resBuf) {
|
||||||
return new String(Base64.encode(resBuf));
|
return new String(Base64.encode(resBuf));
|
||||||
}
|
}
|
||||||
|
|
||||||
public MD5InputStreamResult generateMD5Result(InputStream toEncode) {
|
@Override
|
||||||
|
public MD5InputStreamResult md5Result(InputStream toEncode) {
|
||||||
MD5Digest eTag = new MD5Digest();
|
MD5Digest eTag = new MD5Digest();
|
||||||
byte[] resBuf = new byte[eTag.getDigestSize()];
|
byte[] resBuf = new byte[eTag.getDigestSize()];
|
||||||
byte[] buffer = new byte[1024];
|
byte[] buffer = new byte[1024];
|
||||||
|
@ -139,7 +123,8 @@ public class BouncyCastleEncryptionService extends BaseEncryptionService {
|
||||||
return new MD5InputStreamResult(out.toByteArray(), resBuf, length);
|
return new MD5InputStreamResult(out.toByteArray(), resBuf, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] fromBase64String(String encoded) {
|
@Override
|
||||||
|
public byte[] fromBase64(String encoded) {
|
||||||
return Base64.decode(encoded);
|
return Base64.decode(encoded);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -148,7 +133,7 @@ public class BouncyCastleEncryptionService extends BaseEncryptionService {
|
||||||
return new BouncyCastleMD5OutputStream(out);
|
return new BouncyCastleMD5OutputStream(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class BouncyCastleMD5OutputStream extends MD5OutputStream {
|
private static class BouncyCastleMD5OutputStream extends MD5OutputStream {
|
||||||
public BouncyCastleMD5OutputStream(OutputStream out) {
|
public BouncyCastleMD5OutputStream(OutputStream out) {
|
||||||
super(new DigestOutputStream(out, new MD5Digest()));
|
super(new DigestOutputStream(out, new MD5Digest()));
|
||||||
}
|
}
|
||||||
|
@ -163,9 +148,16 @@ public class BouncyCastleEncryptionService extends BaseEncryptionService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String sha1Base64(InputStream plainBytes) throws NoSuchAlgorithmException,
|
public byte[] sha256(InputStream plainBytes) {
|
||||||
NoSuchProviderException, InvalidKeyException {
|
return sha(plainBytes, new SHA256Digest());
|
||||||
Digest digest = new SHA1Digest();
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] sha1(InputStream plainBytes) {
|
||||||
|
return sha(plainBytes, new SHA1Digest());
|
||||||
|
}
|
||||||
|
|
||||||
|
private byte[] sha(InputStream plainBytes, Digest digest) {
|
||||||
byte[] resBuf = new byte[digest.getDigestSize()];
|
byte[] resBuf = new byte[digest.getDigestSize()];
|
||||||
byte[] buffer = new byte[1024];
|
byte[] buffer = new byte[1024];
|
||||||
long length = 0;
|
long length = 0;
|
||||||
|
@ -184,16 +176,20 @@ public class BouncyCastleEncryptionService extends BaseEncryptionService {
|
||||||
Closeables.closeQuietly(plainBytes);
|
Closeables.closeQuietly(plainBytes);
|
||||||
}
|
}
|
||||||
digest.doFinal(resBuf, 0);
|
digest.doFinal(resBuf, 0);
|
||||||
return toBase64String(resBuf);
|
return resBuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public byte[] rsaPrivateEncrypt(String toSign, Key key) throws NoSuchAlgorithmException,
|
public byte[] rsaSign(String toSign, Key key) {
|
||||||
NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException,
|
|
||||||
BadPaddingException {
|
|
||||||
// TODO convert this to BC code
|
// TODO convert this to BC code
|
||||||
Cipher cipher = Cipher.getInstance("RSA");
|
try {
|
||||||
cipher.init(Cipher.ENCRYPT_MODE, key);
|
Cipher cipher = Cipher.getInstance("RSA");
|
||||||
return cipher.doFinal(toSign.getBytes());
|
cipher.init(Cipher.ENCRYPT_MODE, key);
|
||||||
|
return cipher.doFinal(toSign.getBytes());
|
||||||
|
} catch (Exception e) {
|
||||||
|
Throwables.propagate(e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,6 +42,7 @@ import org.jclouds.encryption.EncryptionService;
|
||||||
import org.jclouds.http.HttpRequest;
|
import org.jclouds.http.HttpRequest;
|
||||||
import org.jclouds.http.HttpRequestFilter;
|
import org.jclouds.http.HttpRequestFilter;
|
||||||
import org.jclouds.logging.Logger;
|
import org.jclouds.logging.Logger;
|
||||||
|
import org.jclouds.util.Utils;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
import com.google.common.collect.Multimap;
|
import com.google.common.collect.Multimap;
|
||||||
|
@ -95,7 +96,7 @@ public class SharedKeyLiteAuthentication implements HttpRequestFilter {
|
||||||
|
|
||||||
private String getMd5For(String stringToHash) {
|
private String getMd5For(String stringToHash) {
|
||||||
try {
|
try {
|
||||||
return encryptionService.md5Hex(stringToHash.getBytes());
|
return encryptionService.hex(encryptionService.md5(Utils.toInputStream(stringToHash)));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,7 +58,7 @@ public class BindCFObjectToPayload extends BindBlobToPayloadAndUserMetadataToHea
|
||||||
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,
|
||||||
encryptionService.toHexString(object.getInfo().getHash()));
|
encryptionService.hex(object.getInfo().getHash()));
|
||||||
request.getHeaders().removeAll("Content-MD5");
|
request.getHeaders().removeAll("Content-MD5");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -54,7 +54,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(encryptionService.toHexString(from.getHash()));
|
to.setETag(encryptionService.hex(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());
|
||||||
|
|
|
@ -56,7 +56,7 @@ public class ResourceToObjectInfo implements
|
||||||
to.setContentType("application/directory");
|
to.setContentType("application/directory");
|
||||||
}
|
}
|
||||||
if (from.getETag() != null && to.getHash() == null)
|
if (from.getETag() != null && to.getHash() == null)
|
||||||
to.setHash(encryptionService.fromHexString(from.getETag()));
|
to.setHash(encryptionService.fromHex(from.getETag()));
|
||||||
to.setName(from.getName());
|
to.setName(from.getName());
|
||||||
to.setLastModified(from.getLastModified());
|
to.setLastModified(from.getLastModified());
|
||||||
if (from.getSize() != null)
|
if (from.getSize() != null)
|
||||||
|
|
|
@ -60,7 +60,7 @@ public class ParseObjectInfoFromHeaders implements
|
||||||
String eTagHeader = from.getFirstHeaderOrNull("Etag");
|
String eTagHeader = from.getFirstHeaderOrNull("Etag");
|
||||||
if (eTagHeader != null) {
|
if (eTagHeader != null) {
|
||||||
String hashString = Utils.replaceAll(eTagHeader, '"', "");
|
String hashString = Utils.replaceAll(eTagHeader, '"', "");
|
||||||
to.setHash(encryptionService.fromHexString(hashString));
|
to.setHash(encryptionService.fromHex(hashString));
|
||||||
}
|
}
|
||||||
return to;
|
return to;
|
||||||
}
|
}
|
||||||
|
|
|
@ -82,7 +82,7 @@ public class ParseObjectInfoListFromJsonResponse extends ParseJson<PageSet<Objec
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] getHash() {
|
public byte[] getHash() {
|
||||||
return encryptionService.fromHexString(hash);
|
return encryptionService.fromHex(hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Date getLastModified() {
|
public Date getLastModified() {
|
||||||
|
|
|
@ -304,7 +304,7 @@ public class CloudFilesClientLiveTest extends BaseBlobStoreIntegrationTest {
|
||||||
CFObject object = newCFObject(data, key);
|
CFObject object = newCFObject(data, key);
|
||||||
byte[] md5 = object.getInfo().getHash();
|
byte[] md5 = object.getInfo().getHash();
|
||||||
String newEtag = getApi().putObject(containerName, object);
|
String newEtag = getApi().putObject(containerName, object);
|
||||||
assertEquals(encryptionService.toHexString(md5), encryptionService.toHexString(object
|
assertEquals(encryptionService.hex(md5), encryptionService.hex(object
|
||||||
.getInfo().getHash()));
|
.getInfo().getHash()));
|
||||||
|
|
||||||
// Test HEAD of missing object
|
// Test HEAD of missing object
|
||||||
|
@ -316,9 +316,9 @@ public class CloudFilesClientLiveTest extends BaseBlobStoreIntegrationTest {
|
||||||
// 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(encryptionService.toHexString(md5), encryptionService.toHexString(object
|
assertEquals(encryptionService.hex(md5), encryptionService.hex(object
|
||||||
.getInfo().getHash()));
|
.getInfo().getHash()));
|
||||||
assertEquals(metadata.getHash(), encryptionService.fromHexString(newEtag));
|
assertEquals(metadata.getHash(), encryptionService.fromHex(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");
|
||||||
|
|
||||||
|
@ -336,9 +336,9 @@ public class CloudFilesClientLiveTest extends BaseBlobStoreIntegrationTest {
|
||||||
// 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(encryptionService.toHexString(md5), encryptionService.toHexString(getBlob
|
assertEquals(encryptionService.hex(md5), encryptionService.hex(getBlob
|
||||||
.getInfo().getHash()));
|
.getInfo().getHash()));
|
||||||
assertEquals(encryptionService.fromHexString(newEtag), getBlob.getInfo().getHash());
|
assertEquals(encryptionService.fromHex(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");
|
||||||
|
@ -346,7 +346,7 @@ public class CloudFilesClientLiveTest extends BaseBlobStoreIntegrationTest {
|
||||||
// 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(encryptionService.fromHexString(incorrectEtag));
|
object.getInfo().setHash(encryptionService.fromHex(incorrectEtag));
|
||||||
try {
|
try {
|
||||||
getApi().putObject(containerName, object);
|
getApi().putObject(containerName, object);
|
||||||
} catch (HttpResponseException e) {
|
} catch (HttpResponseException e) {
|
||||||
|
@ -359,7 +359,7 @@ public class CloudFilesClientLiveTest extends BaseBlobStoreIntegrationTest {
|
||||||
blob.getInfo().setName("chunked-object");
|
blob.getInfo().setName("chunked-object");
|
||||||
blob.setPayload(bais);
|
blob.setPayload(bais);
|
||||||
newEtag = getApi().putObject(containerName, blob);
|
newEtag = getApi().putObject(containerName, blob);
|
||||||
assertEquals(encryptionService.toHexString(md5), encryptionService.toHexString(getBlob
|
assertEquals(encryptionService.hex(md5), encryptionService.hex(getBlob
|
||||||
.getInfo().getHash()));
|
.getInfo().getHash()));
|
||||||
|
|
||||||
// Test GET with options
|
// Test GET with options
|
||||||
|
@ -374,7 +374,7 @@ public class CloudFilesClientLiveTest extends BaseBlobStoreIntegrationTest {
|
||||||
// Matching ETag
|
// Matching ETag
|
||||||
getBlob = getApi().getObject(containerName, object.getInfo().getName(),
|
getBlob = getApi().getObject(containerName, object.getInfo().getName(),
|
||||||
GetOptions.Builder.ifETagMatches(newEtag));
|
GetOptions.Builder.ifETagMatches(newEtag));
|
||||||
assertEquals(getBlob.getInfo().getHash(), encryptionService.fromHexString(newEtag));
|
assertEquals(getBlob.getInfo().getHash(), encryptionService.fromHex(newEtag));
|
||||||
getBlob = getApi().getObject(containerName, object.getInfo().getName(),
|
getBlob = getApi().getObject(containerName, object.getInfo().getName(),
|
||||||
GetOptions.Builder.startAt(8));
|
GetOptions.Builder.startAt(8));
|
||||||
assertEquals(Utils.toStringAndClose(getBlob.getContent()), data.substring(8));
|
assertEquals(Utils.toStringAndClose(getBlob.getContent()), data.substring(8));
|
||||||
|
|
Loading…
Reference in New Issue