Issue 191: added RSA PEM parsing to encryptionUtils

This commit is contained in:
Adrian Cole 2010-07-30 23:58:31 -07:00
parent 6d438fbbe1
commit a9a0c53fb2
36 changed files with 1502 additions and 511 deletions

View File

@ -24,6 +24,7 @@ import static org.easymock.classextension.EasyMock.replay;
import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertEquals;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.util.Date; import java.util.Date;
import java.util.Map; import java.util.Map;
@ -58,6 +59,8 @@ public class ParseObjectMetadataFromHeadersTest {
encryptionService = new JCEEncryptionService(); encryptionService = new JCEEncryptionService();
} catch (NoSuchAlgorithmException e) { } catch (NoSuchAlgorithmException e) {
Throwables.propagate(e); Throwables.propagate(e);
} catch (CertificateException e) {
Throwables.propagate(e);
} }
} }
@ -70,7 +73,7 @@ public class ParseObjectMetadataFromHeadersTest {
http.getHeaders().put("Content-Disposition", "contentDisposition"); http.getHeaders().put("Content-Disposition", "contentDisposition");
http.getHeaders().put(HttpHeaders.CONTENT_ENCODING, "encoding"); http.getHeaders().put(HttpHeaders.CONTENT_ENCODING, "encoding");
ParseObjectMetadataFromHeaders parser = new ParseObjectMetadataFromHeaders(blobParser(http, "\"abc\""), ParseObjectMetadataFromHeaders parser = new ParseObjectMetadataFromHeaders(blobParser(http, "\"abc\""),
blobToObjectMetadata, encryptionService, "x-amz-meta-"); blobToObjectMetadata, encryptionService, "x-amz-meta-");
MutableObjectMetadata response = parser.apply(http); MutableObjectMetadata response = parser.apply(http);
assertEquals(response, expects); assertEquals(response, expects);
} }
@ -86,7 +89,7 @@ public class ParseObjectMetadataFromHeadersTest {
http.getHeaders().put(HttpHeaders.CONTENT_ENCODING, "encoding"); http.getHeaders().put(HttpHeaders.CONTENT_ENCODING, "encoding");
http.getHeaders().put("x-amz-meta-object-eTag", "\"abc\""); http.getHeaders().put("x-amz-meta-object-eTag", "\"abc\"");
ParseObjectMetadataFromHeaders parser = new ParseObjectMetadataFromHeaders(blobParser(http, null), ParseObjectMetadataFromHeaders parser = new ParseObjectMetadataFromHeaders(blobParser(http, null),
blobToObjectMetadata, encryptionService, "x-amz-meta-"); blobToObjectMetadata, encryptionService, "x-amz-meta-");
MutableObjectMetadata response = parser.apply(http); MutableObjectMetadata response = parser.apply(http);
assertEquals(response, expects); assertEquals(response, expects);
} }

View File

@ -22,6 +22,7 @@ import static org.testng.Assert.assertEquals;
import java.io.InputStream; import java.io.InputStream;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.util.TreeSet; import java.util.TreeSet;
import org.jclouds.aws.s3.domain.CanonicalUser; import org.jclouds.aws.s3.domain.CanonicalUser;
@ -55,6 +56,8 @@ public class ListBucketHandlerTest extends BaseHandlerTest {
encryptionService = new JCEEncryptionService(); encryptionService = new JCEEncryptionService();
} catch (NoSuchAlgorithmException e) { } catch (NoSuchAlgorithmException e) {
Throwables.propagate(e); Throwables.propagate(e);
} catch (CertificateException e) {
Throwables.propagate(e);
} }
} }
@ -69,56 +72,59 @@ public class ListBucketHandlerTest extends BaseHandlerTest {
public void testApplyInputStream() { public void testApplyInputStream() {
InputStream is = getClass().getResourceAsStream("/s3/list_bucket.xml"); InputStream is = getClass().getResourceAsStream("/s3/list_bucket.xml");
CanonicalUser owner = new CanonicalUser("e1a5f66a480ca99a4fdfe8e318c3020446c9989d7004e7778029fbcc5d990fa0", CanonicalUser owner = new CanonicalUser("e1a5f66a480ca99a4fdfe8e318c3020446c9989d7004e7778029fbcc5d990fa0",
"ferncam"); "ferncam");
ListBucketResponse expected = new ListBucketResponseImpl("adriancole.org.jclouds.aws.s3.amazons3testdelimiter", ListBucketResponse expected = new ListBucketResponseImpl("adriancole.org.jclouds.aws.s3.amazons3testdelimiter",
ImmutableList ImmutableList.of(
.of(
(ObjectMetadata) new BucketListObjectMetadata("apps/0", dateService (ObjectMetadata) new BucketListObjectMetadata("apps/0", dateService
.iso8601DateParse("2009-05-07T18:27:08.000Z"), "\"c82e6a0025c31c5de5947fda62ac51ab\"", .iso8601DateParse("2009-05-07T18:27:08.000Z"), "\"c82e6a0025c31c5de5947fda62ac51ab\"",
encryptionService.fromHex("c82e6a0025c31c5de5947fda62ac51ab"), 8, owner, encryptionService.fromHex("c82e6a0025c31c5de5947fda62ac51ab"), 8, owner,
StorageClass.STANDARD), (ObjectMetadata) new BucketListObjectMetadata("apps/1", StorageClass.STANDARD),
dateService.iso8601DateParse("2009-05-07T18:27:09.000Z"), (ObjectMetadata) new BucketListObjectMetadata("apps/1", dateService
"\"944fab2c5a9a6bacf07db5e688310d7a\"", encryptionService .iso8601DateParse("2009-05-07T18:27:09.000Z"), "\"944fab2c5a9a6bacf07db5e688310d7a\"",
.fromHex("944fab2c5a9a6bacf07db5e688310d7a"), 8, owner, StorageClass.STANDARD), encryptionService.fromHex("944fab2c5a9a6bacf07db5e688310d7a"), 8, owner,
StorageClass.STANDARD),
(ObjectMetadata) new BucketListObjectMetadata("apps/2", dateService (ObjectMetadata) new BucketListObjectMetadata("apps/2", dateService
.iso8601DateParse("2009-05-07T18:27:09.000Z"), "\"a227b8888045c8fd159fb495214000f0\"", .iso8601DateParse("2009-05-07T18:27:09.000Z"), "\"a227b8888045c8fd159fb495214000f0\"",
encryptionService.fromHex("a227b8888045c8fd159fb495214000f0"), 8, owner, encryptionService.fromHex("a227b8888045c8fd159fb495214000f0"), 8, owner,
StorageClass.STANDARD), (ObjectMetadata) new BucketListObjectMetadata("apps/3", StorageClass.STANDARD),
dateService.iso8601DateParse("2009-05-07T18:27:09.000Z"), (ObjectMetadata) new BucketListObjectMetadata("apps/3", dateService
"\"c9caa76c3dec53e2a192608ce73eef03\"", encryptionService .iso8601DateParse("2009-05-07T18:27:09.000Z"), "\"c9caa76c3dec53e2a192608ce73eef03\"",
.fromHex("c9caa76c3dec53e2a192608ce73eef03"), 8, owner, StorageClass.STANDARD), encryptionService.fromHex("c9caa76c3dec53e2a192608ce73eef03"), 8, owner,
StorageClass.STANDARD),
(ObjectMetadata) new BucketListObjectMetadata("apps/4", dateService (ObjectMetadata) new BucketListObjectMetadata("apps/4", dateService
.iso8601DateParse("2009-05-07T18:27:09.000Z"), "\"1ce5d0dcc6154a647ea90c7bdf82a224\"", .iso8601DateParse("2009-05-07T18:27:09.000Z"), "\"1ce5d0dcc6154a647ea90c7bdf82a224\"",
encryptionService.fromHex("1ce5d0dcc6154a647ea90c7bdf82a224"), 8, owner, encryptionService.fromHex("1ce5d0dcc6154a647ea90c7bdf82a224"), 8, owner,
StorageClass.STANDARD), (ObjectMetadata) new BucketListObjectMetadata("apps/5", StorageClass.STANDARD),
dateService.iso8601DateParse("2009-05-07T18:27:09.000Z"), (ObjectMetadata) new BucketListObjectMetadata("apps/5", dateService
"\"79433524d87462ee05708a8ef894ed55\"", encryptionService .iso8601DateParse("2009-05-07T18:27:09.000Z"), "\"79433524d87462ee05708a8ef894ed55\"",
.fromHex("79433524d87462ee05708a8ef894ed55"), 8, owner, StorageClass.STANDARD), encryptionService.fromHex("79433524d87462ee05708a8ef894ed55"), 8, owner,
StorageClass.STANDARD),
(ObjectMetadata) new BucketListObjectMetadata("apps/6", dateService (ObjectMetadata) new BucketListObjectMetadata("apps/6", dateService
.iso8601DateParse("2009-05-07T18:27:10.000Z"), "\"dd00a060b28ddca8bc5a21a49e306f67\"", .iso8601DateParse("2009-05-07T18:27:10.000Z"), "\"dd00a060b28ddca8bc5a21a49e306f67\"",
encryptionService.fromHex("dd00a060b28ddca8bc5a21a49e306f67"), 8, owner, encryptionService.fromHex("dd00a060b28ddca8bc5a21a49e306f67"), 8, owner,
StorageClass.STANDARD), (ObjectMetadata) new BucketListObjectMetadata("apps/7", StorageClass.STANDARD),
dateService.iso8601DateParse("2009-05-07T18:27:10.000Z"), (ObjectMetadata) new BucketListObjectMetadata("apps/7", dateService
"\"8cd06eca6e819a927b07a285d750b100\"", encryptionService .iso8601DateParse("2009-05-07T18:27:10.000Z"), "\"8cd06eca6e819a927b07a285d750b100\"",
.fromHex("8cd06eca6e819a927b07a285d750b100"), 8, owner, StorageClass.STANDARD), encryptionService.fromHex("8cd06eca6e819a927b07a285d750b100"), 8, owner,
StorageClass.STANDARD),
(ObjectMetadata) new BucketListObjectMetadata("apps/8", dateService (ObjectMetadata) new BucketListObjectMetadata("apps/8", dateService
.iso8601DateParse("2009-05-07T18:27:10.000Z"), "\"174495094d0633b92cbe46603eee6bad\"", .iso8601DateParse("2009-05-07T18:27:10.000Z"), "\"174495094d0633b92cbe46603eee6bad\"",
encryptionService.fromHex("174495094d0633b92cbe46603eee6bad"), 8, owner, encryptionService.fromHex("174495094d0633b92cbe46603eee6bad"), 8, owner,
StorageClass.STANDARD), (ObjectMetadata) new BucketListObjectMetadata("apps/9", StorageClass.STANDARD),
dateService.iso8601DateParse("2009-05-07T18:27:10.000Z"), (ObjectMetadata) new BucketListObjectMetadata("apps/9", dateService
"\"cd8a19b26fea8a827276df0ad11c580d\"", encryptionService .iso8601DateParse("2009-05-07T18:27:10.000Z"), "\"cd8a19b26fea8a827276df0ad11c580d\"",
.fromHex("cd8a19b26fea8a827276df0ad11c580d"), 8, owner, StorageClass.STANDARD)), encryptionService.fromHex("cd8a19b26fea8a827276df0ad11c580d"), 8, owner,
"apps/", null, null, 1000, null, false, new TreeSet<String>()); StorageClass.STANDARD)), "apps/", null, null, 1000, null, false, new TreeSet<String>());
ListBucketResponse result = (ListBucketResponse) factory.create(injector.getInstance(ListBucketHandler.class)) ListBucketResponse result = (ListBucketResponse) factory.create(injector.getInstance(ListBucketHandler.class))
.parse(is); .parse(is);
assertEquals(result, expected); assertEquals(result, expected);
} }
ParseSax<ListBucketResponse> createParser() { ParseSax<ListBucketResponse> createParser() {
ParseSax<ListBucketResponse> parser = (ParseSax<ListBucketResponse>) factory.create(injector ParseSax<ListBucketResponse> parser = (ParseSax<ListBucketResponse>) factory.create(injector
.getInstance(ListBucketHandler.class)); .getInstance(ListBucketHandler.class));
return parser; return parser;
} }
@ -126,7 +132,7 @@ public class ListBucketHandlerTest extends BaseHandlerTest {
public void testListMyBucketsWithDelimiterSlashAndCommonPrefixesAppsSlash() throws HttpException { public void testListMyBucketsWithDelimiterSlashAndCommonPrefixesAppsSlash() throws HttpException {
ListBucketResponse bucket = createParser().parse( ListBucketResponse bucket = createParser().parse(
Utils.toInputStream(listBucketWithSlashDelimiterAndCommonPrefixApps)); Utils.toInputStream(listBucketWithSlashDelimiterAndCommonPrefixApps));
assertEquals(bucket.getCommonPrefixes().iterator().next(), "apps/"); assertEquals(bucket.getCommonPrefixes().iterator().next(), "apps/");
assertEquals(bucket.getDelimiter(), "/"); assertEquals(bucket.getDelimiter(), "/");
assert bucket.getMarker() == null; assert bucket.getMarker() == null;

View File

@ -24,15 +24,12 @@ import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull; import static org.testng.Assert.assertNotNull;
import java.io.IOException; import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.util.Set; import java.util.Set;
import java.util.SortedSet; import java.util.SortedSet;
import org.jclouds.aws.AWSResponseException; import org.jclouds.aws.AWSResponseException;
import org.jclouds.aws.domain.Region; import org.jclouds.aws.domain.Region;
import org.jclouds.aws.sqs.domain.Queue; import org.jclouds.aws.sqs.domain.Queue;
import org.jclouds.encryption.EncryptionService;
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;
@ -41,7 +38,6 @@ 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;
import com.google.common.base.Throwables;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
import com.google.inject.Module; import com.google.inject.Module;
@ -59,15 +55,6 @@ public class SQSClientLiveTest {
private RestContext<SQSClient, SQSAsyncClient> context; private RestContext<SQSClient, SQSAsyncClient> context;
protected volatile static EncryptionService encryptionService;
static {
try {
encryptionService = new JCEEncryptionService();
} catch (NoSuchAlgorithmException e) {
Throwables.propagate(e);
}
}
private Set<Queue> queues = Sets.newHashSet(); private Set<Queue> queues = Sets.newHashSet();
@BeforeGroups(groups = { "live" }) @BeforeGroups(groups = { "live" })
@ -136,7 +123,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(Utils.toInputStream(message)); byte[] md5 = context.utils().encryption().md5(Utils.toInputStream(message));
for (Queue queue : queues) { for (Queue queue : queues) {
assertEquals(client.sendMessage(queue, message), md5); assertEquals(client.sendMessage(queue, message), md5);
} }

View File

@ -25,6 +25,7 @@ import static org.jclouds.blobstore.options.GetOptions.Builder.ifUnmodifiedSince
import static org.jclouds.blobstore.options.GetOptions.Builder.range; import static org.jclouds.blobstore.options.GetOptions.Builder.range;
import static org.jclouds.blobstore.util.BlobStoreUtils.getContentAsStringOrNullAndClose; import static org.jclouds.blobstore.util.BlobStoreUtils.getContentAsStringOrNullAndClose;
import static org.jclouds.concurrent.ConcurrentUtils.awaitCompletion; import static org.jclouds.concurrent.ConcurrentUtils.awaitCompletion;
import static org.jclouds.concurrent.ConcurrentUtils.compose;
import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull; import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertNull; import static org.testng.Assert.assertNull;
@ -36,6 +37,7 @@ import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.util.Date; import java.util.Date;
import java.util.Map; import java.util.Map;
import java.util.concurrent.Future; import java.util.concurrent.Future;
@ -49,7 +51,6 @@ import org.jclouds.blobstore.domain.BlobMetadata;
import org.jclouds.blobstore.domain.PageSet; import org.jclouds.blobstore.domain.PageSet;
import org.jclouds.blobstore.domain.StorageMetadata; import org.jclouds.blobstore.domain.StorageMetadata;
import org.jclouds.blobstore.domain.StorageType; import org.jclouds.blobstore.domain.StorageType;
import static org.jclouds.concurrent.ConcurrentUtils.*;
import org.jclouds.encryption.EncryptionService; import org.jclouds.encryption.EncryptionService;
import org.jclouds.encryption.internal.JCEEncryptionService; import org.jclouds.encryption.internal.JCEEncryptionService;
import org.jclouds.http.BaseJettyTest; import org.jclouds.http.BaseJettyTest;
@ -429,6 +430,8 @@ public class BaseBlobIntegrationTest extends BaseBlobStoreIntegrationTest {
encryptionService = new JCEEncryptionService(); encryptionService = new JCEEncryptionService();
} catch (NoSuchAlgorithmException e) { } catch (NoSuchAlgorithmException e) {
Throwables.propagate(e); Throwables.propagate(e);
} catch (CertificateException e) {
Throwables.propagate(e);
} }
} }

View File

@ -23,7 +23,6 @@ import static org.jclouds.blobstore.util.BlobStoreUtils.getContentAsStringOrNull
import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertEquals;
import java.io.IOException; import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.Map.Entry; import java.util.Map.Entry;
@ -40,8 +39,6 @@ import org.jclouds.blobstore.attr.ConsistencyModel;
import org.jclouds.blobstore.domain.Blob; import org.jclouds.blobstore.domain.Blob;
import org.jclouds.blobstore.domain.StorageMetadata; import org.jclouds.blobstore.domain.StorageMetadata;
import org.jclouds.blobstore.domain.StorageType; import org.jclouds.blobstore.domain.StorageType;
import org.jclouds.encryption.EncryptionService;
import org.jclouds.encryption.internal.JCEEncryptionService;
import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule; import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule;
import org.testng.ITestContext; import org.testng.ITestContext;
import org.testng.annotations.AfterClass; import org.testng.annotations.AfterClass;
@ -62,13 +59,13 @@ public class BaseBlobStoreIntegrationTest {
protected static final String TEST_STRING = String.format(XML_STRING_FORMAT, "apple"); protected static final String TEST_STRING = String.format(XML_STRING_FORMAT, "apple");
protected Map<String, String> fiveStrings = ImmutableMap.of("one", String.format(XML_STRING_FORMAT, "apple"), "two", protected Map<String, String> fiveStrings = ImmutableMap.of("one", String.format(XML_STRING_FORMAT, "apple"), "two",
String.format(XML_STRING_FORMAT, "bear"), "three", String.format(XML_STRING_FORMAT, "candy"), "four", String String.format(XML_STRING_FORMAT, "bear"), "three", String.format(XML_STRING_FORMAT, "candy"), "four",
.format(XML_STRING_FORMAT, "dogma"), "five", String.format(XML_STRING_FORMAT, "emma")); String.format(XML_STRING_FORMAT, "dogma"), "five", String.format(XML_STRING_FORMAT, "emma"));
protected Map<String, String> fiveStringsUnderPath = ImmutableMap.of("path/1", String.format(XML_STRING_FORMAT, protected Map<String, String> fiveStringsUnderPath = ImmutableMap.of("path/1", String.format(XML_STRING_FORMAT,
"apple"), "path/2", String.format(XML_STRING_FORMAT, "bear"), "path/3", String.format(XML_STRING_FORMAT, "apple"), "path/2", String.format(XML_STRING_FORMAT, "bear"), "path/3", String.format(XML_STRING_FORMAT,
"candy"), "path/4", String.format(XML_STRING_FORMAT, "dogma"), "path/5", String.format(XML_STRING_FORMAT, "candy"), "path/4", String.format(XML_STRING_FORMAT, "dogma"), "path/5", String.format(XML_STRING_FORMAT,
"emma")); "emma"));
public static long INCONSISTENCY_WINDOW = 10000; public static long INCONSISTENCY_WINDOW = 10000;
protected static volatile AtomicInteger containerIndex = new AtomicInteger(0); protected static volatile AtomicInteger containerIndex = new AtomicInteger(0);
@ -81,18 +78,8 @@ public class BaseBlobStoreIntegrationTest {
*/ */
private volatile static BlockingQueue<String> containerNames = new ArrayBlockingQueue<String>(containerCount); private volatile static BlockingQueue<String> containerNames = new ArrayBlockingQueue<String>(containerCount);
protected volatile static EncryptionService encryptionService;
static {
try {
encryptionService = new JCEEncryptionService();
} catch (NoSuchAlgorithmException e) {
Throwables.propagate(e);
}
}
/** /**
* There are a lot of retries here mainly from experience running inside * There are a lot of retries here mainly from experience running inside amazon EC2.
* amazon EC2.
*/ */
@BeforeSuite @BeforeSuite
public void setUpResourcesForAllThreads(ITestContext testContext) throws Exception { public void setUpResourcesForAllThreads(ITestContext testContext) throws Exception {
@ -102,7 +89,7 @@ public class BaseBlobStoreIntegrationTest {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private BlobStoreContext getCloudResources(ITestContext testContext) throws ClassNotFoundException, private BlobStoreContext getCloudResources(ITestContext testContext) throws ClassNotFoundException,
InstantiationException, IllegalAccessException, Exception { InstantiationException, IllegalAccessException, Exception {
String initializerClass = checkNotNull(System.getProperty("jclouds.test.initializer"), "jclouds.test.initializer"); String initializerClass = checkNotNull(System.getProperty("jclouds.test.initializer"), "jclouds.test.initializer");
Class<BaseTestInitializer> clazz = (Class<BaseTestInitializer>) Class.forName(initializerClass); Class<BaseTestInitializer> clazz = (Class<BaseTestInitializer>) Class.forName(initializerClass);
BaseTestInitializer initializer = clazz.newInstance(); BaseTestInitializer initializer = clazz.newInstance();
@ -112,11 +99,10 @@ public class BaseBlobStoreIntegrationTest {
protected ExecutorService exec; protected ExecutorService exec;
/** /**
* we are doing this at a class level, as the context.getBlobStore() object * we are doing this at a class level, as the context.getBlobStore() object is going to be shared
* is going to be shared for all methods in the class. We don't want to do * for all methods in the class. We don't want to do this for group, as some test classes may
* this for group, as some test classes may want to have a different * want to have a different implementation of context.getBlobStore(). For example, one class may
* implementation of context.getBlobStore(). For example, one class may want * want non-blocking i/o and another class google appengine.
* non-blocking i/o and another class google appengine.
*/ */
@BeforeClass(groups = { "integration", "live" }) @BeforeClass(groups = { "integration", "live" })
public void setUpResourcesOnThisThread(ITestContext testContext) throws Exception { public void setUpResourcesOnThisThread(ITestContext testContext) throws Exception {
@ -136,7 +122,7 @@ public class BaseBlobStoreIntegrationTest {
private static volatile boolean initialized = false; private static volatile boolean initialized = false;
protected void createContainersSharedByAllThreads(BlobStoreContext context, ITestContext testContext) protected void createContainersSharedByAllThreads(BlobStoreContext context, ITestContext testContext)
throws Exception { throws Exception {
while (!initialized) { while (!initialized) {
synchronized (BaseBlobStoreIntegrationTest.class) { synchronized (BaseBlobStoreIntegrationTest.class) {
if (!initialized) { if (!initialized) {
@ -187,12 +173,12 @@ public class BaseBlobStoreIntegrationTest {
try { try {
for (int i = 0; i < 2; i++) { for (int i = 0; i < 2; i++) {
Iterable<? extends StorageMetadata> testContainers = Iterables.filter(context.getBlobStore().list(), Iterable<? extends StorageMetadata> testContainers = Iterables.filter(context.getBlobStore().list(),
new Predicate<StorageMetadata>() { new Predicate<StorageMetadata>() {
public boolean apply(StorageMetadata input) { public boolean apply(StorageMetadata input) {
return (input.getType() == StorageType.CONTAINER || input.getType() == StorageType.FOLDER) return (input.getType() == StorageType.CONTAINER || input.getType() == StorageType.FOLDER)
&& input.getName().startsWith(CONTAINER_PREFIX.toLowerCase()); && input.getName().startsWith(CONTAINER_PREFIX.toLowerCase());
} }
}); });
for (StorageMetadata container : testContainers) { for (StorageMetadata container : testContainers) {
deleteContainerOrWarnIfUnable(context, container.getName()); deleteContainerOrWarnIfUnable(context, container.getName());
} }
@ -209,12 +195,11 @@ public class BaseBlobStoreIntegrationTest {
public static boolean SANITY_CHECK_RETURNED_BUCKET_NAME = false; public static boolean SANITY_CHECK_RETURNED_BUCKET_NAME = false;
/** /**
* Due to eventual consistency, container commands may not return correctly * Due to eventual consistency, container commands may not return correctly immediately. Hence,
* immediately. Hence, we will try up to the inconsistency window to see if * we will try up to the inconsistency window to see if the assertion completes.
* the assertion completes.
*/ */
protected static void assertConsistencyAware(BlobStoreContext context, Runnable assertion) protected static void assertConsistencyAware(BlobStoreContext context, Runnable assertion)
throws InterruptedException { throws InterruptedException {
if (context.getConsistencyModel() == ConsistencyModel.STRICT) { if (context.getConsistencyModel() == ConsistencyModel.STRICT) {
assertion.run(); assertion.run();
return; return;
@ -240,7 +225,7 @@ public class BaseBlobStoreIntegrationTest {
} }
protected static void createContainerAndEnsureEmpty(BlobStoreContext context, final String containerName) protected static void createContainerAndEnsureEmpty(BlobStoreContext context, final String containerName)
throws InterruptedException { throws InterruptedException {
context.getBlobStore().createContainerInLocation(null, containerName); context.getBlobStore().createContainerInLocation(null, containerName);
if (context.getConsistencyModel() == ConsistencyModel.EVENTUAL) if (context.getConsistencyModel() == ConsistencyModel.EVENTUAL)
Thread.sleep(1000); Thread.sleep(1000);
@ -284,19 +269,19 @@ public class BaseBlobStoreIntegrationTest {
} }
protected void assertConsistencyAwareContainerSize(final String containerName, final int count) protected void assertConsistencyAwareContainerSize(final String containerName, final int count)
throws InterruptedException { throws InterruptedException {
assertConsistencyAware(new Runnable() { assertConsistencyAware(new Runnable() {
public void run() { public void run() {
try { try {
assert context.getBlobStore().countBlobs(containerName) == count : String.format( assert context.getBlobStore().countBlobs(containerName) == count : String.format(
"expected only %d values in %s: %s", count, containerName, Sets.newHashSet(Iterables.transform( "expected only %d values in %s: %s", count, containerName, Sets.newHashSet(Iterables.transform(
context.getBlobStore().list(containerName), new Function<StorageMetadata, String>() { context.getBlobStore().list(containerName), new Function<StorageMetadata, String>() {
public String apply(StorageMetadata from) { public String apply(StorageMetadata from) {
return from.getName(); return from.getName();
} }
}))); })));
} catch (Exception e) { } catch (Exception e) {
Throwables.propagateIfPossible(e); Throwables.propagateIfPossible(e);
} }
@ -312,9 +297,9 @@ public class BaseBlobStoreIntegrationTest {
} }
/** /**
* requestor will create a container using the name returned from this. This * requestor will create a container using the name returned from this. This method will take
* method will take care not to exceed the maximum containers permitted by a * care not to exceed the maximum containers permitted by a provider by deleting an existing
* provider by deleting an existing container first. * container first.
* *
* @throws InterruptedException * @throws InterruptedException
*/ */
@ -326,13 +311,12 @@ public class BaseBlobStoreIntegrationTest {
if (containerName != null) { if (containerName != null) {
containerNames.add(containerName); containerNames.add(containerName);
/* /*
* Ensure that any returned container name actually exists on the * Ensure that any returned container name actually exists on the server. Return of a
* server. Return of a non-existent container introduces subtle testing * non-existent container introduces subtle testing bugs, where later unrelated tests will
* bugs, where later unrelated tests will fail. * fail.
* *
* NOTE: This sanity check should only be run for Stub-based * NOTE: This sanity check should only be run for Stub-based Integration testing -- it will
* Integration testing -- it will *substantially* slow down tests on a * *substantially* slow down tests on a real server over a network.
* real server over a network.
*/ */
if (SANITY_CHECK_RETURNED_BUCKET_NAME) { if (SANITY_CHECK_RETURNED_BUCKET_NAME) {
if (!Iterables.any(context.getBlobStore().list(), new Predicate<StorageMetadata>() { if (!Iterables.any(context.getBlobStore().list(), new Predicate<StorageMetadata>() {
@ -347,8 +331,7 @@ public class BaseBlobStoreIntegrationTest {
} }
/** /**
* abandon old container name instead of waiting for the container to be * abandon old container name instead of waiting for the container to be created.
* created.
* *
* @throws InterruptedException * @throws InterruptedException
*/ */

View File

@ -79,21 +79,21 @@ public class BaseContainerIntegrationTest extends BaseBlobStoreIntegrationTest {
// normalize the // normalize the
// providers. // providers.
object.getMetadata().getUserMetadata().put("Adrian", "powderpuff"); object.getMetadata().getUserMetadata().put("Adrian", "powderpuff");
object.getMetadata().setContentMD5(encryptionService.md5(toInputStream(TEST_STRING))); object.getMetadata().setContentMD5(context.utils().encryption().md5(toInputStream(TEST_STRING)));
String containerName = getContainerName(); String containerName = getContainerName();
try { try {
addBlobToContainer(containerName, object); addBlobToContainer(containerName, object);
validateContent(containerName, key); validateContent(containerName, key);
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(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(), encryptionService.md5(toInputStream(TEST_STRING))); assertEquals(metadata.getContentMD5(), context.utils().encryption().md5(toInputStream(TEST_STRING)));
} finally { } finally {
returnContainer(containerName); returnContainer(containerName);
} }
@ -125,7 +125,7 @@ public class BaseContainerIntegrationTest extends BaseBlobStoreIntegrationTest {
container = context.getBlobStore().list(containerName, afterMarker(marker)); container = context.getBlobStore().list(containerName, afterMarker(marker));
assertEquals(container.getNextMarker(), null); assertEquals(container.getNextMarker(), null);
assert container.size() == 25 : String.format("size should have been 25, but was %d: %s", container.size(), assert container.size() == 25 : String.format("size should have been 25, but was %d: %s", container.size(),
container); container);
assert container.getNextMarker() == null; assert container.getNextMarker() == null;
} finally { } finally {
@ -295,7 +295,7 @@ public class BaseContainerIntegrationTest extends BaseBlobStoreIntegrationTest {
public void run() { public void run() {
try { try {
assert !context.getBlobStore().containerExists(containerName) : "container " + containerName assert !context.getBlobStore().containerExists(containerName) : "container " + containerName
+ " still exists"; + " still exists";
} catch (Exception e) { } catch (Exception e) {
propagateIfPossible(e); propagateIfPossible(e);
} }
@ -305,7 +305,7 @@ public class BaseContainerIntegrationTest extends BaseBlobStoreIntegrationTest {
@Test(groups = { "integration", "live" }) @Test(groups = { "integration", "live" })
public void testListContainer() throws InterruptedException, ExecutionException, TimeoutException, public void testListContainer() throws InterruptedException, ExecutionException, TimeoutException,
UnsupportedEncodingException { UnsupportedEncodingException {
String containerName = getContainerName(); String containerName = getContainerName();
try { try {
add15UnderRoot(containerName); add15UnderRoot(containerName);

View File

@ -49,7 +49,6 @@ import org.jclouds.chef.domain.Role;
import org.jclouds.chef.domain.Sandbox; import org.jclouds.chef.domain.Sandbox;
import org.jclouds.chef.domain.UploadSandbox; import org.jclouds.chef.domain.UploadSandbox;
import org.jclouds.chef.filters.SignedHeaderAuth; import org.jclouds.chef.filters.SignedHeaderAuth;
import org.jclouds.chef.functions.ParseKeyFromJson;
import org.jclouds.chef.functions.ParseKeySetFromJson; import org.jclouds.chef.functions.ParseKeySetFromJson;
import org.jclouds.domain.JsonBall; import org.jclouds.domain.JsonBall;
import org.jclouds.rest.annotations.BinderParam; import org.jclouds.rest.annotations.BinderParam;
@ -86,7 +85,7 @@ public interface ChefAsyncClient {
@POST @POST
@Path("sandboxes") @Path("sandboxes")
ListenableFuture<UploadSandbox> getUploadSandboxForChecksums( ListenableFuture<UploadSandbox> getUploadSandboxForChecksums(
@BinderParam(BindChecksumsToJsonPayload.class) Set<List<Byte>> md5s); @BinderParam(BindChecksumsToJsonPayload.class) Set<List<Byte>> md5s);
@PUT @PUT
ListenableFuture<Void> uploadContent(@BinderParam(BindChecksumsToJsonPayload.class) Set<List<Byte>> md5s); ListenableFuture<Void> uploadContent(@BinderParam(BindChecksumsToJsonPayload.class) Set<List<Byte>> md5s);
@ -97,7 +96,7 @@ public interface ChefAsyncClient {
@PUT @PUT
@Path("sandboxes/{id}") @Path("sandboxes/{id}")
ListenableFuture<Sandbox> commitSandbox(@PathParam("id") String id, ListenableFuture<Sandbox> commitSandbox(@PathParam("id") String id,
@BinderParam(BindIsCompletedToJsonPayload.class) boolean isCompleted); @BinderParam(BindIsCompletedToJsonPayload.class) boolean isCompleted);
/** /**
* @see ChefCookbooks#listCookbooks * @see ChefCookbooks#listCookbooks
@ -114,7 +113,7 @@ public interface ChefAsyncClient {
@PUT @PUT
@Path("cookbooks/{cookbookname}/{version}") @Path("cookbooks/{cookbookname}/{version}")
ListenableFuture<CookbookVersion> updateCookbook(@PathParam("cookbookname") String cookbookName, ListenableFuture<CookbookVersion> updateCookbook(@PathParam("cookbookname") String cookbookName,
@PathParam("version") String version, @BinderParam(BindToJsonPayload.class) CookbookVersion cookbook); @PathParam("version") String version, @BinderParam(BindToJsonPayload.class) CookbookVersion cookbook);
/** /**
* @see ChefCookbook#deleteCookbook(String) * @see ChefCookbook#deleteCookbook(String)
@ -123,7 +122,7 @@ public interface ChefAsyncClient {
@Path("cookbooks/{cookbookname}/{version}") @Path("cookbooks/{cookbookname}/{version}")
@ExceptionParser(ReturnNullOnNotFoundOr404.class) @ExceptionParser(ReturnNullOnNotFoundOr404.class)
ListenableFuture<CookbookVersion> deleteCookbook(@PathParam("cookbookname") String cookbookName, ListenableFuture<CookbookVersion> deleteCookbook(@PathParam("cookbookname") String cookbookName,
@PathParam("version") String version); @PathParam("version") String version);
/** /**
* @see ChefCookbook#getVersionsOfCookbook * @see ChefCookbook#getVersionsOfCookbook
@ -141,24 +140,22 @@ public interface ChefAsyncClient {
@Path("cookbooks/{cookbookname}/{version}") @Path("cookbooks/{cookbookname}/{version}")
@ExceptionParser(ReturnNullOnNotFoundOr404.class) @ExceptionParser(ReturnNullOnNotFoundOr404.class)
ListenableFuture<CookbookVersion> getCookbook(@PathParam("cookbookname") String cookbookName, ListenableFuture<CookbookVersion> getCookbook(@PathParam("cookbookname") String cookbookName,
@PathParam("version") String version); @PathParam("version") String version);
/** /**
* @see ChefClient#createClient * @see ChefClient#createClient
*/ */
@POST @POST
@Path("clients") @Path("clients")
@ResponseParser(ParseKeyFromJson.class) ListenableFuture<Client> createClient(@BinderParam(BindClientnameToJsonPayload.class) String clientname);
ListenableFuture<String> createClient(@BinderParam(BindClientnameToJsonPayload.class) String clientname);
/** /**
* @see ChefClient#generateKeyForClient * @see ChefClient#generateKeyForClient
*/ */
@PUT @PUT
@Path("clients/{clientname}") @Path("clients/{clientname}")
@ResponseParser(ParseKeyFromJson.class) ListenableFuture<Client> generateKeyForClient(
ListenableFuture<String> generateKeyForClient( @PathParam("clientname") @BinderParam(BindGenerateKeyForClientToJsonPayload.class) String clientname);
@PathParam("clientname") @BinderParam(BindGenerateKeyForClientToJsonPayload.class) String clientname);
/** /**
* @see ChefClient#clientExists * @see ChefClient#clientExists
@ -206,7 +203,7 @@ public interface ChefAsyncClient {
@PUT @PUT
@Path("nodes/{nodename}") @Path("nodes/{nodename}")
ListenableFuture<Node> updateNode( ListenableFuture<Node> updateNode(
@PathParam("nodename") @ParamParser(NodeName.class) @BinderParam(BindToJsonPayload.class) Node node); @PathParam("nodename") @ParamParser(NodeName.class) @BinderParam(BindToJsonPayload.class) Node node);
/** /**
* @see ChefNode#nodeExists * @see ChefNode#nodeExists
@ -254,7 +251,7 @@ public interface ChefAsyncClient {
@PUT @PUT
@Path("roles/{rolename}") @Path("roles/{rolename}")
ListenableFuture<Role> updateRole( ListenableFuture<Role> updateRole(
@PathParam("rolename") @ParamParser(RoleName.class) @BinderParam(BindToJsonPayload.class) Role role); @PathParam("rolename") @ParamParser(RoleName.class) @BinderParam(BindToJsonPayload.class) Role role);
/** /**
* @see ChefRole#roleExists * @see ChefRole#roleExists
@ -302,7 +299,7 @@ public interface ChefAsyncClient {
@PUT @PUT
@Path("data/{path}") @Path("data/{path}")
ListenableFuture<JsonBall> updateDataBag(@PathParam("path") String path, ListenableFuture<JsonBall> updateDataBag(@PathParam("path") String path,
@BinderParam(BindToJsonPayload.class) JsonBall node); @BinderParam(BindToJsonPayload.class) JsonBall node);
/** /**
* @see ChefDataBag#nodeExists * @see ChefDataBag#nodeExists

View File

@ -70,8 +70,7 @@ public interface ChefClient {
* FIXME Comment this * FIXME Comment this
* *
* @param md5s * @param md5s
* raw md5s; uses {@code Bytes.asList()} and {@code * raw md5s; uses {@code Bytes.asList()} and {@code Bytes.toByteArray()} as necessary
* Bytes.toByteArray()} as necessary
* @return * @return
*/ */
UploadSandbox getUploadSandboxForChecksums(Set<List<Byte>> md5s); UploadSandbox getUploadSandboxForChecksums(Set<List<Byte>> md5s);
@ -85,8 +84,7 @@ public interface ChefClient {
* <p/> * <p/>
* "401 Unauthorized" if the caller is not a recognized user. * "401 Unauthorized" if the caller is not a recognized user.
* <p/> * <p/>
* "403 Forbidden" if you do not have permission to see the * "403 Forbidden" if you do not have permission to see the cookbook list.
* cookbook list.
*/ */
Set<String> listCookbooks(); Set<String> listCookbooks();
@ -108,8 +106,7 @@ public interface ChefClient {
* <p/> * <p/>
* "401 Unauthorized" if you are not a recognized user. * "401 Unauthorized" if you are not a recognized user.
* <p/> * <p/>
* "403 Forbidden" if you do not have Delete rights on the * "403 Forbidden" if you do not have Delete rights on the cookbook.
* cookbook.
*/ */
CookbookVersion deleteCookbook(String cookbookName, String version); CookbookVersion deleteCookbook(String cookbookName, String version);
@ -121,14 +118,13 @@ public interface ChefClient {
* <p/> * <p/>
* "401 Unauthorized" if the caller is not a recognized user. * "401 Unauthorized" if the caller is not a recognized user.
* <p/> * <p/>
* "403 Forbidden" if the caller is not authorized to view the * "403 Forbidden" if the caller is not authorized to view the cookbook.
* cookbook.
*/ */
Set<String> getVersionsOfCookbook(String cookbookName); Set<String> getVersionsOfCookbook(String cookbookName);
/** /**
* Returns a description of the cookbook, with links to all of its component * Returns a description of the cookbook, with links to all of its component parts, and the
* parts, and the metadata. * metadata.
* *
* @return the cookbook or null, if not found * @return the cookbook or null, if not found
* *
@ -136,31 +132,28 @@ public interface ChefClient {
* <p/> * <p/>
* "401 Unauthorized" if the caller is not a recognized user. * "401 Unauthorized" if the caller is not a recognized user.
* <p/> * <p/>
* "403 Forbidden" if the caller is not authorized to view the * "403 Forbidden" if the caller is not authorized to view the cookbook.
* cookbook.
*/ */
CookbookVersion getCookbook(String cookbookName, String version); CookbookVersion getCookbook(String cookbookName, String version);
/** /**
* creates a new client * creates a new client
* *
* @return the private key of the client. You can then use this client name * @return the private key of the client. You can then use this client name and private key to
* and private key to access the Opscode API. * access the Opscode API.
* @throws AuthorizationException * @throws AuthorizationException
* <p/> * <p/>
* "401 Unauthorized" if the caller is not a recognized user. * "401 Unauthorized" if the caller is not a recognized user.
* <p/> * <p/>
* "403 Forbidden" if the caller is not authorized to create a * "403 Forbidden" if the caller is not authorized to create a client.
* client.
* @throws HttpResponseException * @throws HttpResponseException
* "409 Conflict" if the client already exists * "409 Conflict" if the client already exists
*/ */
@Timeout(duration = 120, timeUnit = TimeUnit.SECONDS) @Timeout(duration = 120, timeUnit = TimeUnit.SECONDS)
String createClient(String name); Client createClient(String name);
/** /**
* generate a new key-pair for this client, and return the new private key in * generate a new key-pair for this client, and return the new private key in the response body.
* the response body.
* *
* @return the new private key * @return the new private key
* *
@ -168,11 +161,10 @@ public interface ChefClient {
* <p/> * <p/>
* "401 Unauthorized" if the caller is not a recognized user. * "401 Unauthorized" if the caller is not a recognized user.
* <p/> * <p/>
* "403 Forbidden" if the caller is not authorized to modify the * "403 Forbidden" if the caller is not authorized to modify the client.
* client.
*/ */
@Timeout(duration = 120, timeUnit = TimeUnit.SECONDS) @Timeout(duration = 120, timeUnit = TimeUnit.SECONDS)
String generateKeyForClient(String name); Client generateKeyForClient(String name);
/** /**
* @return list of client names. * @return list of client names.
@ -229,8 +221,7 @@ public interface ChefClient {
* <p/> * <p/>
* "401 Unauthorized" if the caller is not a recognized user. * "401 Unauthorized" if the caller is not a recognized user.
* <p/> * <p/>
* "403 Forbidden" if the caller is not authorized to create a * "403 Forbidden" if the caller is not authorized to create a node.
* node.
* @throws HttpResponseException * @throws HttpResponseException
* "409 Conflict" if the node already exists * "409 Conflict" if the node already exists
*/ */
@ -302,8 +293,7 @@ public interface ChefClient {
* <p/> * <p/>
* "401 Unauthorized" if the caller is not a recognized user. * "401 Unauthorized" if the caller is not a recognized user.
* <p/> * <p/>
* "403 Forbidden" if the caller is not authorized to create a * "403 Forbidden" if the caller is not authorized to create a role.
* role.
* @throws HttpResponseException * @throws HttpResponseException
* "409 Conflict" if the role already exists * "409 Conflict" if the role already exists
*/ */

View File

@ -88,7 +88,7 @@ public class BaseChefRestClientModule<S, A> extends RestClientModule<S, A> {
@Singleton @Singleton
public PrivateKey provideKey(EncryptionService encryptionService, @Named(PROPERTY_CREDENTIAL) String pem) public PrivateKey provideKey(EncryptionService encryptionService, @Named(PROPERTY_CREDENTIAL) String pem)
throws UnsupportedEncodingException { throws UnsupportedEncodingException {
return encryptionService.readPrivateKeyFromPEM(pem.getBytes("UTF-8")); return encryptionService.privateKeyFromPEM(pem.getBytes("UTF-8"));
} }
@Override @Override

View File

@ -18,17 +18,24 @@
*/ */
package org.jclouds.chef.config; package org.jclouds.chef.config;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.cert.X509Certificate;
import java.util.Map; import java.util.Map;
import javax.inject.Inject;
import javax.inject.Named; import javax.inject.Named;
import javax.inject.Singleton; import javax.inject.Singleton;
import org.jclouds.Constants; import org.jclouds.Constants;
import org.jclouds.chef.domain.DataBagItem; import org.jclouds.chef.domain.DataBagItem;
import org.jclouds.encryption.EncryptionService;
import org.jclouds.json.config.GsonModule.DateAdapter; import org.jclouds.json.config.GsonModule.DateAdapter;
import org.jclouds.json.config.GsonModule.Iso8601DateAdapter; import org.jclouds.json.config.GsonModule.Iso8601DateAdapter;
import com.google.common.base.Throwables;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import com.google.gson.JsonDeserializationContext; import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer; import com.google.gson.JsonDeserializer;
@ -47,6 +54,87 @@ import com.google.inject.Provides;
* @author Adrian Cole * @author Adrian Cole
*/ */
public class ChefParserModule extends AbstractModule { public class ChefParserModule extends AbstractModule {
@ImplementedBy(PrivateKeyAdapterImpl.class)
public static interface PrivateKeyAdapter extends JsonDeserializer<PrivateKey> {
}
@Singleton
public static class PrivateKeyAdapterImpl implements PrivateKeyAdapter {
private final EncryptionService encryptionService;
@Inject
PrivateKeyAdapterImpl(EncryptionService encryptionService) {
this.encryptionService = encryptionService;
}
@Override
public PrivateKey deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
throws JsonParseException {
String keyText = json.getAsString().replaceAll("\\n", "\n");
try {
return encryptionService.privateKeyFromPEM(keyText.getBytes("UTF-8"));
} catch (UnsupportedEncodingException e) {
Throwables.propagate(e);
return null;
}
}
}
@ImplementedBy(PublicKeyAdapterImpl.class)
public static interface PublicKeyAdapter extends JsonDeserializer<PublicKey> {
}
@Singleton
public static class PublicKeyAdapterImpl implements PublicKeyAdapter {
private final EncryptionService encryptionService;
@Inject
PublicKeyAdapterImpl(EncryptionService encryptionService) {
this.encryptionService = encryptionService;
}
@Override
public PublicKey deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
throws JsonParseException {
String keyText = json.getAsString().replaceAll("\\n", "\n");
try {
return encryptionService.publicKeyFromPEM(keyText.getBytes("UTF-8"));
} catch (UnsupportedEncodingException e) {
Throwables.propagate(e);
return null;
}
}
}
@ImplementedBy(X509CertificateAdapterImpl.class)
public static interface X509CertificateAdapter extends JsonDeserializer<X509Certificate> {
}
@Singleton
public static class X509CertificateAdapterImpl implements X509CertificateAdapter {
private final EncryptionService encryptionService;
@Inject
X509CertificateAdapterImpl(EncryptionService encryptionService) {
this.encryptionService = encryptionService;
}
@Override
public X509Certificate deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
throws JsonParseException {
String keyText = json.getAsString().replaceAll("\\n", "\n");
try {
return encryptionService.x509CertificateFromPEM(keyText.getBytes("UTF-8"));
} catch (UnsupportedEncodingException e) {
Throwables.propagate(e);
return null;
}
}
}
@ImplementedBy(DataBagItemAdapterImpl.class) @ImplementedBy(DataBagItemAdapterImpl.class)
public static interface DataBagItemAdapter extends JsonSerializer<DataBagItem>, JsonDeserializer<DataBagItem> { public static interface DataBagItemAdapter extends JsonSerializer<DataBagItem>, JsonDeserializer<DataBagItem> {
@ -62,7 +150,7 @@ public class ChefParserModule extends AbstractModule {
@Override @Override
public DataBagItem deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) public DataBagItem deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
throws JsonParseException { throws JsonParseException {
IdHolder idHolder = context.deserialize(json, IdHolder.class); IdHolder idHolder = context.deserialize(json, IdHolder.class);
return new DataBagItem(idHolder.id, json.toString()); return new DataBagItem(idHolder.id, json.toString());
} }
@ -75,8 +163,10 @@ public class ChefParserModule extends AbstractModule {
@Provides @Provides
@Singleton @Singleton
@Named(Constants.PROPERTY_GSON_ADAPTERS) @Named(Constants.PROPERTY_GSON_ADAPTERS)
public Map<Type, Object> provideCustomAdapterBindings(DataBagItemAdapter adapter) { public Map<Type, Object> provideCustomAdapterBindings(DataBagItemAdapter adapter, PrivateKeyAdapter privateAdapter,
return ImmutableMap.<Type, Object> of(DataBagItem.class, adapter); PublicKeyAdapter publicAdapter, X509CertificateAdapter certAdapter) {
return ImmutableMap.<Type, Object> of(DataBagItem.class, adapter, PrivateKey.class, privateAdapter,
PublicKey.class, publicAdapter, X509Certificate.class, certAdapter);
} }
@Override @Override

View File

@ -23,6 +23,12 @@
*/ */
package org.jclouds.chef.domain; package org.jclouds.chef.domain;
import java.security.PrivateKey;
import java.security.cert.X509Certificate;
import javax.annotation.Nullable;
import com.google.gson.annotations.SerializedName;
/** /**
* Client object. * Client object.
@ -30,7 +36,9 @@ package org.jclouds.chef.domain;
* @author Adrian Cole * @author Adrian Cole
*/ */
public class Client { public class Client {
private String certificate; private X509Certificate certificate;
@SerializedName("private_key")
private PrivateKey privateKey;
private String orgname; private String orgname;
private String clientname; private String clientname;
private String name; private String name;
@ -41,7 +49,11 @@ public class Client {
} }
public String getCertificate() { public PrivateKey getPrivateKey() {
return privateKey;
}
public X509Certificate getCertificate() {
return certificate; return certificate;
} }
@ -64,7 +76,7 @@ public class Client {
@Override @Override
public String toString() { public String toString() {
return "[name=" + name + ", clientname=" + clientname + ", orgname=" + orgname + ", isValidator=" + validator return "[name=" + name + ", clientname=" + clientname + ", orgname=" + orgname + ", isValidator=" + validator
+ ", certificate=" + certificate + "]"; + ", certificate=" + certificate + ", privateKey=" + (privateKey != null) + "]";
} }
@Override @Override
@ -73,9 +85,10 @@ public class Client {
int result = 1; int result = 1;
result = prime * result + ((certificate == null) ? 0 : certificate.hashCode()); result = prime * result + ((certificate == null) ? 0 : certificate.hashCode());
result = prime * result + ((clientname == null) ? 0 : clientname.hashCode()); result = prime * result + ((clientname == null) ? 0 : clientname.hashCode());
result = prime * result + (validator ? 1231 : 1237);
result = prime * result + ((name == null) ? 0 : name.hashCode()); result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + ((orgname == null) ? 0 : orgname.hashCode()); result = prime * result + ((orgname == null) ? 0 : orgname.hashCode());
result = prime * result + ((privateKey == null) ? 0 : privateKey.hashCode());
result = prime * result + (validator ? 1231 : 1237);
return result; return result;
} }
@ -98,8 +111,6 @@ public class Client {
return false; return false;
} else if (!clientname.equals(other.clientname)) } else if (!clientname.equals(other.clientname))
return false; return false;
if (validator != other.validator)
return false;
if (name == null) { if (name == null) {
if (other.name != null) if (other.name != null)
return false; return false;
@ -110,14 +121,24 @@ public class Client {
return false; return false;
} else if (!orgname.equals(other.orgname)) } else if (!orgname.equals(other.orgname))
return false; return false;
if (privateKey == null) {
if (other.privateKey != null)
return false;
} else if (!privateKey.equals(other.privateKey))
return false;
if (validator != other.validator)
return false;
return true; return true;
} }
public Client(String certificate, String orgname, String clientname, String name, boolean isValidator) { public Client(X509Certificate certificate, String orgname, String clientname, String name, boolean isValidator,
@Nullable PrivateKey privateKey) {
this.certificate = certificate; this.certificate = certificate;
this.orgname = orgname; this.orgname = orgname;
this.clientname = clientname; this.clientname = clientname;
this.name = name; this.name = name;
this.validator = isValidator; this.validator = isValidator;
this.privateKey = privateKey;
} }
} }

View File

@ -18,6 +18,8 @@
*/ */
package org.jclouds.chef.domain; package org.jclouds.chef.domain;
import java.security.PrivateKey;
import com.google.gson.annotations.SerializedName; import com.google.gson.annotations.SerializedName;
/** /**
@ -32,6 +34,8 @@ public class Organization implements Comparable<Organization> {
@SerializedName("org_type") @SerializedName("org_type")
private String orgType; private String orgType;
private String clientname; private String clientname;
@SerializedName("private_key")
private PrivateKey privateKey;
public Organization(String name) { public Organization(String name) {
this(); this();
@ -80,6 +84,10 @@ public class Organization implements Comparable<Organization> {
this.clientname = clientname; this.clientname = clientname;
} }
public PrivateKey getPrivateKey() {
return privateKey;
}
@Override @Override
public int hashCode() { public int hashCode() {
final int prime = 31; final int prime = 31;
@ -126,7 +134,7 @@ public class Organization implements Comparable<Organization> {
@Override @Override
public String toString() { public String toString() {
return "Organization [clientname=" + clientname + ", fullName=" + fullName + ", name=" + name + ", orgType=" return "Organization [clientname=" + clientname + ", fullName=" + fullName + ", name=" + name + ", orgType="
+ orgType + "]"; + orgType + "]";
} }
} }

View File

@ -18,6 +18,8 @@
*/ */
package org.jclouds.chef.domain; package org.jclouds.chef.domain;
import java.security.PrivateKey;
import com.google.gson.annotations.SerializedName; import com.google.gson.annotations.SerializedName;
/** /**
@ -37,6 +39,8 @@ public class User implements Comparable<User> {
private String displayName; private String displayName;
private String email; private String email;
private String password; private String password;
@SerializedName("private_key")
private PrivateKey privateKey;
public User(String username) { public User(String username) {
this.username = username; this.username = username;
@ -108,6 +112,10 @@ public class User implements Comparable<User> {
return password; return password;
} }
public PrivateKey getPrivateKey() {
return privateKey;
}
@Override @Override
public int hashCode() { public int hashCode() {
final int prime = 31; final int prime = 31;
@ -172,7 +180,7 @@ public class User implements Comparable<User> {
@Override @Override
public String toString() { public String toString() {
return "User [displayName=" + displayName + ", email=" + email + ", firstName=" + firstName + ", lastName=" return "User [displayName=" + displayName + ", email=" + email + ", firstName=" + firstName + ", lastName="
+ lastName + ", middleName=" + middleName + ", password=" + password + ", username=" + username + "]"; + lastName + ", middleName=" + middleName + ", password=" + password + ", username=" + username + "]";
} }
} }

View File

@ -81,9 +81,8 @@ public class SignedHeaderAuth implements HttpRequestFilter {
Logger signatureLog = Logger.NULL; Logger signatureLog = Logger.NULL;
@Inject @Inject
public SignedHeaderAuth(SignatureWire signatureWire, @Named(PROPERTY_IDENTITY) String userId, public SignedHeaderAuth(SignatureWire signatureWire, @Named(PROPERTY_IDENTITY) String userId, PrivateKey privateKey,
PrivateKey privateKey, @TimeStamp Provider<String> timeStampProvider, @TimeStamp Provider<String> timeStampProvider, EncryptionService encryptionService, HttpUtils utils) {
EncryptionService encryptionService, HttpUtils utils) {
this.signatureWire = signatureWire; this.signatureWire = signatureWire;
this.userId = userId; this.userId = userId;
this.privateKey = privateKey; this.privateKey = privateKey;
@ -96,48 +95,41 @@ public class SignedHeaderAuth implements HttpRequestFilter {
public void filter(HttpRequest request) throws HttpException { public void filter(HttpRequest request) throws HttpException {
String contentHash = hashBody(request.getPayload()); String contentHash = hashBody(request.getPayload());
request.getHeaders().replaceValues("X-Ops-Content-Hash", request.getHeaders().replaceValues("X-Ops-Content-Hash", Collections.singletonList(contentHash));
Collections.singletonList(contentHash));
String timestamp = timeStampProvider.get(); String timestamp = timeStampProvider.get();
String toSign = createStringToSign(request.getMethod(), hashPath(request.getEndpoint() String toSign = createStringToSign(request.getMethod(), hashPath(request.getEndpoint().getPath()), contentHash,
.getPath()), contentHash, timestamp); timestamp);
request.getHeaders().replaceValues("X-Ops-Userid", Collections.singletonList(userId)); request.getHeaders().replaceValues("X-Ops-Userid", Collections.singletonList(userId));
request.getHeaders().replaceValues("X-Ops-Sign", request.getHeaders().replaceValues("X-Ops-Sign", Collections.singletonList(SIGNING_DESCRIPTION));
Collections.singletonList(SIGNING_DESCRIPTION));
calculateAndReplaceAuthorizationHeaders(request, toSign); calculateAndReplaceAuthorizationHeaders(request, toSign);
request.getHeaders().replaceValues("X-Ops-Timestamp", Collections.singletonList(timestamp)); request.getHeaders().replaceValues("X-Ops-Timestamp", Collections.singletonList(timestamp));
utils.logRequest(signatureLog, request, "<<"); utils.logRequest(signatureLog, request, "<<");
} }
@VisibleForTesting @VisibleForTesting
void calculateAndReplaceAuthorizationHeaders(HttpRequest request, String toSign) void calculateAndReplaceAuthorizationHeaders(HttpRequest request, String toSign) throws HttpException {
throws HttpException {
String signature = sign(toSign); String signature = sign(toSign);
if (signatureWire.enabled()) if (signatureWire.enabled())
signatureWire.input(Utils.toInputStream(signature)); signatureWire.input(Utils.toInputStream(signature));
String[] signatureLines = Iterables.toArray(Splitter.fixedLength(60).split(signature), String[] signatureLines = Iterables.toArray(Splitter.fixedLength(60).split(signature), String.class);
String.class);
for (int i = 0; i < signatureLines.length; i++) { for (int i = 0; i < signatureLines.length; i++) {
request.getHeaders().replaceValues("X-Ops-Authorization-" + (i + 1), request.getHeaders().replaceValues("X-Ops-Authorization-" + (i + 1),
Collections.singletonList(signatureLines[i])); Collections.singletonList(signatureLines[i]));
} }
} }
public String createStringToSign(String request, String hashedPath, String contentHash, public String createStringToSign(String request, String hashedPath, String contentHash, String timestamp) {
String timestamp) {
return new StringBuilder().append("Method:").append(request).append("\n").append( return new StringBuilder().append("Method:").append(request).append("\n").append("Hashed Path:").append(
"Hashed Path:").append(hashedPath).append("\n").append("X-Ops-Content-Hash:") hashedPath).append("\n").append("X-Ops-Content-Hash:").append(contentHash).append("\n").append(
.append(contentHash).append("\n").append("X-Ops-Timestamp:").append(timestamp) "X-Ops-Timestamp:").append(timestamp).append("\n").append("X-Ops-UserId:").append(userId).toString();
.append("\n").append("X-Ops-UserId:").append(userId).toString();
} }
@VisibleForTesting @VisibleForTesting
String hashPath(String path) { String hashPath(String path) {
try { try {
return encryptionService.base64(encryptionService.sha1(Utils return encryptionService.base64(encryptionService.sha1(Utils.toInputStream(canonicalPath(path))));
.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);
@ -190,7 +182,7 @@ public class SignedHeaderAuth implements HttpRequestFilter {
public String sign(String toSign) { public String sign(String toSign) {
try { try {
byte[] encrypted = encryptionService.rsaSign(toSign, privateKey); byte[] encrypted = encryptionService.rsaEncrypt(Payloads.newStringPayload(toSign), privateKey);
return encryptionService.base64(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);

View File

@ -1,69 +0,0 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*/
package org.jclouds.chef.functions;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.jclouds.http.HttpResponse;
import org.jclouds.http.functions.ReturnStringIf2xx;
import com.google.common.base.Function;
/**
*
*
* @author Adrian Cole
*/
@Singleton
public class ParseKeyFromJson implements Function<HttpResponse, String> {
Pattern pattern = Pattern.compile(".*private_key\": *\"([^\"]+)\".*");
private final ReturnStringIf2xx returnStringIf200;
@Inject
ParseKeyFromJson(ReturnStringIf2xx returnStringIf200) {
this.returnStringIf200 = returnStringIf200;
}
@Override
public String apply(HttpResponse response) {
String content = returnStringIf200.apply(response);
if (content == null)
return null;
return parse(content);
}
public String parse(String in) {
Matcher matcher = pattern.matcher(in);
while (matcher.find()) {
return matcher.group(1).replaceAll("\\\\n", "\n");
}
assert false : String.format("pattern: %s didn't match %s", pattern, in);
return null;
}
}

View File

@ -36,7 +36,6 @@ import org.jclouds.chef.domain.Node;
import org.jclouds.chef.domain.Role; import org.jclouds.chef.domain.Role;
import org.jclouds.chef.filters.SignedHeaderAuth; import org.jclouds.chef.filters.SignedHeaderAuth;
import org.jclouds.chef.filters.SignedHeaderAuthTest; import org.jclouds.chef.filters.SignedHeaderAuthTest;
import org.jclouds.chef.functions.ParseKeyFromJson;
import org.jclouds.chef.functions.ParseKeySetFromJson; import org.jclouds.chef.functions.ParseKeySetFromJson;
import org.jclouds.date.TimeStamp; import org.jclouds.date.TimeStamp;
import org.jclouds.encryption.EncryptionService; import org.jclouds.encryption.EncryptionService;
@ -74,9 +73,9 @@ public class ChefAsyncClientTest extends RestClientTest<ChefAsyncClient> {
Method method = ChefAsyncClient.class.getMethod("commitSandbox", String.class, boolean.class); Method method = ChefAsyncClient.class.getMethod("commitSandbox", String.class, boolean.class);
GeneratedHttpRequest<ChefAsyncClient> httpRequest = processor.createRequest(method, GeneratedHttpRequest<ChefAsyncClient> httpRequest = processor.createRequest(method,
"0189e76ccc476701d6b374e5a1a27347", true); "0189e76ccc476701d6b374e5a1a27347", true);
assertRequestLineEquals(httpRequest, assertRequestLineEquals(httpRequest,
"PUT http://localhost:4000/sandboxes/0189e76ccc476701d6b374e5a1a27347 HTTP/1.1"); "PUT http://localhost:4000/sandboxes/0189e76ccc476701d6b374e5a1a27347 HTTP/1.1");
assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\nX-Chef-Version: 0.9.8\n"); assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\nX-Chef-Version: 0.9.8\n");
assertPayloadEquals(httpRequest, "{\"is_completed\":\"true\"}", "application/json", false); assertPayloadEquals(httpRequest, "{\"is_completed\":\"true\"}", "application/json", false);
@ -92,15 +91,15 @@ public class ChefAsyncClientTest extends RestClientTest<ChefAsyncClient> {
EncryptionService encryptionService = injector.getInstance(EncryptionService.class); EncryptionService encryptionService = injector.getInstance(EncryptionService.class);
Method method = ChefAsyncClient.class.getMethod("getUploadSandboxForChecksums", Set.class); Method method = ChefAsyncClient.class.getMethod("getUploadSandboxForChecksums", Set.class);
GeneratedHttpRequest<ChefAsyncClient> httpRequest = processor.createRequest(method, ImmutableSet.of(Bytes GeneratedHttpRequest<ChefAsyncClient> httpRequest = processor.createRequest(method, ImmutableSet.of(Bytes
.asList(encryptionService.fromHex("0189e76ccc476701d6b374e5a1a27347")), Bytes.asList(encryptionService .asList(encryptionService.fromHex("0189e76ccc476701d6b374e5a1a27347")), Bytes.asList(encryptionService
.fromHex("0c5ecd7788cf4f6c7de2a57193897a6c")), Bytes.asList(encryptionService .fromHex("0c5ecd7788cf4f6c7de2a57193897a6c")), Bytes.asList(encryptionService
.fromHex("1dda05ed139664f1f89b9dec482b77c0")))); .fromHex("1dda05ed139664f1f89b9dec482b77c0"))));
assertRequestLineEquals(httpRequest, "POST http://localhost:4000/sandboxes HTTP/1.1"); assertRequestLineEquals(httpRequest, "POST http://localhost:4000/sandboxes HTTP/1.1");
assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\nX-Chef-Version: 0.9.8\n"); assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\nX-Chef-Version: 0.9.8\n");
assertPayloadEquals( assertPayloadEquals(
httpRequest, httpRequest,
"{\"checksums\":{\"0189e76ccc476701d6b374e5a1a27347\":null,\"0c5ecd7788cf4f6c7de2a57193897a6c\":null,\"1dda05ed139664f1f89b9dec482b77c0\":null}}", "{\"checksums\":{\"0189e76ccc476701d6b374e5a1a27347\":null,\"0c5ecd7788cf4f6c7de2a57193897a6c\":null,\"1dda05ed139664f1f89b9dec482b77c0\":null}}",
"application/json", false); "application/json", false);
assertResponseParserClassEquals(method, httpRequest, ParseJson.class); assertResponseParserClassEquals(method, httpRequest, ParseJson.class);
assertSaxResponseParserClassEquals(method, null); assertSaxResponseParserClassEquals(method, null);
@ -142,16 +141,16 @@ public class ChefAsyncClientTest extends RestClientTest<ChefAsyncClient> {
public void testUpdateCookbook() throws SecurityException, NoSuchMethodException, IOException { public void testUpdateCookbook() throws SecurityException, NoSuchMethodException, IOException {
Method method = ChefAsyncClient.class.getMethod("updateCookbook", String.class, String.class, Method method = ChefAsyncClient.class.getMethod("updateCookbook", String.class, String.class,
CookbookVersion.class); CookbookVersion.class);
GeneratedHttpRequest<ChefAsyncClient> httpRequest = processor.createRequest(method, "cookbook", "1.0.1", GeneratedHttpRequest<ChefAsyncClient> httpRequest = processor.createRequest(method, "cookbook", "1.0.1",
new CookbookVersion("cookbook", "1.0.1")); new CookbookVersion("cookbook", "1.0.1"));
assertRequestLineEquals(httpRequest, "PUT http://localhost:4000/cookbooks/cookbook/1.0.1 HTTP/1.1"); assertRequestLineEquals(httpRequest, "PUT http://localhost:4000/cookbooks/cookbook/1.0.1 HTTP/1.1");
assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\nX-Chef-Version: 0.9.8\n"); assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\nX-Chef-Version: 0.9.8\n");
assertPayloadEquals( assertPayloadEquals(
httpRequest, httpRequest,
"{\"name\":\"cookbook-1.0.1\",\"definitions\":[],\"attributes\":[],\"files\":[],\"metadata\":{\"suggestions\":{},\"dependencies\":{},\"conflicting\":{},\"providing\":{},\"platforms\":{},\"recipes\":{},\"replacing\":{},\"groupings\":{},\"attributes\":{},\"recommendations\":{}},\"providers\":[],\"cookbook_name\":\"cookbook\",\"resources\":[],\"templates\":[],\"libraries\":[],\"version\":\"1.0.1\",\"recipes\":[],\"root_files\":[],\"json_class\":\"Chef::CookbookVersion\",\"chef_type\":\"cookbook_version\"}", "{\"name\":\"cookbook-1.0.1\",\"definitions\":[],\"attributes\":[],\"files\":[],\"metadata\":{\"suggestions\":{},\"dependencies\":{},\"conflicting\":{},\"providing\":{},\"platforms\":{},\"recipes\":{},\"replacing\":{},\"groupings\":{},\"attributes\":{},\"recommendations\":{}},\"providers\":[],\"cookbook_name\":\"cookbook\",\"resources\":[],\"templates\":[],\"libraries\":[],\"version\":\"1.0.1\",\"recipes\":[],\"root_files\":[],\"json_class\":\"Chef::CookbookVersion\",\"chef_type\":\"cookbook_version\"}",
"application/json", false); "application/json", false);
assertResponseParserClassEquals(method, httpRequest, ParseJson.class); assertResponseParserClassEquals(method, httpRequest, ParseJson.class);
assertSaxResponseParserClassEquals(method, null); assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, null); assertExceptionParserClassEquals(method, null);
@ -214,7 +213,7 @@ public class ChefAsyncClientTest extends RestClientTest<ChefAsyncClient> {
assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\nX-Chef-Version: 0.9.8\n"); assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\nX-Chef-Version: 0.9.8\n");
assertPayloadEquals(httpRequest, "{\"clientname\":\"client\"}", "application/json", false); assertPayloadEquals(httpRequest, "{\"clientname\":\"client\"}", "application/json", false);
assertResponseParserClassEquals(method, httpRequest, ParseKeyFromJson.class); assertResponseParserClassEquals(method, httpRequest, ParseJson.class);
assertSaxResponseParserClassEquals(method, null); assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, null); assertExceptionParserClassEquals(method, null);
@ -245,7 +244,7 @@ public class ChefAsyncClientTest extends RestClientTest<ChefAsyncClient> {
assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\nX-Chef-Version: 0.9.8\n"); assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\nX-Chef-Version: 0.9.8\n");
assertPayloadEquals(httpRequest, "{\"clientname\":\"client\", \"private_key\": true}", "application/json", false); assertPayloadEquals(httpRequest, "{\"clientname\":\"client\", \"private_key\": true}", "application/json", false);
assertResponseParserClassEquals(method, httpRequest, ParseKeyFromJson.class); assertResponseParserClassEquals(method, httpRequest, ParseJson.class);
assertSaxResponseParserClassEquals(method, null); assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, null); assertExceptionParserClassEquals(method, null);
@ -286,14 +285,14 @@ public class ChefAsyncClientTest extends RestClientTest<ChefAsyncClient> {
public void testCreateNode() throws SecurityException, NoSuchMethodException, IOException { public void testCreateNode() throws SecurityException, NoSuchMethodException, IOException {
Method method = ChefAsyncClient.class.getMethod("createNode", Node.class); Method method = ChefAsyncClient.class.getMethod("createNode", Node.class);
GeneratedHttpRequest<ChefAsyncClient> httpRequest = processor.createRequest(method, new Node("testnode", GeneratedHttpRequest<ChefAsyncClient> httpRequest = processor.createRequest(method, new Node("testnode",
ImmutableSet.of("recipe[java]"))); ImmutableSet.of("recipe[java]")));
assertRequestLineEquals(httpRequest, "POST http://localhost:4000/nodes HTTP/1.1"); assertRequestLineEquals(httpRequest, "POST http://localhost:4000/nodes HTTP/1.1");
assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\nX-Chef-Version: 0.9.8\n"); assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\nX-Chef-Version: 0.9.8\n");
assertPayloadEquals( assertPayloadEquals(
httpRequest, httpRequest,
"{\"name\":\"testnode\",\"normal\":{},\"override\":{},\"default\":{},\"automatic\":{},\"run_list\":[\"recipe[java]\"],\"json_class\":\"Chef::Node\",\"chef_type\":\"node\"}", "{\"name\":\"testnode\",\"normal\":{},\"override\":{},\"default\":{},\"automatic\":{},\"run_list\":[\"recipe[java]\"],\"json_class\":\"Chef::Node\",\"chef_type\":\"node\"}",
"application/json", false); "application/json", false);
assertResponseParserClassEquals(method, httpRequest, ReleasePayloadAndReturn.class); assertResponseParserClassEquals(method, httpRequest, ReleasePayloadAndReturn.class);
assertSaxResponseParserClassEquals(method, null); assertSaxResponseParserClassEquals(method, null);
@ -306,14 +305,14 @@ public class ChefAsyncClientTest extends RestClientTest<ChefAsyncClient> {
public void testUpdateNode() throws SecurityException, NoSuchMethodException, IOException { public void testUpdateNode() throws SecurityException, NoSuchMethodException, IOException {
Method method = ChefAsyncClient.class.getMethod("updateNode", Node.class); Method method = ChefAsyncClient.class.getMethod("updateNode", Node.class);
GeneratedHttpRequest<ChefAsyncClient> httpRequest = processor.createRequest(method, new Node("testnode", GeneratedHttpRequest<ChefAsyncClient> httpRequest = processor.createRequest(method, new Node("testnode",
ImmutableSet.of("recipe[java]"))); ImmutableSet.of("recipe[java]")));
assertRequestLineEquals(httpRequest, "PUT http://localhost:4000/nodes/testnode HTTP/1.1"); assertRequestLineEquals(httpRequest, "PUT http://localhost:4000/nodes/testnode HTTP/1.1");
assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\nX-Chef-Version: 0.9.8\n"); assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\nX-Chef-Version: 0.9.8\n");
assertPayloadEquals( assertPayloadEquals(
httpRequest, httpRequest,
"{\"name\":\"testnode\",\"normal\":{},\"override\":{},\"default\":{},\"automatic\":{},\"run_list\":[\"recipe[java]\"],\"json_class\":\"Chef::Node\",\"chef_type\":\"node\"}", "{\"name\":\"testnode\",\"normal\":{},\"override\":{},\"default\":{},\"automatic\":{},\"run_list\":[\"recipe[java]\"],\"json_class\":\"Chef::Node\",\"chef_type\":\"node\"}",
"application/json", false); "application/json", false);
assertResponseParserClassEquals(method, httpRequest, ParseJson.class); assertResponseParserClassEquals(method, httpRequest, ParseJson.class);
assertSaxResponseParserClassEquals(method, null); assertSaxResponseParserClassEquals(method, null);
@ -372,14 +371,14 @@ public class ChefAsyncClientTest extends RestClientTest<ChefAsyncClient> {
public void testCreateRole() throws SecurityException, NoSuchMethodException, IOException { public void testCreateRole() throws SecurityException, NoSuchMethodException, IOException {
Method method = ChefAsyncClient.class.getMethod("createRole", Role.class); Method method = ChefAsyncClient.class.getMethod("createRole", Role.class);
GeneratedHttpRequest<ChefAsyncClient> httpRequest = processor.createRequest(method, new Role("testrole", GeneratedHttpRequest<ChefAsyncClient> httpRequest = processor.createRequest(method, new Role("testrole",
ImmutableSet.of("recipe[java]"))); ImmutableSet.of("recipe[java]")));
assertRequestLineEquals(httpRequest, "POST http://localhost:4000/roles HTTP/1.1"); assertRequestLineEquals(httpRequest, "POST http://localhost:4000/roles HTTP/1.1");
assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\nX-Chef-Version: 0.9.8\n"); assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\nX-Chef-Version: 0.9.8\n");
assertPayloadEquals( assertPayloadEquals(
httpRequest, httpRequest,
"{\"name\":\"testrole\",\"override_attributes\":{},\"default_attributes\":{},\"run_list\":[\"recipe[java]\"],\"json_class\":\"Chef::Role\",\"chef_type\":\"role\"}", "{\"name\":\"testrole\",\"override_attributes\":{},\"default_attributes\":{},\"run_list\":[\"recipe[java]\"],\"json_class\":\"Chef::Role\",\"chef_type\":\"role\"}",
"application/json", false); "application/json", false);
assertResponseParserClassEquals(method, httpRequest, ParseJson.class); assertResponseParserClassEquals(method, httpRequest, ParseJson.class);
assertSaxResponseParserClassEquals(method, null); assertSaxResponseParserClassEquals(method, null);
@ -392,14 +391,14 @@ public class ChefAsyncClientTest extends RestClientTest<ChefAsyncClient> {
public void testUpdateRole() throws SecurityException, NoSuchMethodException, IOException { public void testUpdateRole() throws SecurityException, NoSuchMethodException, IOException {
Method method = ChefAsyncClient.class.getMethod("updateRole", Role.class); Method method = ChefAsyncClient.class.getMethod("updateRole", Role.class);
GeneratedHttpRequest<ChefAsyncClient> httpRequest = processor.createRequest(method, new Role("testrole", GeneratedHttpRequest<ChefAsyncClient> httpRequest = processor.createRequest(method, new Role("testrole",
ImmutableSet.of("recipe[java]"))); ImmutableSet.of("recipe[java]")));
assertRequestLineEquals(httpRequest, "PUT http://localhost:4000/roles/testrole HTTP/1.1"); assertRequestLineEquals(httpRequest, "PUT http://localhost:4000/roles/testrole HTTP/1.1");
assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\nX-Chef-Version: 0.9.8\n"); assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\nX-Chef-Version: 0.9.8\n");
assertPayloadEquals( assertPayloadEquals(
httpRequest, httpRequest,
"{\"name\":\"testrole\",\"override_attributes\":{},\"default_attributes\":{},\"run_list\":[\"recipe[java]\"],\"json_class\":\"Chef::Role\",\"chef_type\":\"role\"}", "{\"name\":\"testrole\",\"override_attributes\":{},\"default_attributes\":{},\"run_list\":[\"recipe[java]\"],\"json_class\":\"Chef::Role\",\"chef_type\":\"role\"}",
"application/json", false); "application/json", false);
assertResponseParserClassEquals(method, httpRequest, ParseJson.class); assertResponseParserClassEquals(method, httpRequest, ParseJson.class);
assertSaxResponseParserClassEquals(method, null); assertSaxResponseParserClassEquals(method, null);
@ -455,6 +454,6 @@ public class ChefAsyncClientTest extends RestClientTest<ChefAsyncClient> {
@Override @Override
public ContextSpec<ChefClient, ChefAsyncClient> createContextSpec() { public ContextSpec<ChefClient, ChefAsyncClient> createContextSpec() {
return new RestContextFactory().createContextSpec("chef", "user", SignedHeaderAuthTest.PRIVATE_KEY, return new RestContextFactory().createContextSpec("chef", "user", SignedHeaderAuthTest.PRIVATE_KEY,
new Properties()); new Properties());
} }
} }

View File

@ -98,7 +98,7 @@ public class ChefClientLiveTest {
Properties props = new Properties(); Properties props = new Properties();
props.setProperty("chef.endpoint", endpoint); props.setProperty("chef.endpoint", endpoint);
return (ChefContext) new RestContextFactory().<ChefClient, ChefAsyncClient> createContext("chef", identity, key, return (ChefContext) new RestContextFactory().<ChefClient, ChefAsyncClient> createContext("chef", identity, key,
ImmutableSet.<Module> of(new Log4JLoggingModule()), props); ImmutableSet.<Module> of(new Log4JLoggingModule()), props);
} }
public void testCreateNewCookbook() throws Exception { public void testCreateNewCookbook() throws Exception {
@ -142,7 +142,9 @@ public class ChefClientLiveTest {
@Test(dependsOnMethods = "testCreateClient") @Test(dependsOnMethods = "testCreateClient")
public void testGenerateKeyForClient() throws Exception { public void testGenerateKeyForClient() throws Exception {
clientKey = validatorConnection.getApi().generateKeyForClient(PREFIX); clientKey = validatorConnection.utils().encryption().toPem(
validatorConnection.getApi().generateKeyForClient(PREFIX).getPrivateKey());
assertNotNull(clientKey); assertNotNull(clientKey);
clientConnection.close(); clientConnection.close();
clientConnection = createConnection(PREFIX, clientKey); clientConnection = createConnection(PREFIX, clientKey);
@ -156,9 +158,9 @@ public class ChefClientLiveTest {
System.err.printf("%s/%s:%n", cookbook, version); System.err.printf("%s/%s:%n", cookbook, version);
CookbookVersion cookbookO = adminConnection.getApi().getCookbook(cookbook, version); CookbookVersion cookbookO = adminConnection.getApi().getCookbook(cookbook, version);
for (Resource resource : ImmutableList.<Resource> builder().addAll(cookbookO.getDefinitions()).addAll( for (Resource resource : ImmutableList.<Resource> builder().addAll(cookbookO.getDefinitions()).addAll(
cookbookO.getFiles()).addAll(cookbookO.getLibraries()).addAll(cookbookO.getProviders()).addAll( cookbookO.getFiles()).addAll(cookbookO.getLibraries()).addAll(cookbookO.getProviders()).addAll(
cookbookO.getRecipes()).addAll(cookbookO.getResources()).addAll(cookbookO.getRootFiles()).addAll( cookbookO.getRecipes()).addAll(cookbookO.getResources()).addAll(cookbookO.getRootFiles()).addAll(
cookbookO.getTemplates()).build()) { cookbookO.getTemplates()).build()) {
try { try {
InputStream stream = adminConnection.utils().http().get(resource.getUrl()); InputStream stream = adminConnection.utils().http().get(resource.getUrl());
byte[] md5 = adminConnection.utils().encryption().md5(stream); byte[] md5 = adminConnection.utils().encryption().md5(stream);
@ -189,28 +191,30 @@ public class ChefClientLiveTest {
CookbookVersion cook = adminConnection.getApi().getCookbook(cookbook, version); CookbookVersion cook = adminConnection.getApi().getCookbook(cookbook, version);
adminConnection.getApi().deleteCookbook(cookbook, version); adminConnection.getApi().deleteCookbook(cookbook, version);
assert adminConnection.getApi().getCookbook(cookbook, version) == null : cookbook + version; assert adminConnection.getApi().getCookbook(cookbook, version) == null : cookbook + version;
adminConnection.getApi().updateCookbook(cookbook, version, cook); adminConnection.getApi().updateCookbook(cookbook, version, cook);
} }
} }
@Test @Test
public void testListClients() throws Exception { public void testListClients() throws Exception {
Set<String> clients = validatorConnection.getApi().listClients(); for (String client : validatorConnection.getApi().listClients())
assertNotNull(clients); assertNotNull(validatorConnection.getApi().getClient(client));
assert clients.contains(validator) : "validator: " + validator + " not in: " + clients;
} }
@Test(dependsOnMethods = "testListClients") @Test(dependsOnMethods = "testListClients")
public void testCreateClient() throws Exception { public void testCreateClient() throws Exception {
validatorConnection.getApi().deleteClient(PREFIX); validatorConnection.getApi().deleteClient(PREFIX);
clientKey = validatorConnection.getApi().createClient(PREFIX);
assertNotNull(clientKey); clientKey = validatorConnection.utils().encryption().toPem(
validatorConnection.getApi().createClient(PREFIX).getPrivateKey());
System.out.println(clientKey); System.out.println(clientKey);
assertNotNull(clientKey);
clientConnection = createConnection(PREFIX, clientKey); clientConnection = createConnection(PREFIX, clientKey);
clientConnection.getApi().clientExists(PREFIX); clientConnection.getApi().clientExists(PREFIX);
Set<String> clients = adminConnection.getApi().listClients(); Set<String> clients = validatorConnection.getApi().listClients();
assert clients.contains(PREFIX) : String.format("client %s not in %s", PREFIX, clients); assert clients.contains(PREFIX) : String.format("client %s not in %s", PREFIX, clients);
assertNotNull(validatorConnection.getApi().getClient(PREFIX));
} }
@Test(dependsOnMethods = "testCreateClient") @Test(dependsOnMethods = "testCreateClient")

View File

@ -1,14 +1,18 @@
package org.jclouds.chef.functions; package org.jclouds.chef.functions;
import static org.jclouds.io.Payloads.newStringPayload; import static org.jclouds.io.Payloads.newInputStreamPayload;
import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertEquals;
import java.io.IOException; import java.io.IOException;
import java.security.PrivateKey;
import java.security.cert.X509Certificate;
import org.jclouds.chef.config.ChefParserModule; import org.jclouds.chef.config.ChefParserModule;
import org.jclouds.chef.domain.Client; import org.jclouds.chef.domain.Client;
import org.jclouds.encryption.EncryptionService;
import org.jclouds.http.HttpResponse; import org.jclouds.http.HttpResponse;
import org.jclouds.http.functions.ParseJson; import org.jclouds.http.functions.ParseJson;
import org.jclouds.io.Payloads;
import org.jclouds.json.config.GsonModule; import org.jclouds.json.config.GsonModule;
import org.testng.annotations.BeforeTest; import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test; import org.testng.annotations.Test;
@ -26,22 +30,35 @@ import com.google.inject.TypeLiteral;
@Test(groups = "unit", sequential = true, testName = "chef.ParseClientFromJsonTest") @Test(groups = "unit", sequential = true, testName = "chef.ParseClientFromJsonTest")
public class ParseClientFromJsonTest { public class ParseClientFromJsonTest {
private static final String PRIVATE_KEY = "-----BEGIN RSA PRIVATE KEY-----\nMIIEpQIBAAKCAQEAyb2ZJJqGm0KKR+8nfQJNsSd+F9tXNMV7CfOcW6jsqs8EZgiV\nR09hD1IYOj4YqM0qJONlgyg4xRWewdSG7QTPj1lJpVAida9sXy2+kzyagZA1Am0O\nZcbqb5hoeIDgcX+eDa79s0u0DomjcfO9EKhvHLBz+zM+3QqPRkPV8nYTbfs+HjVz\nzOU6D1B0XR3+IPZZl2AnWs2d0qhnStHcDUvnRVQ0P482YwN9VgceOZtpPz0DCKEJ\n5Tx5STub8k0/zt/VAMHQafLSuQMLd2s4ZLuOZptN//uAsTmxireqd37z+8ZTdBbJ\n8LEpJ+iCXuSfm5aUh7iw6oxvToY2AL53+jK2UQIDAQABAoIBAQDA88B3i/xWn0vX\nBVxFamCYoecuNjGwXXkSyZew616A+EOCu47bh4aTurdFbYL0YFaAtaWvzlaN2eHg\nDb+HDuTefE29+WkcGk6SshPmiz5T0XOCAICWw6wSVDkHmGwS4jZvbAFm7W8nwGk9\nYhxgxFiRngswJZFopOLoF5WXs2td8guIYNslMpo7tu50iFnBHwKO2ZsPAk8t9nnS\nxlDavKruymEmqHCr3+dtio5eaenJcp3fjoXBQOKUk3ipII29XRB8NqeCVV/7Kxwq\nckqOBEbRwBclckyIbD+RiAgKvOelORjEiE9R42vuqvxRA6k9kd9o7utlX0AUtpEn\n3gZc6LepAoGBAP9ael5Y75+sK2JJUNOOhO8ae45cdsilp2yI0X+UBaSuQs2+dyPp\nkpEHAxd4pmmSvn/8c9TlEZhr+qYbABXVPlDncxpIuw2Ajbk7s/S4XaSKsRqpXL57\nzj/QOqLkRk8+OVV9q6lMeQNqLtEj1u6JPviX70Ro+FQtRttNOYbfdP/fAoGBAMpA\nXjR5woV5sUb+REg9vEuYo8RSyOarxqKFCIXVUNsLOx+22+AK4+CQpbueWN7jotrl\nYD6uT6svWi3AAC7kiY0UI/fjVPRCUi8tVoQUE0TaU5VLITaYOB+W/bBaDE4M9560\n1NuDWO90baA5dfU44iuzva02rGJXK9+nS3o8nk/PAoGBALOL6djnDe4mwAaG6Jco\ncd4xr8jkyPzCRZuyBCSBbwphIUXLc7hDprPky064ncJD1UDmwIdkXd/fpMkg2QmA\n/CUk6LEFjMisqHojOaCL9gQZJPhLN5QUN2x1PJWGjs1vQh8Tkx0iUUCOa8bQPXNR\n+34OTsW6TUna4CSZAycLfhffAoGBAIggVsefBCvuQkF0NeUhmDCRZfhnd8y55RHR\n1HCvqKIlpv+rhcX/zmyBLuteopYyRJRsOiE2FW00i8+rIPRu4Z3Q5nybx7w3PzV9\noHN5R5baE9OyI4KpZWztpYYitZF67NcnAvVULHHOvVJQGnKYfLHJYmrJF7GA1ojM\nAuMdFbjFAoGAPxUhxwFy8gaqBahKUEZn4F81HFP5ihGhkT4QL6AFPO2e+JhIGjuR\n27+85hcFqQ+HHVtFsm81b/a+R7P4UuCRgc8eCjxQMoJ1Xl4n7VbjPbHMnIN0Ryvd\nO4ZpWDWYnCO021JTOUUOJ4J/y0416Bvkw0z59y7sNX7wDBBHHbK/XCc=\n-----END RSA PRIVATE KEY-----\n";
private static final String CERTIFICATE = "-----BEGIN CERTIFICATE-----\nMIIClzCCAgCgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBnjELMAkGA1UEBhMCVVMx\nEzARBgNVBAgMCldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUxFjAUBgNVBAoM\nDU9wc2NvZGUsIEluYy4xHDAaBgNVBAsME0NlcnRpZmljYXRlIFNlcnZpY2UxMjAw\nBgNVBAMMKW9wc2NvZGUuY29tL2VtYWlsQWRkcmVzcz1hdXRoQG9wc2NvZGUuY29t\nMB4XDTEwMDczMDIwNDEzMFoXDTIwMDcyNzIwNDEzMFowADCCASIwDQYJKoZIhvcN\nAQEBBQADggEPADCCAQoCggEBAMm9mSSahptCikfvJ30CTbEnfhfbVzTFewnznFuo\n7KrPBGYIlUdPYQ9SGDo+GKjNKiTjZYMoOMUVnsHUhu0Ez49ZSaVQInWvbF8tvpM8\nmoGQNQJtDmXG6m+YaHiA4HF/ng2u/bNLtA6Jo3HzvRCobxywc/szPt0Kj0ZD1fJ2\nE237Ph41c8zlOg9QdF0d/iD2WZdgJ1rNndKoZ0rR3A1L50VUND+PNmMDfVYHHjmb\naT89AwihCeU8eUk7m/JNP87f1QDB0Gny0rkDC3drOGS7jmabTf/7gLE5sYq3qnd+\n8/vGU3QWyfCxKSfogl7kn5uWlIe4sOqMb06GNgC+d/oytlECAwEAATANBgkqhkiG\n9w0BAQUFAAOBgQBftzSZxstWw60GqRTDNN/F2GnrdtnKBoXzHww3r6jtGEylYq20\n5KfKpEx+sPX0gyZuYJiXC2CkEjImAluWKcdN9ZF6VD541sheAjbiaU7q7ZsztTxF\nWUH2tCvHeDXYKPKek3QzL7bYpUhLnCN/XxEv6ibeMDwtI7f5qpk2Aspzcw==\n-----END CERTIFICATE-----\n";
private ParseJson<Client> handler; private ParseJson<Client> handler;
private EncryptionService encryptionService;
private PrivateKey privateKey;
private X509Certificate certificate;
@BeforeTest @BeforeTest
protected void setUpInjector() throws IOException { protected void setUpInjector() throws IOException {
Injector injector = Guice.createInjector(new ChefParserModule(), new GsonModule()); Injector injector = Guice.createInjector(new ChefParserModule(), new GsonModule());
handler = injector.getInstance(Key.get(new TypeLiteral<ParseJson<Client>>() { handler = injector.getInstance(Key.get(new TypeLiteral<ParseJson<Client>>() {
})); }));
encryptionService = injector.getInstance(EncryptionService.class);
certificate = encryptionService.x509CertificateFromPEM(CERTIFICATE.getBytes("UTF-8"));
privateKey = encryptionService.privateKeyFromPEM(PRIVATE_KEY.getBytes("UTF-8"));
} }
public void test() { public void test() {
Client user = new Client("-----BEGIN CERTIFICATE-----dXQ==-----END CERTIFICATE-----", "jclouds", Client user = new Client(certificate, "jclouds", "adriancole-jcloudstest", "adriancole-jcloudstest", false,
"adrian-jcloudstest", "adrian-jcloudstest", false); privateKey);
String toParse = "{ \"certificate\":\"-----BEGIN CERTIFICATE-----dXQ==-----END CERTIFICATE-----\", \"orgname\":\"jclouds\", \"clientname\":\"adrian-jcloudstest\", \"name\": \"adrian-jcloudstest\",\"validator\": false }"; byte[] encrypted = encryptionService.rsaEncrypt(Payloads.newPayload("fooya"), user.getCertificate()
System.out.println(toParse); .getPublicKey());
assertEquals(handler.apply(new HttpResponse(200, "ok", newStringPayload(toParse))), user);
assertEquals(encryptionService.rsaDecrypt(Payloads.newPayload(encrypted), user.getPrivateKey()), "fooya"
.getBytes());
assertEquals(handler.apply(new HttpResponse(200, "ok", newInputStreamPayload(ParseClientFromJsonTest.class
.getResourceAsStream("/client.json")))), user);
} }
} }

View File

@ -1,51 +0,0 @@
package org.jclouds.chef.functions;
import static org.testng.Assert.assertEquals;
import java.io.IOException;
import org.jclouds.chef.config.ChefParserModule;
import org.jclouds.http.HttpResponse;
import org.jclouds.io.Payloads;
import org.jclouds.json.config.GsonModule;
import org.jclouds.util.Utils;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
import com.google.inject.Guice;
import com.google.inject.Injector;
/**
* Tests behavior of {@code ParseKeyFromJson}
*
* @author Adrian Cole
*/
@Test(groups = "unit", sequential = true, testName = "chef.ParseKeyFromJsonTest")
public class ParseKeyFromJsonTest {
private ParseKeyFromJson handler;
@BeforeTest
protected void setUpInjector() throws IOException {
Injector injector = Guice.createInjector(new ChefParserModule(), new GsonModule());
handler = injector.getInstance(ParseKeyFromJson.class);
}
public void testRegex() {
assertEquals(
handler
.apply(new HttpResponse(
200,
"ok",
Payloads
.newPayload(Utils
.toInputStream("{\n\"uri\": \"https://api.opscode.com/users/bobo\", \"private_key\": \"RSA_PRIVATE_KEY\",}")))),
"RSA_PRIVATE_KEY");
}
public void test2() {
String key = handler.apply(new HttpResponse(200, "ok", Payloads.newPayload(ParseKeyFromJsonTest.class
.getResourceAsStream("/newclient.txt"))));
assert key.startsWith("-----BEGIN RSA PRIVATE KEY-----\n");
}
}

View File

@ -0,0 +1 @@
{"orgname":"jclouds","certificate":"-----BEGIN CERTIFICATE-----\nMIIClzCCAgCgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBnjELMAkGA1UEBhMCVVMx\nEzARBgNVBAgMCldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUxFjAUBgNVBAoM\nDU9wc2NvZGUsIEluYy4xHDAaBgNVBAsME0NlcnRpZmljYXRlIFNlcnZpY2UxMjAw\nBgNVBAMMKW9wc2NvZGUuY29tL2VtYWlsQWRkcmVzcz1hdXRoQG9wc2NvZGUuY29t\nMB4XDTEwMDczMDIwNDEzMFoXDTIwMDcyNzIwNDEzMFowADCCASIwDQYJKoZIhvcN\nAQEBBQADggEPADCCAQoCggEBAMm9mSSahptCikfvJ30CTbEnfhfbVzTFewnznFuo\n7KrPBGYIlUdPYQ9SGDo+GKjNKiTjZYMoOMUVnsHUhu0Ez49ZSaVQInWvbF8tvpM8\nmoGQNQJtDmXG6m+YaHiA4HF/ng2u/bNLtA6Jo3HzvRCobxywc/szPt0Kj0ZD1fJ2\nE237Ph41c8zlOg9QdF0d/iD2WZdgJ1rNndKoZ0rR3A1L50VUND+PNmMDfVYHHjmb\naT89AwihCeU8eUk7m/JNP87f1QDB0Gny0rkDC3drOGS7jmabTf/7gLE5sYq3qnd+\n8/vGU3QWyfCxKSfogl7kn5uWlIe4sOqMb06GNgC+d/oytlECAwEAATANBgkqhkiG\n9w0BAQUFAAOBgQBftzSZxstWw60GqRTDNN/F2GnrdtnKBoXzHww3r6jtGEylYq20\n5KfKpEx+sPX0gyZuYJiXC2CkEjImAluWKcdN9ZF6VD541sheAjbiaU7q7ZsztTxF\nWUH2tCvHeDXYKPKek3QzL7bYpUhLnCN/XxEv6ibeMDwtI7f5qpk2Aspzcw==\n-----END CERTIFICATE-----\n","uri":"https://api.opscode.com/organizations/jclouds/clients/adriancole-jcloudstest","private_key":"-----BEGIN RSA PRIVATE KEY-----\nMIIEpQIBAAKCAQEAyb2ZJJqGm0KKR+8nfQJNsSd+F9tXNMV7CfOcW6jsqs8EZgiV\nR09hD1IYOj4YqM0qJONlgyg4xRWewdSG7QTPj1lJpVAida9sXy2+kzyagZA1Am0O\nZcbqb5hoeIDgcX+eDa79s0u0DomjcfO9EKhvHLBz+zM+3QqPRkPV8nYTbfs+HjVz\nzOU6D1B0XR3+IPZZl2AnWs2d0qhnStHcDUvnRVQ0P482YwN9VgceOZtpPz0DCKEJ\n5Tx5STub8k0/zt/VAMHQafLSuQMLd2s4ZLuOZptN//uAsTmxireqd37z+8ZTdBbJ\n8LEpJ+iCXuSfm5aUh7iw6oxvToY2AL53+jK2UQIDAQABAoIBAQDA88B3i/xWn0vX\nBVxFamCYoecuNjGwXXkSyZew616A+EOCu47bh4aTurdFbYL0YFaAtaWvzlaN2eHg\nDb+HDuTefE29+WkcGk6SshPmiz5T0XOCAICWw6wSVDkHmGwS4jZvbAFm7W8nwGk9\nYhxgxFiRngswJZFopOLoF5WXs2td8guIYNslMpo7tu50iFnBHwKO2ZsPAk8t9nnS\nxlDavKruymEmqHCr3+dtio5eaenJcp3fjoXBQOKUk3ipII29XRB8NqeCVV/7Kxwq\nckqOBEbRwBclckyIbD+RiAgKvOelORjEiE9R42vuqvxRA6k9kd9o7utlX0AUtpEn\n3gZc6LepAoGBAP9ael5Y75+sK2JJUNOOhO8ae45cdsilp2yI0X+UBaSuQs2+dyPp\nkpEHAxd4pmmSvn/8c9TlEZhr+qYbABXVPlDncxpIuw2Ajbk7s/S4XaSKsRqpXL57\nzj/QOqLkRk8+OVV9q6lMeQNqLtEj1u6JPviX70Ro+FQtRttNOYbfdP/fAoGBAMpA\nXjR5woV5sUb+REg9vEuYo8RSyOarxqKFCIXVUNsLOx+22+AK4+CQpbueWN7jotrl\nYD6uT6svWi3AAC7kiY0UI/fjVPRCUi8tVoQUE0TaU5VLITaYOB+W/bBaDE4M9560\n1NuDWO90baA5dfU44iuzva02rGJXK9+nS3o8nk/PAoGBALOL6djnDe4mwAaG6Jco\ncd4xr8jkyPzCRZuyBCSBbwphIUXLc7hDprPky064ncJD1UDmwIdkXd/fpMkg2QmA\n/CUk6LEFjMisqHojOaCL9gQZJPhLN5QUN2x1PJWGjs1vQh8Tkx0iUUCOa8bQPXNR\n+34OTsW6TUna4CSZAycLfhffAoGBAIggVsefBCvuQkF0NeUhmDCRZfhnd8y55RHR\n1HCvqKIlpv+rhcX/zmyBLuteopYyRJRsOiE2FW00i8+rIPRu4Z3Q5nybx7w3PzV9\noHN5R5baE9OyI4KpZWztpYYitZF67NcnAvVULHHOvVJQGnKYfLHJYmrJF7GA1ojM\nAuMdFbjFAoGAPxUhxwFy8gaqBahKUEZn4F81HFP5ihGhkT4QL6AFPO2e+JhIGjuR\n27+85hcFqQ+HHVtFsm81b/a+R7P4UuCRgc8eCjxQMoJ1Xl4n7VbjPbHMnIN0Ryvd\nO4ZpWDWYnCO021JTOUUOJ4J/y0416Bvkw0z59y7sNX7wDBBHHbK/XCc=\n-----END RSA PRIVATE KEY-----\n","clientname":"adriancole-jcloudstest","name":"adriancole-jcloudstest","validator":false}

View File

@ -31,6 +31,7 @@ import java.util.Properties;
import java.util.Set; import java.util.Set;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener; import javax.servlet.ServletContextListener;
@ -39,14 +40,13 @@ import org.jclouds.chef.ChefAsyncClient;
import org.jclouds.chef.ChefClient; import org.jclouds.chef.ChefClient;
import org.jclouds.chef.ChefContext; import org.jclouds.chef.ChefContext;
import org.jclouds.chef.ChefService; import org.jclouds.chef.ChefService;
import org.jclouds.chef.domain.Client;
import org.jclouds.chef.reference.ChefConstants; import org.jclouds.chef.reference.ChefConstants;
import org.jclouds.chef.servlet.functions.InitParamsToProperties; import org.jclouds.chef.servlet.functions.InitParamsToProperties;
import org.jclouds.logging.Logger; import org.jclouds.logging.Logger;
import org.jclouds.logging.jdk.JDKLogger; import org.jclouds.logging.jdk.JDKLogger;
import org.jclouds.rest.RestContextFactory; import org.jclouds.rest.RestContextFactory;
import java.util.concurrent.Future;
/** /**
* Registers a new node in Chef and binds its name to {@link ChefConstants.CHEF_NODE}, its role to * Registers a new node in Chef and binds its name to {@link ChefConstants.CHEF_NODE}, its role to
* {@link ChefConstants.CHEF_ROLE} and the {@link ChefService} for the client to * {@link ChefConstants.CHEF_ROLE} and the {@link ChefService} for the client to
@ -121,7 +121,7 @@ public class ChefRegistrationListener implements ServletContextListener {
private ChefService createClientAndNode(ChefService validatorClient, String role, String id, Properties overrides) { private ChefService createClientAndNode(ChefService validatorClient, String role, String id, Properties overrides) {
logger.trace("attempting to create client %s", id); logger.trace("attempting to create client %s", id);
String clientKey = validatorClient.getContext().getApi().createClient(id); Client client = validatorClient.getContext().getApi().createClient(id);
logger.debug("created client %s", id); logger.debug("created client %s", id);
ChefService clientService = null; ChefService clientService = null;
try { try {
@ -129,7 +129,8 @@ public class ChefRegistrationListener implements ServletContextListener {
clientProperties.putAll(overrides); clientProperties.putAll(overrides);
removeCredentials(clientProperties); removeCredentials(clientProperties);
clientProperties.setProperty("chef.identity", id); clientProperties.setProperty("chef.identity", id);
clientProperties.setProperty("chef.credential", clientKey); clientProperties.setProperty("chef.credential", validatorClient.getContext().utils().encryption().toPem(
client.getPrivateKey()));
clientService = createService(clientProperties); clientService = createService(clientProperties);
clientService.createNodeAndPopulateAutomaticAttributes(id, singleton("role[" + role + "]")); clientService.createNodeAndPopulateAutomaticAttributes(id, singleton("role[" + role + "]"));
return clientService; return clientService;

View File

@ -24,6 +24,8 @@ import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.security.Key; import java.security.Key;
import java.security.PrivateKey; import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.cert.X509Certificate;
import org.jclouds.encryption.internal.JCEEncryptionService; import org.jclouds.encryption.internal.JCEEncryptionService;
import org.jclouds.http.PayloadEnclosing; import org.jclouds.http.PayloadEnclosing;
@ -46,7 +48,7 @@ public interface EncryptionService {
byte[] fromHex(String encoded); byte[] fromHex(String encoded);
byte[] rsaSign(String toSign, Key privateKey); byte[] rsaEncrypt(Payload payload, Key key);
byte[] hmacSha256(String toEncode, byte[] key); byte[] hmacSha256(String toEncode, byte[] key);
@ -64,6 +66,7 @@ public interface EncryptionService {
* <h2>Note</h2> * <h2>Note</h2>
* <p/> * <p/>
* If this is an InputStream, it will be converted to a byte array first. * If this is an InputStream, it will be converted to a byte array first.
*
* @throws IOException * @throws IOException
*/ */
<T extends PayloadEnclosing> T generateMD5BufferingIfNotRepeatable(T payloadEnclosing); <T extends PayloadEnclosing> T generateMD5BufferingIfNotRepeatable(T payloadEnclosing);
@ -74,7 +77,7 @@ public interface EncryptionService {
MD5OutputStream md5OutputStream(OutputStream out); MD5OutputStream md5OutputStream(OutputStream out);
PrivateKey readPrivateKeyFromPEM(byte [] pem); PrivateKey privateKeyFromPEM(byte[] pem);
public static abstract class MD5OutputStream extends FilterOutputStream { public static abstract class MD5OutputStream extends FilterOutputStream {
public MD5OutputStream(OutputStream out) { public MD5OutputStream(OutputStream out) {
@ -84,4 +87,16 @@ public interface EncryptionService {
public abstract byte[] getMD5(); public abstract byte[] getMD5();
} }
PublicKey publicKeyFromPEM(byte[] pem);
X509Certificate x509CertificateFromPEM(byte[] pem);
byte[] rsaDecrypt(Payload payload, Key key);
String toPem(X509Certificate cert);
String toPem(PublicKey key);
String toPem(PrivateKey key);
} }

View File

@ -20,15 +20,33 @@ package org.jclouds.encryption.internal;
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.propagate;
import static com.google.common.io.Closeables.closeQuietly;
import java.io.ByteArrayInputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.KeyFactory; import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey; import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.cert.CertificateEncodingException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.security.spec.KeySpec; import java.security.spec.KeySpec;
import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Arrays;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.ShortBufferException;
import net.oauth.signature.pem.PEMReader; import net.oauth.signature.pem.PEMReader;
import net.oauth.signature.pem.PKCS1EncodedKeySpec; import net.oauth.signature.pem.PKCS1EncodedKeySpec;
@ -52,12 +70,14 @@ public abstract class BaseEncryptionService implements EncryptionService {
protected static final int BUF_SIZE = 0x2000; // 8 protected static final int BUF_SIZE = 0x2000; // 8
final byte[] HEX_CHAR_TABLE = { (byte) '0', (byte) '1', (byte) '2', (byte) '3', (byte) '4', (byte) '5', (byte) '6', final byte[] HEX_CHAR_TABLE = { (byte) '0', (byte) '1', (byte) '2', (byte) '3', (byte) '4', (byte) '5', (byte) '6',
(byte) '7', (byte) '8', (byte) '9', (byte) 'a', (byte) 'b', (byte) 'c', (byte) 'd', (byte) 'e', (byte) 'f' }; (byte) '7', (byte) '8', (byte) '9', (byte) 'a', (byte) 'b', (byte) 'c', (byte) 'd', (byte) 'e', (byte) 'f' };
private final KeyFactory rsaKeyFactory; private final KeyFactory rsaKeyFactory;
private final CertificateFactory certFactory;
public BaseEncryptionService(KeyFactory rsaKeyFactory) { public BaseEncryptionService(KeyFactory rsaKeyFactory, CertificateFactory certFactory) {
this.rsaKeyFactory = rsaKeyFactory; this.rsaKeyFactory = rsaKeyFactory;
this.certFactory = certFactory;
} }
@Override @Override
@ -118,7 +138,7 @@ public abstract class BaseEncryptionService implements EncryptionService {
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override @Override
public PrivateKey readPrivateKeyFromPEM(byte[] pem) { public PrivateKey privateKeyFromPEM(byte[] pem) {
PEMReader reader; PEMReader reader;
try { try {
reader = new PEMReader(pem); reader = new PEMReader(pem);
@ -131,7 +151,7 @@ public abstract class BaseEncryptionService implements EncryptionService {
} else if (PEMReader.PRIVATE_PKCS8_MARKER.equals(reader.getBeginMarker())) { } else if (PEMReader.PRIVATE_PKCS8_MARKER.equals(reader.getBeginMarker())) {
keySpec = new PKCS8EncodedKeySpec(bytes); keySpec = new PKCS8EncodedKeySpec(bytes);
} else { } else {
throw new IOException("Invalid PEM file: Unknown marker " + "for private key " + reader.getBeginMarker()); throw new IOException("Invalid PEM file: Unknown marker for private key " + reader.getBeginMarker());
} }
return rsaKeyFactory.generatePrivate(keySpec); return rsaKeyFactory.generatePrivate(keySpec);
} catch (Exception e) { } catch (Exception e) {
@ -139,4 +159,141 @@ public abstract class BaseEncryptionService implements EncryptionService {
return null; return null;
} }
} }
/**
* {@inheritDoc}
*/
@Override
public PublicKey publicKeyFromPEM(byte[] pem) {
PEMReader reader;
try {
reader = new PEMReader(pem);
byte[] bytes = reader.getDerBytes();
KeySpec keySpec;
if (PEMReader.PUBLIC_X509_MARKER.equals(reader.getBeginMarker())) {
keySpec = new X509EncodedKeySpec(bytes);
} else {
throw new IOException("Invalid PEM file: Unknown marker for public key " + reader.getBeginMarker());
}
return rsaKeyFactory.generatePublic(keySpec);
} catch (Exception e) {
Throwables.propagate(e);
return null;
}
}
/**
* {@inheritDoc}
*/
@Override
public X509Certificate x509CertificateFromPEM(byte[] pem) {
PEMReader reader;
try {
reader = new PEMReader(pem);
byte[] bytes = reader.getDerBytes();
if (PEMReader.CERTIFICATE_X509_MARKER.equals(reader.getBeginMarker())) {
return (X509Certificate) certFactory.generateCertificate(new ByteArrayInputStream(bytes));
} else {
throw new IOException("Invalid PEM file: Unknown marker for public key " + reader.getBeginMarker());
}
} catch (Exception e) {
Throwables.propagate(e);
return null;
}
}
@Override
public byte[] rsaEncrypt(Payload payload, Key key) {
// TODO convert this to BC code
Cipher cipher = null;
try {
cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, key);
} catch (NoSuchAlgorithmException e) {
Throwables.propagate(e);
} catch (NoSuchPaddingException e) {
Throwables.propagate(e);
} catch (InvalidKeyException e) {
Throwables.propagate(e);
}
return cipherPayload(cipher, payload);
}
@Override
public byte[] rsaDecrypt(Payload payload, Key key) {
// TODO convert this to BC code
Cipher cipher = null;
try {
cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, key);
} catch (NoSuchAlgorithmException e) {
Throwables.propagate(e);
} catch (NoSuchPaddingException e) {
Throwables.propagate(e);
} catch (InvalidKeyException e) {
Throwables.propagate(e);
}
return cipherPayload(cipher, payload);
}
private byte[] cipherPayload(Cipher cipher, Payload payload) {
byte[] resBuf = new byte[cipher.getOutputSize(payload.getContentLength().intValue())];
byte[] buffer = new byte[BUF_SIZE];
long length = 0;
int numRead = -1;
InputStream plainBytes = payload.getInput();
try {
do {
numRead = plainBytes.read(buffer);
if (numRead > 0) {
length += numRead;
cipher.update(buffer, 0, numRead);
}
} while (numRead != -1);
} catch (IOException e) {
propagate(e);
} finally {
closeQuietly(plainBytes);
}
try {
int size = cipher.doFinal(resBuf, 0);
return Arrays.copyOfRange(resBuf, 0, size);
} catch (IllegalBlockSizeException e) {
Throwables.propagate(e);
} catch (ShortBufferException e) {
Throwables.propagate(e);
} catch (BadPaddingException e) {
Throwables.propagate(e);
}
assert false;
return null;
}
@Override
public String toPem(X509Certificate cert) {
try {
return new StringBuilder("-----BEGIN CERTIFICATE-----\n").append(base64(cert.getEncoded())).append(
"\n-----END CERTIFICATE-----\n").toString();
} catch (CertificateEncodingException e) {
Throwables.propagate(e);
return null;
}
}
@Override
public String toPem(PublicKey key) {
return new StringBuilder("-----BEGIN PUBLIC KEY-----\n").append(base64(key.getEncoded())).append(
"\n-----END PUBLIC KEY-----\n").toString();
}
@Override
public String toPem(PrivateKey key) {
return new StringBuilder("-----BEGIN PRIVATE KEY-----\n").append(base64(key.getEncoded())).append(
"\n-----END PRIVATE KEY-----\n").toString();
}
} }

View File

@ -27,12 +27,12 @@ import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.security.DigestOutputStream; import java.security.DigestOutputStream;
import java.security.InvalidKeyException; import java.security.InvalidKeyException;
import java.security.Key;
import java.security.KeyFactory; import java.security.KeyFactory;
import java.security.MessageDigest; import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import javax.crypto.Cipher;
import javax.crypto.Mac; import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec; import javax.crypto.spec.SecretKeySpec;
@ -44,12 +44,12 @@ import org.jclouds.io.payloads.ByteArrayPayload;
*/ */
public class JCEEncryptionService extends BaseEncryptionService { public class JCEEncryptionService extends BaseEncryptionService {
public JCEEncryptionService(KeyFactory rsaKeyFactory) { public JCEEncryptionService(KeyFactory rsaKeyFactory, CertificateFactory certFactory) {
super(rsaKeyFactory); super(rsaKeyFactory, certFactory);
} }
public JCEEncryptionService() throws NoSuchAlgorithmException { public JCEEncryptionService() throws NoSuchAlgorithmException, CertificateException {
super(KeyFactory.getInstance("RSA")); this(KeyFactory.getInstance("RSA"), CertificateFactory.getInstance("X.509"));
} }
@Override @Override
@ -199,17 +199,4 @@ public class JCEEncryptionService extends BaseEncryptionService {
return digest.digest(); return digest.digest();
} }
@Override
public byte[] rsaSign(String toSign, Key key) {
Cipher cipher;
try {
cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, key);
return cipher.doFinal(toSign.getBytes());
} catch (Exception e) {
propagate(e);
return null;
}
}
} }

View File

@ -24,7 +24,6 @@ import static org.jclouds.rest.RestContextFactory.createContextBuilder;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.security.NoSuchAlgorithmException;
import java.util.Map; import java.util.Map;
import java.util.Properties; import java.util.Properties;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
@ -39,7 +38,6 @@ import javax.ws.rs.core.HttpHeaders;
import org.jclouds.encryption.EncryptionService; import org.jclouds.encryption.EncryptionService;
import org.jclouds.encryption.internal.Base64; import org.jclouds.encryption.internal.Base64;
import org.jclouds.encryption.internal.JCEEncryptionService;
import org.jclouds.rest.RestContext; import org.jclouds.rest.RestContext;
import org.jclouds.rest.RestContextBuilder; import org.jclouds.rest.RestContextBuilder;
import org.jclouds.rest.RestContextFactory.ContextSpec; import org.jclouds.rest.RestContextFactory.ContextSpec;
@ -91,7 +89,7 @@ public abstract class BaseJettyTest {
Handler server1Handler = new AbstractHandler() { Handler server1Handler = new AbstractHandler() {
public void handle(String target, HttpServletRequest request, HttpServletResponse response, int dispatch) public void handle(String target, HttpServletRequest request, HttpServletResponse response, int dispatch)
throws IOException, ServletException { throws IOException, ServletException {
if (failIfNoContentLength(request, response)) { if (failIfNoContentLength(request, response)) {
return; return;
} else if (target.indexOf("sleep") > 0) { } else if (target.indexOf("sleep") > 0) {
@ -124,13 +122,7 @@ public abstract class BaseJettyTest {
if (request.getContentLength() > 0) { if (request.getContentLength() > 0) {
if (request.getHeader("Content-MD5") != null) { if (request.getHeader("Content-MD5") != null) {
String expectedMd5 = request.getHeader("Content-MD5"); String expectedMd5 = request.getHeader("Content-MD5");
String realMd5FromRequest; String realMd5FromRequest = Base64.encodeBytes(encryptionService.md5(request.getInputStream()));
try {
realMd5FromRequest = Base64.encodeBytes(new JCEEncryptionService()
.md5(request.getInputStream()));
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
boolean matched = expectedMd5.equals(realMd5FromRequest); boolean matched = expectedMd5.equals(realMd5FromRequest);
if (matched) { if (matched) {
response.setContentType("text/xml"); response.setContentType("text/xml");
@ -152,8 +144,7 @@ public abstract class BaseJettyTest {
response.getWriter().println("test"); response.getWriter().println("test");
} else if (request.getMethod().equals("HEAD")) { } else if (request.getMethod().equals("HEAD")) {
/* /*
* NOTE: by HTML specification, HEAD response MUST NOT include a * NOTE: by HTML specification, HEAD response MUST NOT include a body
* body
*/ */
response.setContentType("text/xml"); response.setContentType("text/xml");
response.setStatus(HttpServletResponse.SC_OK); response.setStatus(HttpServletResponse.SC_OK);
@ -175,7 +166,7 @@ public abstract class BaseJettyTest {
Handler server2Handler = new AbstractHandler() { Handler server2Handler = new AbstractHandler() {
public void handle(String target, HttpServletRequest request, HttpServletResponse response, int dispatch) public void handle(String target, HttpServletRequest request, HttpServletResponse response, int dispatch)
throws IOException, ServletException { throws IOException, ServletException {
if (request.getMethod().equals("PUT")) { if (request.getMethod().equals("PUT")) {
if (request.getContentLength() > 0) { if (request.getContentLength() > 0) {
response.setStatus(HttpServletResponse.SC_OK); response.setStatus(HttpServletResponse.SC_OK);
@ -186,12 +177,7 @@ public abstract class BaseJettyTest {
if (request.getHeader("Content-MD5") != null) { if (request.getHeader("Content-MD5") != null) {
String expectedMd5 = request.getHeader("Content-MD5"); String expectedMd5 = request.getHeader("Content-MD5");
String realMd5FromRequest; String realMd5FromRequest;
try { realMd5FromRequest = Base64.encodeBytes(encryptionService.md5(request.getInputStream()));
realMd5FromRequest = Base64.encodeBytes(new JCEEncryptionService()
.md5(request.getInputStream()));
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
boolean matched = expectedMd5.equals(realMd5FromRequest); boolean matched = expectedMd5.equals(realMd5FromRequest);
if (matched) { if (matched) {
response.setContentType("text/xml"); response.setContentType("text/xml");
@ -207,8 +193,7 @@ public abstract class BaseJettyTest {
} }
} else if (request.getMethod().equals("HEAD")) { } else if (request.getMethod().equals("HEAD")) {
/* /*
* NOTE: by HTML specification, HEAD response MUST NOT include a * NOTE: by HTML specification, HEAD response MUST NOT include a body
* body
*/ */
response.setContentType("text/xml"); response.setContentType("text/xml");
response.setStatus(HttpServletResponse.SC_OK); response.setStatus(HttpServletResponse.SC_OK);
@ -237,7 +222,7 @@ public abstract class BaseJettyTest {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public static InputSupplier<InputStream> getTestDataSupplier() throws IOException { public static InputSupplier<InputStream> getTestDataSupplier() throws IOException {
byte[] oneConstitution = ByteStreams.toByteArray(new GZIPInputStream(BaseJettyTest.class byte[] oneConstitution = ByteStreams.toByteArray(new GZIPInputStream(BaseJettyTest.class
.getResourceAsStream("/const.txt.gz"))); .getResourceAsStream("/const.txt.gz")));
InputSupplier<ByteArrayInputStream> constitutionSupplier = ByteStreams.newInputStreamSupplier(oneConstitution); InputSupplier<ByteArrayInputStream> constitutionSupplier = ByteStreams.newInputStreamSupplier(oneConstitution);
InputSupplier<InputStream> temp = ByteStreams.join(constitutionSupplier); InputSupplier<InputStream> temp = ByteStreams.join(constitutionSupplier);
@ -249,11 +234,11 @@ public abstract class BaseJettyTest {
} }
public static RestContextBuilder<IntegrationTestClient, IntegrationTestAsyncClient> newBuilder(int testPort, public static RestContextBuilder<IntegrationTestClient, IntegrationTestAsyncClient> newBuilder(int testPort,
Properties properties, Module... connectionModules) { Properties properties, Module... connectionModules) {
ContextSpec<IntegrationTestClient, IntegrationTestAsyncClient> contextSpec = contextSpec("test", ContextSpec<IntegrationTestClient, IntegrationTestAsyncClient> contextSpec = contextSpec("test",
"http://localhost:" + testPort, "1", "identity", null, IntegrationTestClient.class, "http://localhost:" + testPort, "1", "identity", null, IntegrationTestClient.class,
IntegrationTestAsyncClient.class, ImmutableSet.<Module> copyOf(connectionModules)); IntegrationTestAsyncClient.class, ImmutableSet.<Module> copyOf(connectionModules));
return createContextBuilder(contextSpec, properties); return createContextBuilder(contextSpec, properties);
} }
@ -287,7 +272,7 @@ public abstract class BaseJettyTest {
} }
protected boolean redirectEveryTwentyRequests(HttpServletRequest request, HttpServletResponse response) protected boolean redirectEveryTwentyRequests(HttpServletRequest request, HttpServletResponse response)
throws IOException { throws IOException {
if (cycle.incrementAndGet() % 20 == 0) { if (cycle.incrementAndGet() % 20 == 0) {
response.sendRedirect("http://localhost:" + (testPort + 1) + "/"); response.sendRedirect("http://localhost:" + (testPort + 1) + "/");
((Request) request).setHandled(true); ((Request) request).setHandled(true);

View File

@ -23,6 +23,7 @@ import static org.testng.Assert.assertEquals;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.net.URI; import java.net.URI;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import javax.ws.rs.core.HttpHeaders; import javax.ws.rs.core.HttpHeaders;
@ -40,7 +41,7 @@ public class BasicAuthenticationTest {
private static final String USER = "Aladdin"; private static final String USER = "Aladdin";
private static final String PASSWORD = "open sesame"; private static final String PASSWORD = "open sesame";
public void testAuth() throws UnsupportedEncodingException, NoSuchAlgorithmException { public void testAuth() throws UnsupportedEncodingException, NoSuchAlgorithmException, CertificateException {
BasicAuthentication filter = new BasicAuthentication(USER, PASSWORD, new JCEEncryptionService()); BasicAuthentication filter = new BasicAuthentication(USER, PASSWORD, new JCEEncryptionService());
HttpRequest request = new HttpRequest("GET", URI.create("http://localhost")); HttpRequest request = new HttpRequest("GET", URI.create("http://localhost"));
filter.filter(request); filter.filter(request);

View File

@ -28,6 +28,7 @@ import java.io.InputStream;
import java.net.URL; import java.net.URL;
import java.net.URLConnection; import java.net.URLConnection;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.util.concurrent.Callable; import java.util.concurrent.Callable;
import java.util.concurrent.Future; import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@ -58,6 +59,9 @@ public class WireLiveTest {
} catch (NoSuchAlgorithmException e) { } catch (NoSuchAlgorithmException e) {
Throwables.propagate(e); Throwables.propagate(e);
encryptionService = null; encryptionService = null;
} catch (CertificateException e) {
Throwables.propagate(e);
encryptionService = null;
} }
} }

View File

@ -0,0 +1,872 @@
Provided by USConstitution.net
------------------------------
[Note: Repealed text is not noted in this version. Spelling errors have been
corrected in this version. For an uncorrected, annotated version of the
Constitution, visit http://www.usconstitution.net/const.html ]
We the People of the United States, in Order to form a more perfect Union,
establish Justice, insure domestic Tranquility, provide for the common
defence, promote the general Welfare, and secure the Blessings of Liberty to
ourselves and our Posterity, do ordain and establish this Constitution for the
United States of America.
Article 1.
Section 1
All legislative Powers herein granted shall be vested in a Congress of the
United States, which shall consist of a Senate and House of Representatives.
Section 2
The House of Representatives shall be composed of Members chosen every second
Year by the People of the several States, and the Electors in each State shall
have the Qualifications requisite for Electors of the most numerous Branch of
the State Legislature.
No Person shall be a Representative who shall not have attained to the Age of
twenty five Years, and been seven Years a Citizen of the United States, and who
shall not, when elected, be an Inhabitant of that State in which he shall be
chosen.
Representatives and direct Taxes shall be apportioned among the several States
which may be included within this Union, according to their respective Numbers,
which shall be determined by adding to the whole Number of free Persons,
including those bound to Service for a Term of Years, and excluding Indians not
taxed, three fifths of all other Persons.
The actual Enumeration shall be made within three Years after the first Meeting
of the Congress of the United States, and within every subsequent Term of ten
Years, in such Manner as they shall by Law direct. The Number of
Representatives shall not exceed one for every thirty Thousand, but each State
shall have at Least one Representative; and until such enumeration shall be
made, the State of New Hampshire shall be entitled to choose three,
Massachusetts eight, Rhode Island and Providence Plantations one, Connecticut
five, New York six, New Jersey four, Pennsylvania eight, Delaware one, Maryland
six, Virginia ten, North Carolina five, South Carolina five and Georgia three.
When vacancies happen in the Representation from any State, the Executive
Authority thereof shall issue Writs of Election to fill such Vacancies.
The House of Representatives shall choose their Speaker and other Officers; and
shall have the sole Power of Impeachment.
Section 3
The Senate of the United States shall be composed of two Senators from each
State, chosen by the Legislature thereof, for six Years; and each Senator shall
have one Vote.
Immediately after they shall be assembled in Consequence of the first Election,
they shall be divided as equally as may be into three Classes. The Seats of the
Senators of the first Class shall be vacated at the Expiration of the second
Year, of the second Class at the Expiration of the fourth Year, and of the
third Class at the Expiration of the sixth Year, so that one third may be
chosen every second Year; and if Vacancies happen by Resignation, or otherwise,
during the Recess of the Legislature of any State, the Executive thereof may
make temporary Appointments until the next Meeting of the Legislature, which
shall then fill such Vacancies.
No person shall be a Senator who shall not have attained to the Age of thirty
Years, and been nine Years a Citizen of the United States, and who shall not,
when elected, be an Inhabitant of that State for which he shall be chosen.
The Vice President of the United States shall be President of the Senate, but
shall have no Vote, unless they be equally divided.
The Senate shall choose their other Officers, and also a President pro tempore,
in the absence of the Vice President, or when he shall exercise the Office of
President of the United States.
The Senate shall have the sole Power to try all Impeachments. When sitting for
that Purpose, they shall be on Oath or Affirmation. When the President of the
United States is tried, the Chief Justice shall preside: And no Person shall be
convicted without the Concurrence of two thirds of the Members present.
Judgment in Cases of Impeachment shall not extend further than to removal from
Office, and disqualification to hold and enjoy any Office of honor, Trust or
Profit under the United States: but the Party convicted shall nevertheless be
liable and subject to Indictment, Trial, Judgment and Punishment, according to
Law.
Section 4
The Times, Places and Manner of holding Elections for Senators and
Representatives, shall be prescribed in each State by the Legislature thereof;
but the Congress may at any time by Law make or alter such Regulations, except
as to the Place of Choosing Senators.
The Congress shall assemble at least once in every Year, and such Meeting shall
be on the first Monday in December, unless they shall by Law appoint a
different Day.
Section 5
Each House shall be the Judge of the Elections, Returns and Qualifications of
its own Members, and a Majority of each shall constitute a Quorum to do
Business; but a smaller number may adjourn from day to day, and may be
authorized to compel the Attendance of absent Members, in such Manner, and
under such Penalties as each House may provide.
Each House may determine the Rules of its Proceedings, punish its Members for
disorderly Behavior, and, with the Concurrence of two-thirds, expel a Member.
Each House shall keep a Journal of its Proceedings, and from time to time
publish the same, excepting such Parts as may in their Judgment require
Secrecy; and the Yeas and Nays of the Members of either House on any question
shall, at the Desire of one fifth of those Present, be entered on the Journal.
Neither House, during the Session of Congress, shall, without the Consent of
the other, adjourn for more than three days, nor to any other Place than that
in which the two Houses shall be sitting.
Section 6
The Senators and Representatives shall receive a Compensation for their
Services, to be ascertained by Law, and paid out of the Treasury of the United
States. They shall in all Cases, except Treason, Felony and Breach of the
Peace, be privileged from Arrest during their Attendance at the Session of
their respective Houses, and in going to and returning from the same; and for
any Speech or Debate in either House, they shall not be questioned in any other
Place.
No Senator or Representative shall, during the Time for which he was elected,
be appointed to any civil Office under the Authority of the United States which
shall have been created, or the Emoluments whereof shall have been increased
during such time; and no Person holding any Office under the United States,
shall be a Member of either House during his Continuance in Office.
Section 7
All bills for raising Revenue shall originate in the House of Representatives;
but the Senate may propose or concur with Amendments as on other Bills.
Every Bill which shall have passed the House of Representatives and the Senate,
shall, before it become a Law, be presented to the President of the United
States; If he approve he shall sign it, but if not he shall return it, with his
Objections to that House in which it shall have originated, who shall enter the
Objections at large on their Journal, and proceed to reconsider it. If after
such Reconsideration two thirds of that House shall agree to pass the Bill, it
shall be sent, together with the Objections, to the other House, by which it
shall likewise be reconsidered, and if approved by two thirds of that House, it
shall become a Law. But in all such Cases the Votes of both Houses shall be
determined by Yeas and Nays, and the Names of the Persons voting for and
against the Bill shall be entered on the Journal of each House respectively. If
any Bill shall not be returned by the President within ten Days (Sundays
excepted) after it shall have been presented to him, the Same shall be a Law,
in like Manner as if he had signed it, unless the Congress by their Adjournment
prevent its Return, in which Case it shall not be a Law.
Every Order, Resolution, or Vote to which the Concurrence of the Senate and
House of Representatives may be necessary (except on a question of Adjournment)
shall be presented to the President of the United States; and before the Same
shall take Effect, shall be approved by him, or being disapproved by him, shall
be repassed by two thirds of the Senate and House of Representatives, according
to the Rules and Limitations prescribed in the Case of a Bill.
Section 8
The Congress shall have Power To lay and collect Taxes, Duties, Imposts and
Excises, to pay the Debts and provide for the common Defence and general
Welfare of the United States; but all Duties, Imposts and Excises shall be
uniform throughout the United States;
To borrow money on the credit of the United States;
To regulate Commerce with foreign Nations, and among the several States, and
with the Indian Tribes;
To establish an uniform Rule of Naturalization, and uniform Laws on the subject
of Bankruptcies throughout the United States;
To coin Money, regulate the Value thereof, and of foreign Coin, and fix the
Standard of Weights and Measures;
To provide for the Punishment of counterfeiting the Securities and current Coin
of the United States;
To establish Post Offices and Post Roads;
To promote the Progress of Science and useful Arts, by securing for limited
Times to Authors and Inventors the exclusive Right to their respective Writings
and Discoveries;
To constitute Tribunals inferior to the supreme Court;
To define and punish Piracies and Felonies committed on the high Seas, and
Offenses against the Law of Nations;
To declare War, grant Letters of Marque and Reprisal, and make Rules concerning
Captures on Land and Water;
To raise and support Armies, but no Appropriation of Money to that Use shall be
for a longer Term than two Years;
To provide and maintain a Navy;
To make Rules for the Government and Regulation of the land and naval Forces;
To provide for calling forth the Militia to execute the Laws of the Union,
suppress Insurrections and repel Invasions;
To provide for organizing, arming, and disciplining the Militia, and for
governing such Part of them as may be employed in the Service of the United
States, reserving to the States respectively, the Appointment of the Officers,
and the Authority of training the Militia according to the discipline
prescribed by Congress;
To exercise exclusive Legislation in all Cases whatsoever, over such District
(not exceeding ten Miles square) as may, by Cession of particular States, and
the acceptance of Congress, become the Seat of the Government of the United
States, and to exercise like Authority over all Places purchased by the Consent
of the Legislature of the State in which the Same shall be, for the Erection of
Forts, Magazines, Arsenals, dock-Yards, and other needful Buildings; And
To make all Laws which shall be necessary and proper for carrying into
Execution the foregoing Powers, and all other Powers vested by this
Constitution in the Government of the United States, or in any Department or
Officer thereof.
Section 9
The Migration or Importation of such Persons as any of the States now existing
shall think proper to admit, shall not be prohibited by the Congress prior to
the Year one thousand eight hundred and eight, but a tax or duty may be imposed
on such Importation, not exceeding ten dollars for each Person.
The privilege of the Writ of Habeas Corpus shall not be suspended, unless when
in Cases of Rebellion or Invasion the public Safety may require it.
No Bill of Attainder or ex post facto Law shall be passed.
No capitation, or other direct, Tax shall be laid, unless in Proportion to the
Census or Enumeration herein before directed to be taken.
No Tax or Duty shall be laid on Articles exported from any State.
No Preference shall be given by any Regulation of Commerce or Revenue to the
Ports of one State over those of another: nor shall Vessels bound to, or from,
one State, be obliged to enter, clear, or pay Duties in another.
No Money shall be drawn from the Treasury, but in Consequence of Appropriations
made by Law; and a regular Statement and Account of the Receipts and
Expenditures of all public Money shall be published from time to time.
No Title of Nobility shall be granted by the United States: And no Person
holding any Office of Profit or Trust under them, shall, without the Consent of
the Congress, accept of any present, Emolument, Office, or Title, of any kind
whatever, from any King, Prince or foreign State.
Section 10
No State shall enter into any Treaty, Alliance, or Confederation; grant Letters
of Marque and Reprisal; coin Money; emit Bills of Credit; make any Thing but
gold and silver Coin a Tender in Payment of Debts; pass any Bill of Attainder,
ex post facto Law, or Law impairing the Obligation of Contracts, or grant any
Title of Nobility.
No State shall, without the Consent of the Congress, lay any Imposts or Duties
on Imports or Exports, except what may be absolutely necessary for executing
its inspection Laws: and the net Produce of all Duties and Imposts, laid by
any State on Imports or Exports, shall be for the Use of the Treasury of the
United States; and all such Laws shall be subject to the Revision and Control
of the Congress.
No State shall, without the Consent of Congress, lay any duty of Tonnage, keep
Troops, or Ships of War in time of Peace, enter into any Agreement or Compact
with another State, or with a foreign Power, or engage in War, unless actually
invaded, or in such imminent Danger as will not admit of delay.
Article 2.
Section 1
The executive Power shall be vested in a President of the United States of
America. He shall hold his Office during the Term of four Years, and, together
with the Vice-President chosen for the same Term, be elected, as follows:
Each State shall appoint, in such Manner as the Legislature thereof may direct,
a Number of Electors, equal to the whole Number of Senators and Representatives
to which the State may be entitled in the Congress: but no Senator or
Representative, or Person holding an Office of Trust or Profit under the United
States, shall be appointed an Elector.
The Electors shall meet in their respective States, and vote by Ballot for two
persons, of whom one at least shall not lie an Inhabitant of the same State
with themselves. And they shall make a List of all the Persons voted for, and
of the Number of Votes for each; which List they shall sign and certify, and
transmit sealed to the Seat of the Government of the United States, directed to
the President of the Senate. The President of the Senate shall, in the Presence
of the Senate and House of Representatives, open all the Certificates, and the
Votes shall then be counted. The Person having the greatest Number of Votes
shall be the President, if such Number be a Majority of the whole Number of
Electors appointed; and if there be more than one who have such Majority, and
have an equal Number of Votes, then the House of Representatives shall
immediately choose by Ballot one of them for President; and if no Person have a
Majority, then from the five highest on the List the said House shall in like
Manner choose the President. But in choosing the President, the Votes shall be
taken by States, the Representation from each State having one Vote; a quorum
for this Purpose shall consist of a Member or Members from two-thirds of the
States, and a Majority of all the States shall be necessary to a Choice. In
every Case, after the Choice of the President, the Person having the greatest
Number of Votes of the Electors shall be the Vice President. But if there
should remain two or more who have equal Votes, the Senate shall choose from
them by Ballot the Vice-President.
The Congress may determine the Time of choosing the Electors, and the Day on
which they shall give their Votes; which Day shall be the same throughout the
United States.
No person except a natural born Citizen, or a Citizen of the United States, at
the time of the Adoption of this Constitution, shall be eligible to the Office
of President; neither shall any Person be eligible to that Office who shall not
have attained to the Age of thirty-five Years, and been fourteen Years a
Resident within the United States.
In Case of the Removal of the President from Office, or of his Death,
Resignation, or Inability to discharge the Powers and Duties of the said
Office, the same shall devolve on the Vice President, and the Congress may by
Law provide for the Case of Removal, Death, Resignation or Inability, both of
the President and Vice President, declaring what Officer shall then act as
President, and such Officer shall act accordingly, until the Disability be
removed, or a President shall be elected.
The President shall, at stated Times, receive for his Services, a Compensation,
which shall neither be increased nor diminished during the Period for which he
shall have been elected, and he shall not receive within that Period any other
Emolument from the United States, or any of them.
Before he enter on the Execution of his Office, he shall take the following
Oath or Affirmation:
"I do solemnly swear (or affirm) that I will faithfully execute the Office of
President of the United States, and will to the best of my Ability, preserve,
protect and defend the Constitution of the United States."
Section 2
The President shall be Commander in Chief of the Army and Navy of the United
States, and of the Militia of the several States, when called into the actual
Service of the United States; he may require the Opinion, in writing, of the
principal Officer in each of the executive Departments, upon any subject
relating to the Duties of their respective Offices, and he shall have Power to
Grant Reprieves and Pardons for Offenses against the United States, except in
Cases of Impeachment.
He shall have Power, by and with the Advice and Consent of the Senate, to make
Treaties, provided two thirds of the Senators present concur; and he shall
nominate, and by and with the Advice and Consent of the Senate, shall appoint
Ambassadors, other public Ministers and Consuls, Judges of the supreme Court,
and all other Officers of the United States, whose Appointments are not herein
otherwise provided for, and which shall be established by Law: but the Congress
may by Law vest the Appointment of such inferior Officers, as they think
proper, in the President alone, in the Courts of Law, or in the Heads of
Departments.
The President shall have Power to fill up all Vacancies that may happen during
the Recess of the Senate, by granting Commissions which shall expire at the End
of their next Session.
Section 3
He shall from time to time give to the Congress Information of the State of the
Union, and recommend to their Consideration such Measures as he shall judge
necessary and expedient; he may, on extraordinary Occasions, convene both
Houses, or either of them, and in Case of Disagreement between them, with
Respect to the Time of Adjournment, he may adjourn them to such Time as he
shall think proper; he shall receive Ambassadors and other public Ministers; he
shall take Care that the Laws be faithfully executed, and shall Commission all
the Officers of the United States.
Section 4
The President, Vice President and all civil Officers of the United States,
shall be removed from Office on Impeachment for, and Conviction of, Treason,
Bribery, or other high Crimes and Misdemeanors.
Article 3.
Section 1
The judicial Power of the United States, shall be vested in one supreme Court,
and in such inferior Courts as the Congress may from time to time ordain and
establish. The Judges, both of the supreme and inferior Courts, shall hold
their Offices during good Behavior, and shall, at stated Times, receive for
their Services a Compensation which shall not be diminished during their
Continuance in Office.
Section 2
The judicial Power shall extend to all Cases, in Law and Equity, arising under
this Constitution, the Laws of the United States, and Treaties made, or which
shall be made, under their Authority; to all Cases affecting Ambassadors, other
public Ministers and Consuls; to all Cases of admiralty and maritime
Jurisdiction; to Controversies to which the United States shall be a Party; to
Controversies between two or more States; between a State and Citizens of
another State; between Citizens of different States; between Citizens of the
same State claiming Lands under Grants of different States, and between a
State, or the Citizens thereof, and foreign States, Citizens or Subjects.
In all Cases affecting Ambassadors, other public Ministers and Consuls, and
those in which a State shall be Party, the supreme Court shall have original
Jurisdiction. In all the other Cases before mentioned, the supreme Court shall
have appellate Jurisdiction, both as to Law and Fact, with such Exceptions, and
under such Regulations as the Congress shall make.
The Trial of all Crimes, except in Cases of Impeachment, shall be by Jury; and
such Trial shall be held in the State where the said Crimes shall have been
committed; but when not committed within any State, the Trial shall be at such
Place or Places as the Congress may by Law have directed.
Section 3
Treason against the United States, shall consist only in levying War against
them, or in adhering to their Enemies, giving them Aid and Comfort. No Person
shall be convicted of Treason unless on the Testimony of two Witnesses to the
same overt Act, or on Confession in open Court.
The Congress shall have power to declare the Punishment of Treason, but no
Attainder of Treason shall work Corruption of Blood, or Forfeiture except
during the Life of the Person attainted.
Article 4.
Section 1
Full Faith and Credit shall be given in each State to the public Acts, Records,
and judicial Proceedings of every other State. And the Congress may by general
Laws prescribe the Manner in which such Acts, Records and Proceedings shall be
proved, and the Effect thereof.
Section 2
The Citizens of each State shall be entitled to all Privileges and Immunities
of Citizens in the several States.
A Person charged in any State with Treason, Felony, or other Crime, who shall
flee from Justice, and be found in another State, shall on demand of the
executive Authority of the State from which he fled, be delivered up, to be
removed to the State having Jurisdiction of the Crime.
No Person held to Service or Labour in one State, under the Laws thereof,
escaping into another, shall, in Consequence of any Law or Regulation therein,
be discharged from such Service or Labour, But shall be delivered up on Claim
of the Party to whom such Service or Labour may be due.
Section 3
New States may be admitted by the Congress into this Union; but no new States
shall be formed or erected within the Jurisdiction of any other State; nor any
State be formed by the Junction of two or more States, or parts of States,
without the Consent of the Legislatures of the States concerned as well as of
the Congress.
The Congress shall have Power to dispose of and make all needful Rules and
Regulations respecting the Territory or other Property belonging to the United
States; and nothing in this Constitution shall be so construed as to Prejudice
any Claims of the United States, or of any particular State.
Section 4
The United States shall guarantee to every State in this Union a Republican
Form of Government, and shall protect each of them against Invasion; and on
Application of the Legislature, or of the Executive (when the Legislature
cannot be convened) against domestic Violence.
Article 5.
The Congress, whenever two thirds of both Houses shall deem it necessary, shall
propose Amendments to this Constitution, or, on the Application of the
Legislatures of two thirds of the several States, shall call a Convention for
proposing Amendments, which, in either Case, shall be valid to all Intents and
Purposes, as part of this Constitution, when ratified by the Legislatures of
three fourths of the several States, or by Conventions in three fourths
thereof, as the one or the other Mode of Ratification may be proposed by the
Congress; Provided that no Amendment which may be made prior to the Year One
thousand eight hundred and eight shall in any Manner affect the first and
fourth Clauses in the Ninth Section of the first Article; and that no State,
without its Consent, shall be deprived of its equal Suffrage in the Senate.
Article 6.
All Debts contracted and Engagements entered into, before the Adoption of this
Constitution, shall be as valid against the United States under this
Constitution, as under the Confederation.
This Constitution, and the Laws of the United States which shall be made in
Pursuance thereof; and all Treaties made, or which shall be made, under the
Authority of the United States, shall be the supreme Law of the Land; and the
Judges in every State shall be bound thereby, any Thing in the Constitution or
Laws of any State to the Contrary notwithstanding.
The Senators and Representatives before mentioned, and the Members of the
several State Legislatures, and all executive and judicial Officers, both of
the United States and of the several States, shall be bound by Oath or
Affirmation, to support this Constitution; but no religious Test shall ever be
required as a Qualification to any Office or public Trust under the United
States.
Article 7.
The Ratification of the Conventions of nine States, shall be sufficient for the
Establishment of this Constitution between the States so ratifying the Same.
Done in Convention by the Unanimous Consent of the States present the
Seventeenth Day of September in the Year of our Lord one thousand seven hundred
and Eighty seven and of the Independence of the United States of America the
Twelfth. In Witness whereof We have hereunto subscribed our Names.
George Washington - President and deputy from Virginia
New Hampshire - John Langdon, Nicholas Gilman
Massachusetts - Nathaniel Gorham, Rufus King
Connecticut - William Samuel Johnson, Roger Sherman
New York - Alexander Hamilton
New Jersey - William Livingston, David Brearley, William Paterson, Jonathan
Dayton
Pennsylvania - Benjamin Franklin, Thomas Mifflin, Robert Morris, George Clymer,
Thomas Fitzsimons, Jared Ingersoll, James Wilson, Gouvernour Morris
Delaware - George Read, Gunning Bedford Jr., John Dickinson, Richard Bassett,
Jacob Broom
Maryland - James McHenry, Daniel of St Thomas Jenifer, Daniel Carroll
Virginia - John Blair, James Madison Jr.
North Carolina - William Blount, Richard Dobbs Spaight, Hugh Williamson
South Carolina - John Rutledge, Charles Cotesworth Pinckney, Charles Pinckney,
Pierce Butler
Georgia - William Few, Abraham Baldwin
Attest: William Jackson, Secretary
Amendment 1
Congress shall make no law respecting an establishment of religion, or
prohibiting the free exercise thereof; or abridging the freedom of speech, or
of the press; or the right of the people peaceably to assemble, and to petition
the Government for a redress of grievances.
Amendment 2
A well regulated Militia, being necessary to the security of a free State, the
right of the people to keep and bear Arms, shall not be infringed.
Amendment 3
No Soldier shall, in time of peace be quartered in any house, without the
consent of the Owner, nor in time of war, but in a manner to be prescribed by
law.
Amendment 4
The right of the people to be secure in their persons, houses, papers, and
effects, against unreasonable searches and seizures, shall not be violated, and
no Warrants shall issue, but upon probable cause, supported by Oath or
affirmation, and particularly describing the place to be searched, and the
persons or things to be seized.
Amendment 5
No person shall be held to answer for a capital, or otherwise infamous crime,
unless on a presentment or indictment of a Grand Jury, except in cases arising
in the land or naval forces, or in the Militia, when in actual service in time
of War or public danger; nor shall any person be subject for the same offense
to be twice put in jeopardy of life or limb; nor shall be compelled in any
criminal case to be a witness against himself, nor be deprived of life,
liberty, or property, without due process of law; nor shall private property be
taken for public use, without just compensation.
Amendment 6
In all criminal prosecutions, the accused shall enjoy the right to a speedy and
public trial, by an impartial jury of the State and district wherein the crime
shall have been committed, which district shall have been previously
ascertained by law, and to be informed of the nature and cause of the
accusation; to be confronted with the witnesses against him; to have compulsory
process for obtaining witnesses in his favor, and to have the Assistance of
Counsel for his defence.
Amendment 7
In Suits at common law, where the value in controversy shall exceed twenty
dollars, the right of trial by jury shall be preserved, and no fact tried by a
jury, shall be otherwise re-examined in any Court of the United States, than
according to the rules of the common law.
Amendment 8
Excessive bail shall not be required, nor excessive fines imposed, nor cruel
and unusual punishments inflicted.
Amendment 9
The enumeration in the Constitution, of certain rights, shall not be construed
to deny or disparage others retained by the people.
Amendment 10
The powers not delegated to the United States by the Constitution, nor
prohibited by it to the States, are reserved to the States respectively, or to
the people.
Amendment 11
The Judicial power of the United States shall not be construed to extend to any
suit in law or equity, commenced or prosecuted against one of the United States
by Citizens of another State, or by Citizens or Subjects of any Foreign State.
Amendment 12
The Electors shall meet in their respective states, and vote by ballot for
President and Vice-President, one of whom, at least, shall not be an inhabitant
of the same state with themselves; they shall name in their ballots the person
voted for as President, and in distinct ballots the person voted for as
Vice-President, and they shall make distinct lists of all persons voted for as
President, and of all persons voted for as Vice-President and of the number of
votes for each, which lists they shall sign and certify, and transmit sealed to
the seat of the government of the United States, directed to the President of
the Senate;
The President of the Senate shall, in the presence of the Senate and House of
Representatives, open all the certificates and the votes shall then be counted;
The person having the greatest Number of votes for President, shall be the
President, if such number be a majority of the whole number of Electors
appointed; and if no person have such majority, then from the persons having
the highest numbers not exceeding three on the list of those voted for as
President, the House of Representatives shall choose immediately, by ballot,
the President. But in choosing the President, the votes shall be taken by
states, the representation from each state having one vote; a quorum for this
purpose shall consist of a member or members from two-thirds of the states, and
a majority of all the states shall be necessary to a choice. And if the House
of Representatives shall not choose a President whenever the right of choice
shall devolve upon them, before the fourth day of March next following, then
the Vice-President shall act as President, as in the case of the death or other
constitutional disability of the President.
The person having the greatest number of votes as Vice-President, shall be the
Vice-President, if such number be a majority of the whole number of Electors
appointed, and if no person have a majority, then from the two highest numbers
on the list, the Senate shall choose the Vice-President; a quorum for the
purpose shall consist of two-thirds of the whole number of Senators, and a
majority of the whole number shall be necessary to a choice. But no person
constitutionally ineligible to the office of President shall be eligible to
that of Vice-President of the United States.
Amendment 13
1. Neither slavery nor involuntary servitude, except as a punishment for crime
whereof the party shall have been duly convicted, shall exist within the United
States, or any place subject to their jurisdiction.
2. Congress shall have power to enforce this article by appropriate
legislation.
Amendment 14
1. All persons born or naturalized in the United States, and subject to the
jurisdiction thereof, are citizens of the United States and of the State
wherein they reside. No State shall make or enforce any law which shall abridge
the privileges or immunities of citizens of the United States; nor shall any
State deprive any person of life, liberty, or property, without due process of
law; nor deny to any person within its jurisdiction the equal protection of the
laws.
2. Representatives shall be apportioned among the several States according to
their respective numbers, counting the whole number of persons in each State,
excluding Indians not taxed. But when the right to vote at any election for the
choice of electors for President and Vice-President of the United States,
Representatives in Congress, the Executive and Judicial officers of a State, or
the members of the Legislature thereof, is denied to any of the male
inhabitants of such State, being twenty-one years of age, and citizens of the
United States, or in any way abridged, except for participation in rebellion,
or other crime, the basis of representation therein shall be reduced in the
proportion which the number of such male citizens shall bear to the whole
number of male citizens twenty-one years of age in such State.
3. No person shall be a Senator or Representative in Congress, or elector of
President and Vice-President, or hold any office, civil or military, under the
United States, or under any State, who, having previously taken an oath, as a
member of Congress, or as an officer of the United States, or as a member of
any State legislature, or as an executive or judicial officer of any State, to
support the Constitution of the United States, shall have engaged in
insurrection or rebellion against the same, or given aid or comfort to the
enemies thereof. But Congress may by a vote of two-thirds of each House, remove
such disability.
4. The validity of the public debt of the United States, authorized by law,
including debts incurred for payment of pensions and bounties for services in
suppressing insurrection or rebellion, shall not be questioned. But neither the
United States nor any State shall assume or pay any debt or obligation incurred
in aid of insurrection or rebellion against the United States, or any claim for
the loss or emancipation of any slave; but all such debts, obligations and
claims shall be held illegal and void.
5. The Congress shall have power to enforce, by appropriate legislation, the
provisions of this article.
Amendment 15
1. The right of citizens of the United States to vote shall not be denied or
abridged by the United States or by any State on account of race, color, or
previous condition of servitude.
2. The Congress shall have power to enforce this article by appropriate
legislation.
Amendment 16
The Congress shall have power to lay and collect taxes on incomes, from
whatever source derived, without apportionment among the several States, and
without regard to any census or enumeration.
Amendment 17
The Senate of the United States shall be composed of two Senators from each
State, elected by the people thereof, for six years; and each Senator shall
have one vote. The electors in each State shall have the qualifications
requisite for electors of the most numerous branch of the State legislatures.
When vacancies happen in the representation of any State in the Senate, the
executive authority of such State shall issue writs of election to fill such
vacancies: Provided, That the legislature of any State may empower the
executive thereof to make temporary appointments until the people fill the
vacancies by election as the legislature may direct.
This amendment shall not be so construed as to affect the election or term of
any Senator chosen before it becomes valid as part of the Constitution.
Amendment 18
1. After one year from the ratification of this article the manufacture, sale,
or transportation of intoxicating liquors within, the importation thereof into,
or the exportation thereof from the United States and all territory subject to
the jurisdiction thereof for beverage purposes is hereby prohibited.
2. The Congress and the several States shall have concurrent power to enforce
this article by appropriate legislation.
3. This article shall be inoperative unless it shall have been ratified as an
amendment to the Constitution by the legislatures of the several States, as
provided in the Constitution, within seven years from the date of the
submission hereof to the States by the Congress.
Amendment 19
The right of citizens of the United States to vote shall not be denied or
abridged by the United States or by any State on account of sex.
Congress shall have power to enforce this article by appropriate legislation.
Amendment 20
1. The terms of the President and Vice President shall end at noon on the 20th
day of January, and the terms of Senators and Representatives at noon on the 3d
day of January, of the years in which such terms would have ended if this
article had not been ratified; and the terms of their successors shall then
begin.
2. The Congress shall assemble at least once in every year, and such meeting
shall begin at noon on the 3d day of January, unless they shall by law appoint
a different day.
3. If, at the time fixed for the beginning of the term of the President, the
President elect shall have died, the Vice President elect shall become
President. If a President shall not have been chosen before the time fixed for
the beginning of his term, or if the President elect shall have failed to
qualify, then the Vice President elect shall act as President until a President
shall have qualified; and the Congress may by law provide for the case wherein
neither a President elect nor a Vice President elect shall have qualified,
declaring who shall then act as President, or the manner in which one who is to
act shall be selected, and such person shall act accordingly until a President
or Vice President shall have qualified.
4. The Congress may by law provide for the case of the death of any of the
persons from whom the House of Representatives may choose a President whenever
the right of choice shall have devolved upon them, and for the case of the
death of any of the persons from whom the Senate may choose a Vice President
whenever the right of choice shall have devolved upon them.
5. Sections 1 and 2 shall take effect on the 15th day of October following the
ratification of this article.
6. This article shall be inoperative unless it shall have been ratified as an
amendment to the Constitution by the legislatures of three-fourths of the
several States within seven years from the date of its submission.
Amendment 21
1. The eighteenth article of amendment to the Constitution of the United States
is hereby repealed.
2. The transportation or importation into any State, Territory, or possession
of the United States for delivery or use therein of intoxicating liquors, in
violation of the laws thereof, is hereby prohibited.
3. The article shall be inoperative unless it shall have been ratified as an
amendment to the Constitution by conventions in the several States, as provided
in the Constitution, within seven years from the date of the submission hereof
to the States by the Congress.
Amendment 22
1. No person shall be elected to the office of the President more than twice,
and no person who has held the office of President, or acted as President, for
more than two years of a term to which some other person was elected President
shall be elected to the office of the President more than once. But this
Article shall not apply to any person holding the office of President, when this
Article was proposed by the Congress, and shall not prevent any person who may
be holding the office of President, or acting as President, during the term
within which this Article becomes operative from holding the office of
President or acting as President during the remainder of such term.
2. This article shall be inoperative unless it shall have been ratified as an
amendment to the Constitution by the legislatures of three-fourths of the
several States within seven years from the date of its submission to the States
by the Congress.
Amendment 23
1. The District constituting the seat of Government of the United States shall
appoint in such manner as the Congress may direct: A number of electors of
President and Vice President equal to the whole number of Senators and
Representatives in Congress to which the District would be entitled if it were
a State, but in no event more than the least populous State; they shall be in
addition to those appointed by the States, but they shall be considered, for
the purposes of the election of President and Vice President, to be electors
appointed by a State; and they shall meet in the District and perform such
duties as provided by the twelfth article of amendment.
2. The Congress shall have power to enforce this article by appropriate
legislation.
Amendment 24
1. The right of citizens of the United States to vote in any primary or other
election for President or Vice President, for electors for President or
Vice President, or for Senator or Representative in Congress, shall not be
denied or abridged by the United States or any State by reason of failure to
pay any poll tax or other tax.
2. The Congress shall have power to enforce this article by appropriate
legislation.
Amendment 25
1. In case of the removal of the President from office or of his death or
resignation, the Vice President shall become President.
2. Whenever there is a vacancy in the office of the Vice President, the
President shall nominate a Vice President who shall take office upon
confirmation by a majority vote of both Houses of Congress.
3. Whenever the President transmits to the President pro tempore of the Senate
and the Speaker of the House of Representatives his written declaration that he
is unable to discharge the powers and duties of his office, and until he
transmits to them a written declaration to the contrary, such powers and duties
shall be discharged by the Vice President as Acting President.
4. Whenever the Vice President and a majority of either the principal officers
of the executive departments or of such other body as Congress may by law
provide, transmit to the President pro tempore of the Senate and the Speaker of
the House of Representatives their written declaration that the President is
unable to discharge the powers and duties of his office, the Vice President
shall immediately assume the powers and duties of the office as Acting
President.
Thereafter, when the President transmits to the President pro tempore of the
Senate and the Speaker of the House of Representatives his written declaration
that no inability exists, he shall resume the powers and duties of his office
unless the Vice President and a majority of either the principal officers of
the executive department or of such other body as Congress may by law provide,
transmit within four days to the President pro tempore of the Senate and the
Speaker of the House of Representatives their written declaration that the
President is unable to discharge the powers and duties of his office. Thereupon
Congress shall decide the issue, assembling within forty eight hours for that
purpose if not in session. If the Congress, within twenty one days after
receipt of the latter written declaration, or, if Congress is not in session,
within twenty one days after Congress is required to assemble, determines by
two thirds vote of both Houses that the President is unable to discharge the
powers and duties of his office, the Vice President shall continue to discharge
the same as Acting President; otherwise, the President shall resume the powers
and duties of his office.
Amendment 26
1. The right of citizens of the United States, who are eighteen years of age or
older, to vote shall not be denied or abridged by the United States or by any
State on account of age.
2. The Congress shall have power to enforce this article by appropriate
legislation.
Amendment 27
No law, varying the compensation for the services of the Senators and
Representatives, shall take effect, until an election of Representatives shall
have intervened.

View File

@ -26,11 +26,11 @@ 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.Key;
import java.security.KeyFactory; import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import javax.crypto.Cipher;
import javax.inject.Singleton; import javax.inject.Singleton;
import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.Digest;
@ -50,12 +50,12 @@ import org.jclouds.io.payloads.ByteArrayPayload;
*/ */
@Singleton @Singleton
public class BouncyCastleEncryptionService extends BaseEncryptionService { public class BouncyCastleEncryptionService extends BaseEncryptionService {
public BouncyCastleEncryptionService(KeyFactory rsaKeyFactory) { public BouncyCastleEncryptionService(KeyFactory rsaKeyFactory, CertificateFactory certFactory) {
super(rsaKeyFactory); super(rsaKeyFactory, certFactory);
} }
public BouncyCastleEncryptionService() throws NoSuchAlgorithmException { public BouncyCastleEncryptionService() throws NoSuchAlgorithmException, CertificateException {
super(KeyFactory.getInstance("RSA")); this(KeyFactory.getInstance("RSA"), CertificateFactory.getInstance("X.509"));
} }
@Override @Override
@ -189,17 +189,4 @@ public class BouncyCastleEncryptionService extends BaseEncryptionService {
return resBuf; return resBuf;
} }
@Override
public byte[] rsaSign(String toSign, Key key) {
// TODO convert this to BC code
try {
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, key);
return cipher.doFinal(toSign.getBytes());
} catch (Exception e) {
propagate(e);
return null;
}
}
} }

View File

@ -25,6 +25,7 @@ import java.io.IOException;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.URI; import java.net.URI;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.util.Date; import java.util.Date;
import javax.ws.rs.HttpMethod; import javax.ws.rs.HttpMethod;
@ -60,6 +61,8 @@ public class ConvertToGaeRequestTest {
encryptionService = new JCEEncryptionService(); encryptionService = new JCEEncryptionService();
} catch (NoSuchAlgorithmException e) { } catch (NoSuchAlgorithmException e) {
Throwables.propagate(e); Throwables.propagate(e);
} catch (CertificateException e) {
Throwables.propagate(e);
} }
} }
@ -152,7 +155,7 @@ public class ConvertToGaeRequestTest {
builder.append(header.getName()).append(": ").append(header.getValue()).append("\n"); builder.append(header.getName()).append(": ").append(header.getValue()).append("\n");
} }
assertEquals(builder.toString(), assertEquals(builder.toString(),
"User-Agent: jclouds/1.0 urlfetch/1.3.5\nContent-MD5: AQIDBA==\nContent-Type: text/plain\nContent-Length: 5\n"); "User-Agent: jclouds/1.0 urlfetch/1.3.5\nContent-MD5: AQIDBA==\nContent-Type: text/plain\nContent-Length: 5\n");
assertEquals(new String(gaeRequest.getPayload()), "hoot!"); assertEquals(new String(gaeRequest.getPayload()), "hoot!");
} }
} }

View File

@ -27,6 +27,7 @@ import java.io.IOException;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.URI; import java.net.URI;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -59,6 +60,8 @@ public class ConvertToJcloudsResponseTest {
encryptionService = new JCEEncryptionService(); encryptionService = new JCEEncryptionService();
} catch (NoSuchAlgorithmException e) { } catch (NoSuchAlgorithmException e) {
Throwables.propagate(e); Throwables.propagate(e);
} catch (CertificateException e) {
Throwables.propagate(e);
} }
} }

View File

@ -38,14 +38,12 @@ import org.jclouds.chef.domain.Organization;
import org.jclouds.chef.domain.User; import org.jclouds.chef.domain.User;
import org.jclouds.chef.filters.SignedHeaderAuth; import org.jclouds.chef.filters.SignedHeaderAuth;
import org.jclouds.chef.functions.OrganizationName; import org.jclouds.chef.functions.OrganizationName;
import org.jclouds.chef.functions.ParseKeyFromJson;
import org.jclouds.chef.functions.Username; import org.jclouds.chef.functions.Username;
import org.jclouds.rest.annotations.BinderParam; import org.jclouds.rest.annotations.BinderParam;
import org.jclouds.rest.annotations.Delegate; import org.jclouds.rest.annotations.Delegate;
import org.jclouds.rest.annotations.ExceptionParser; import org.jclouds.rest.annotations.ExceptionParser;
import org.jclouds.rest.annotations.ParamParser; import org.jclouds.rest.annotations.ParamParser;
import org.jclouds.rest.annotations.RequestFilters; import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.rest.annotations.ResponseParser;
import org.jclouds.rest.binders.BindToJsonPayload; import org.jclouds.rest.binders.BindToJsonPayload;
import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404; import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
@ -74,9 +72,7 @@ public interface OpscodePlatformAsyncClient {
*/ */
@POST @POST
@Path("/users") @Path("/users")
@ResponseParser(ParseKeyFromJson.class) ListenableFuture<User> createUser(@BinderParam(BindToJsonPayload.class) User user);
ListenableFuture<String> createUser(
@BinderParam(BindToJsonPayload.class) User user);
/** /**
* @see ChefClient#updateUser * @see ChefClient#updateUser
@ -85,7 +81,7 @@ public interface OpscodePlatformAsyncClient {
@Path("/users/{username}") @Path("/users/{username}")
@Consumes(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON)
ListenableFuture<User> updateUser( ListenableFuture<User> updateUser(
@PathParam("username") @ParamParser(Username.class) @BinderParam(BindToJsonPayload.class) User user); @PathParam("username") @ParamParser(Username.class) @BinderParam(BindToJsonPayload.class) User user);
/** /**
* @see ChefClient#getUser * @see ChefClient#getUser
@ -110,9 +106,7 @@ public interface OpscodePlatformAsyncClient {
*/ */
@POST @POST
@Path("/organizations") @Path("/organizations")
@ResponseParser(ParseKeyFromJson.class) ListenableFuture<Organization> createOrg(@BinderParam(BindToJsonPayload.class) Organization org);
ListenableFuture<String> createOrg(
@BinderParam(BindToJsonPayload.class) Organization org);
/** /**
* @see ChefClient#updateOrg * @see ChefClient#updateOrg
@ -121,7 +115,7 @@ public interface OpscodePlatformAsyncClient {
@Path("/organizations/{orgname}") @Path("/organizations/{orgname}")
@Consumes(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON)
ListenableFuture<Organization> updateOrg( ListenableFuture<Organization> updateOrg(
@PathParam("orgname") @ParamParser(OrganizationName.class) @BinderParam(BindToJsonPayload.class) Organization org); @PathParam("orgname") @ParamParser(OrganizationName.class) @BinderParam(BindToJsonPayload.class) Organization org);
/** /**
* @see ChefClient#getOrg * @see ChefClient#getOrg

View File

@ -64,7 +64,7 @@ public interface OpscodePlatformClient {
* <p/> * <p/>
* "403 Forbidden" if the caller is not authorized to create a user. * "403 Forbidden" if the caller is not authorized to create a user.
*/ */
String createUser(User user); User createUser(User user);
/** /**
* updates an existing user. Note: you must have update rights on the user. * updates an existing user. Note: you must have update rights on the user.
@ -109,7 +109,7 @@ public interface OpscodePlatformClient {
* <p/> * <p/>
* "403 Forbidden" if the caller is not authorized to create a organization. * "403 Forbidden" if the caller is not authorized to create a organization.
*/ */
String createOrg(Organization organization); Organization createOrg(Organization organization);
/** /**
* updates an existing organization. Note: you must have update rights on the organization. * updates an existing organization. Note: you must have update rights on the organization.

View File

@ -23,9 +23,9 @@
*/ */
package org.jclouds.opscodeplatform; package org.jclouds.opscodeplatform;
import static org.jclouds.concurrent.ConcurrentUtils.sameThreadExecutor;
import static org.easymock.classextension.EasyMock.createMock; import static org.easymock.classextension.EasyMock.createMock;
import static org.easymock.classextension.EasyMock.replay; import static org.easymock.classextension.EasyMock.replay;
import static org.jclouds.concurrent.ConcurrentUtils.sameThreadExecutor;
import static org.jclouds.rest.RestContextFactory.createContextBuilder; import static org.jclouds.rest.RestContextFactory.createContextBuilder;
import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertEquals;
@ -38,7 +38,6 @@ import org.jclouds.chef.domain.Organization;
import org.jclouds.chef.domain.User; import org.jclouds.chef.domain.User;
import org.jclouds.chef.filters.SignedHeaderAuth; import org.jclouds.chef.filters.SignedHeaderAuth;
import org.jclouds.chef.filters.SignedHeaderAuthTest; import org.jclouds.chef.filters.SignedHeaderAuthTest;
import org.jclouds.chef.functions.ParseKeyFromJson;
import org.jclouds.concurrent.config.ConfiguresExecutorService; import org.jclouds.concurrent.config.ConfiguresExecutorService;
import org.jclouds.concurrent.config.ExecutorServiceModule; import org.jclouds.concurrent.config.ExecutorServiceModule;
import org.jclouds.date.TimeStamp; import org.jclouds.date.TimeStamp;
@ -75,12 +74,12 @@ import com.google.inject.TypeLiteral;
public class OpscodePlatformAsyncClientTest extends RestClientTest<OpscodePlatformAsyncClient> { public class OpscodePlatformAsyncClientTest extends RestClientTest<OpscodePlatformAsyncClient> {
public void testDelegatedOpscodePlatformCallsResolveProperly() throws SecurityException, NoSuchMethodException, public void testDelegatedOpscodePlatformCallsResolveProperly() throws SecurityException, NoSuchMethodException,
InterruptedException, ExecutionException { InterruptedException, ExecutionException {
final TransformingHttpCommandExecutorService httpExecutor = createMock(TransformingHttpCommandExecutorService.class); final TransformingHttpCommandExecutorService httpExecutor = createMock(TransformingHttpCommandExecutorService.class);
Injector injector = createContextBuilder(createContextSpec(), Injector injector = createContextBuilder(createContextSpec(),
ImmutableSet.of(new HttpExecutorModule(httpExecutor), new NullLoggingModule(), createModule())) ImmutableSet.of(new HttpExecutorModule(httpExecutor), new NullLoggingModule(), createModule()))
.buildInjector(); .buildInjector();
replay(httpExecutor); replay(httpExecutor);
@ -91,7 +90,7 @@ public class OpscodePlatformAsyncClientTest extends RestClientTest<OpscodePlatfo
assert false : "shouldn't have connected as this url should be dummy"; assert false : "shouldn't have connected as this url should be dummy";
} catch (AssertionError e) { } catch (AssertionError e) {
assert e.getMessage().indexOf("[request=GET https://api.opscode.com/organizations/goo/clients HTTP/1.1]") != -1 : e assert e.getMessage().indexOf("[request=GET https://api.opscode.com/organizations/goo/clients HTTP/1.1]") != -1 : e
.getMessage(); .getMessage();
} }
} }
@ -99,7 +98,7 @@ public class OpscodePlatformAsyncClientTest extends RestClientTest<OpscodePlatfo
public void testCreateUser() throws SecurityException, NoSuchMethodException, IOException { public void testCreateUser() throws SecurityException, NoSuchMethodException, IOException {
Method method = OpscodePlatformAsyncClient.class.getMethod("createUser", User.class); Method method = OpscodePlatformAsyncClient.class.getMethod("createUser", User.class);
GeneratedHttpRequest<OpscodePlatformAsyncClient> httpRequest = processor GeneratedHttpRequest<OpscodePlatformAsyncClient> httpRequest = processor
.createRequest(method, new User("myuser")); .createRequest(method, new User("myuser"));
assertRequestLineEquals(httpRequest, "POST https://api.opscode.com/users HTTP/1.1"); assertRequestLineEquals(httpRequest, "POST https://api.opscode.com/users HTTP/1.1");
assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\n"); assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\n");
@ -111,18 +110,21 @@ public class OpscodePlatformAsyncClientTest extends RestClientTest<OpscodePlatfo
assertRequestLineEquals(httpRequest, "POST https://api.opscode.com/users HTTP/1.1"); assertRequestLineEquals(httpRequest, "POST https://api.opscode.com/users HTTP/1.1");
assertNonPayloadHeadersEqual(httpRequest, new StringBuilder("Accept: application/json").append("\n").append( assertNonPayloadHeadersEqual(httpRequest, new StringBuilder("Accept: application/json").append("\n").append(
"X-Ops-Authorization-1: kfrkDpfgNU26k70R1vl1bEWk0Q0f9Fs/3kxOX7gHd7iNoJq03u7RrcrAOSgL").append("\n").append( "X-Ops-Authorization-1: kfrkDpfgNU26k70R1vl1bEWk0Q0f9Fs/3kxOX7gHd7iNoJq03u7RrcrAOSgL").append("\n")
"X-Ops-Authorization-2: ETj5JNeCk18BmFkHMAbCA9hXVo1T4rlHCpbuzAzFlFxUGAT4wj8UoO7V886X").append("\n").append( .append("X-Ops-Authorization-2: ETj5JNeCk18BmFkHMAbCA9hXVo1T4rlHCpbuzAzFlFxUGAT4wj8UoO7V886X").append(
"X-Ops-Authorization-3: Kf8DvihP6ElthCNuu1xuhN0B4GEmWC9+ut7UMLe0L2T34VzkbCtuInGbf42/").append("\n").append( "\n").append(
"X-Ops-Authorization-4: G7iu94/xFOT1gN9cex4pNyTnRCHzob4JVU1usxt/2g5grN2SyYwRS5+4MNLN").append("\n").append( "X-Ops-Authorization-3: Kf8DvihP6ElthCNuu1xuhN0B4GEmWC9+ut7UMLe0L2T34VzkbCtuInGbf42/").append(
"X-Ops-Authorization-5: WY/iLUPb/9dwtiIQsnUOXqDrs28zNswZulQW4AzYRd7MczJVKU4y4+4XRcB4").append("\n").append( "\n").append(
"X-Ops-Authorization-6: 2+BFLT5o6P6G0D+eCu3zSuaqEJRucPJPaDGWdKIMag==").append("\n").append( "X-Ops-Authorization-4: G7iu94/xFOT1gN9cex4pNyTnRCHzob4JVU1usxt/2g5grN2SyYwRS5+4MNLN").append(
"X-Ops-Content-Hash: yLHOxvgIEtNw5UrZDxslOeMw1gw=").append("\n").append("X-Ops-Sign: version=1.0").append( "\n").append(
"\n").append("X-Ops-Timestamp: timestamp").append("\n").append("X-Ops-Userid: user").append("\n") "X-Ops-Authorization-5: WY/iLUPb/9dwtiIQsnUOXqDrs28zNswZulQW4AzYRd7MczJVKU4y4+4XRcB4").append(
.toString()); "\n").append("X-Ops-Authorization-6: 2+BFLT5o6P6G0D+eCu3zSuaqEJRucPJPaDGWdKIMag==")
.append("\n").append("X-Ops-Content-Hash: yLHOxvgIEtNw5UrZDxslOeMw1gw=").append("\n").append(
"X-Ops-Sign: version=1.0").append("\n").append("X-Ops-Timestamp: timestamp").append("\n")
.append("X-Ops-Userid: user").append("\n").toString());
assertPayloadEquals(httpRequest, "{\"username\":\"myuser\"}", "application/json", false); assertPayloadEquals(httpRequest, "{\"username\":\"myuser\"}", "application/json", false);
assertResponseParserClassEquals(method, httpRequest, ParseKeyFromJson.class); assertResponseParserClassEquals(method, httpRequest, ParseJson.class);
assertSaxResponseParserClassEquals(method, null); assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, null); assertExceptionParserClassEquals(method, null);
@ -133,7 +135,7 @@ public class OpscodePlatformAsyncClientTest extends RestClientTest<OpscodePlatfo
public void testUpdateUser() throws SecurityException, NoSuchMethodException, IOException { public void testUpdateUser() throws SecurityException, NoSuchMethodException, IOException {
Method method = OpscodePlatformAsyncClient.class.getMethod("updateUser", User.class); Method method = OpscodePlatformAsyncClient.class.getMethod("updateUser", User.class);
GeneratedHttpRequest<OpscodePlatformAsyncClient> httpRequest = processor GeneratedHttpRequest<OpscodePlatformAsyncClient> httpRequest = processor
.createRequest(method, new User("myuser")); .createRequest(method, new User("myuser"));
assertRequestLineEquals(httpRequest, "PUT https://api.opscode.com/users/myuser HTTP/1.1"); assertRequestLineEquals(httpRequest, "PUT https://api.opscode.com/users/myuser HTTP/1.1");
assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\n"); assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\n");
@ -182,13 +184,13 @@ public class OpscodePlatformAsyncClientTest extends RestClientTest<OpscodePlatfo
public void testCreateOrg() throws SecurityException, NoSuchMethodException, IOException { public void testCreateOrg() throws SecurityException, NoSuchMethodException, IOException {
Method method = OpscodePlatformAsyncClient.class.getMethod("createOrg", Organization.class); Method method = OpscodePlatformAsyncClient.class.getMethod("createOrg", Organization.class);
GeneratedHttpRequest<OpscodePlatformAsyncClient> httpRequest = processor.createRequest(method, new Organization( GeneratedHttpRequest<OpscodePlatformAsyncClient> httpRequest = processor.createRequest(method, new Organization(
"myorganization")); "myorganization"));
assertRequestLineEquals(httpRequest, "POST https://api.opscode.com/organizations HTTP/1.1"); assertRequestLineEquals(httpRequest, "POST https://api.opscode.com/organizations HTTP/1.1");
assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\n"); assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\n");
assertPayloadEquals(httpRequest, "{\"name\":\"myorganization\"}", "application/json", false); assertPayloadEquals(httpRequest, "{\"name\":\"myorganization\"}", "application/json", false);
assertResponseParserClassEquals(method, httpRequest, ParseKeyFromJson.class); assertResponseParserClassEquals(method, httpRequest, ParseJson.class);
assertSaxResponseParserClassEquals(method, null); assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, null); assertExceptionParserClassEquals(method, null);
@ -199,7 +201,7 @@ public class OpscodePlatformAsyncClientTest extends RestClientTest<OpscodePlatfo
public void testUpdateOrg() throws SecurityException, NoSuchMethodException, IOException { public void testUpdateOrg() throws SecurityException, NoSuchMethodException, IOException {
Method method = OpscodePlatformAsyncClient.class.getMethod("updateOrg", Organization.class); Method method = OpscodePlatformAsyncClient.class.getMethod("updateOrg", Organization.class);
GeneratedHttpRequest<OpscodePlatformAsyncClient> httpRequest = processor.createRequest(method, new Organization( GeneratedHttpRequest<OpscodePlatformAsyncClient> httpRequest = processor.createRequest(method, new Organization(
"myorganization")); "myorganization"));
assertRequestLineEquals(httpRequest, "PUT https://api.opscode.com/organizations/myorganization HTTP/1.1"); assertRequestLineEquals(httpRequest, "PUT https://api.opscode.com/organizations/myorganization HTTP/1.1");
assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\n"); assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\n");
@ -291,6 +293,6 @@ public class OpscodePlatformAsyncClientTest extends RestClientTest<OpscodePlatfo
@Override @Override
public ContextSpec<OpscodePlatformClient, OpscodePlatformAsyncClient> createContextSpec() { public ContextSpec<OpscodePlatformClient, OpscodePlatformAsyncClient> createContextSpec() {
return new RestContextFactory().createContextSpec("opscodeplatform", "user", SignedHeaderAuthTest.PRIVATE_KEY, return new RestContextFactory().createContextSpec("opscodeplatform", "user", SignedHeaderAuthTest.PRIVATE_KEY,
new Properties()); new Properties());
} }
} }

View File

@ -67,12 +67,11 @@ public class OpscodePlatformClientLiveTest {
String keyfile = System.getProperty("jclouds.test.credential"); String keyfile = System.getProperty("jclouds.test.credential");
if (keyfile == null || keyfile.equals("")) if (keyfile == null || keyfile.equals(""))
keyfile = "/etc/chef/validation.pem"; keyfile = "/etc/chef/validation.pem";
validatorConnection = createConnection(orgname + "-validator", Files.toString(new File( validatorConnection = createConnection(orgname + "-validator", Files.toString(new File(keyfile), Charsets.UTF_8));
keyfile), Charsets.UTF_8));
} }
private RestContext<OpscodePlatformClient, OpscodePlatformAsyncClient> createConnection( private RestContext<OpscodePlatformClient, OpscodePlatformAsyncClient> createConnection(String identity, String key)
String identity, String key) throws IOException { throws IOException {
Properties props = new Properties(); Properties props = new Properties();
return new RestContextFactory().createContext("opscodeplatform", identity, key, ImmutableSet return new RestContextFactory().createContext("opscodeplatform", identity, key, ImmutableSet
.<Module> of(new Log4JLoggingModule()), props); .<Module> of(new Log4JLoggingModule()), props);
@ -88,7 +87,8 @@ public class OpscodePlatformClientLiveTest {
@Test(dependsOnMethods = "testListClientsInOrg") @Test(dependsOnMethods = "testListClientsInOrg")
public void testCreateClientInOrg() throws Exception { public void testCreateClientInOrg() throws Exception {
validatorConnection.getApi().getChefClientForOrg(orgname).deleteClient(PREFIX); validatorConnection.getApi().getChefClientForOrg(orgname).deleteClient(PREFIX);
clientKey = validatorConnection.getApi().getChefClientForOrg(orgname).createClient(PREFIX); clientKey = validatorConnection.utils().encryption().toPem(
validatorConnection.getApi().getChefClientForOrg(orgname).createClient(PREFIX).getPrivateKey());
assertNotNull(clientKey); assertNotNull(clientKey);
System.out.println(clientKey); System.out.println(clientKey);
clientConnection = createConnection(PREFIX, clientKey); clientConnection = createConnection(PREFIX, clientKey);
@ -97,8 +97,8 @@ public class OpscodePlatformClientLiveTest {
@Test(dependsOnMethods = "testCreateClientInOrg") @Test(dependsOnMethods = "testCreateClientInOrg")
public void testGenerateKeyForClientInOrg() throws Exception { public void testGenerateKeyForClientInOrg() throws Exception {
clientKey = validatorConnection.getApi().getChefClientForOrg(orgname).generateKeyForClient( clientKey = validatorConnection.utils().encryption().toPem(
PREFIX); validatorConnection.getApi().getChefClientForOrg(orgname).createClient(PREFIX).getPrivateKey());
assertNotNull(clientKey); assertNotNull(clientKey);
clientConnection.close(); clientConnection.close();
clientConnection = createConnection(PREFIX, clientKey); clientConnection = createConnection(PREFIX, clientKey);

View File

@ -27,7 +27,6 @@ import static org.testng.Assert.fail;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.IOException; import java.io.IOException;
import java.net.URI; import java.net.URI;
import java.security.NoSuchAlgorithmException;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
@ -36,8 +35,6 @@ import java.util.concurrent.TimeoutException;
import org.jclouds.blobstore.ContainerNotFoundException; import org.jclouds.blobstore.ContainerNotFoundException;
import org.jclouds.blobstore.domain.PageSet; import org.jclouds.blobstore.domain.PageSet;
import org.jclouds.blobstore.integration.internal.BaseBlobStoreIntegrationTest; import org.jclouds.blobstore.integration.internal.BaseBlobStoreIntegrationTest;
import org.jclouds.encryption.EncryptionService;
import org.jclouds.encryption.internal.JCEEncryptionService;
import org.jclouds.http.HttpResponseException; import org.jclouds.http.HttpResponseException;
import org.jclouds.http.options.GetOptions; import org.jclouds.http.options.GetOptions;
import org.jclouds.rackspace.cloudfiles.domain.AccountMetadata; import org.jclouds.rackspace.cloudfiles.domain.AccountMetadata;
@ -52,7 +49,6 @@ import org.jclouds.util.Utils;
import org.testng.annotations.Test; import org.testng.annotations.Test;
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.Maps; import com.google.common.collect.Maps;
@ -64,15 +60,6 @@ import com.google.common.collect.Maps;
@Test(groups = "live", testName = "cloudfiles.CloudFilesClientLiveTest") @Test(groups = "live", testName = "cloudfiles.CloudFilesClientLiveTest")
public class CloudFilesClientLiveTest extends BaseBlobStoreIntegrationTest { public class CloudFilesClientLiveTest extends BaseBlobStoreIntegrationTest {
protected volatile static EncryptionService encryptionService;
static {
try {
encryptionService = new JCEEncryptionService();
} catch (NoSuchAlgorithmException e) {
Throwables.propagate(e);
}
}
public CloudFilesClient getApi() { public CloudFilesClient getApi() {
return (CloudFilesClient) context.getProviderSpecificContext().getApi(); return (CloudFilesClient) context.getProviderSpecificContext().getApi();
} }
@ -116,7 +103,7 @@ public class CloudFilesClientLiveTest extends BaseBlobStoreIntegrationTest {
try { try {
cdnMetadata = getApi().getCDNMetadata(containerNameWithoutCDN); cdnMetadata = getApi().getCDNMetadata(containerNameWithoutCDN);
assert cdnMetadata == null || !cdnMetadata.isCDNEnabled() : containerNameWithoutCDN assert cdnMetadata == null || !cdnMetadata.isCDNEnabled() : containerNameWithoutCDN
+ " should not have metadata"; + " should not have metadata";
} catch (ContainerNotFoundException e) { } catch (ContainerNotFoundException e) {
} catch (HttpResponseException e) { } catch (HttpResponseException e) {
} }
@ -144,8 +131,8 @@ public class CloudFilesClientLiveTest extends BaseBlobStoreIntegrationTest {
})); }));
cdnMetadataList = getApi().listCDNContainers( cdnMetadataList = getApi().listCDNContainers(
ListCdnContainerOptions.Builder.afterMarker( ListCdnContainerOptions.Builder.afterMarker(
containerNameWithCDN.substring(0, containerNameWithCDN.length() - 1)).maxResults(1)); containerNameWithCDN.substring(0, containerNameWithCDN.length() - 1)).maxResults(1));
assertEquals(cdnMetadataList.size(), 1); assertEquals(cdnMetadataList.size(), 1);
// Enable CDN with PUT for the same container, this time with a custom // Enable CDN with PUT for the same container, this time with a custom
@ -196,7 +183,7 @@ public class CloudFilesClientLiveTest extends BaseBlobStoreIntegrationTest {
// Create test containers // Create test containers
String[] containerNames = new String[] { containerPrefix + ".testListOwnedContainers1", String[] containerNames = new String[] { containerPrefix + ".testListOwnedContainers1",
containerPrefix + ".testListOwnedContainers2" }; containerPrefix + ".testListOwnedContainers2" };
assertTrue(getApi().createContainer(containerNames[0])); assertTrue(getApi().createContainer(containerNames[0]));
assertTrue(getApi().createContainer(containerNames[1])); assertTrue(getApi().createContainer(containerNames[1]));
@ -208,8 +195,8 @@ public class CloudFilesClientLiveTest extends BaseBlobStoreIntegrationTest {
// Test listing with options // Test listing with options
response = getApi().listContainers( response = getApi().listContainers(
ListContainerOptions.Builder.afterMarker(containerNames[0].substring(0, containerNames[0].length() - 1)) ListContainerOptions.Builder.afterMarker(
.maxResults(1)); containerNames[0].substring(0, containerNames[0].length() - 1)).maxResults(1));
assertEquals(response.size(), 1); assertEquals(response.size(), 1);
assertEquals(Iterables.get(response, 0).getName(), containerNames[0]); assertEquals(Iterables.get(response, 0).getName(), containerNames[0]);
@ -259,8 +246,8 @@ public class CloudFilesClientLiveTest extends BaseBlobStoreIntegrationTest {
// List only the container just created, using a marker with the // List only the container just created, using a marker with the
// container name less 1 char // container name less 1 char
Set<ContainerMetadata> response = getApi().listContainers( Set<ContainerMetadata> response = getApi().listContainers(
ListContainerOptions.Builder.afterMarker(containerName1.substring(0, containerName1.length() - 1)) ListContainerOptions.Builder.afterMarker(containerName1.substring(0, containerName1.length() - 1))
.maxResults(1)); .maxResults(1));
assertNotNull(response); assertNotNull(response);
assertEquals(response.size(), 1); assertEquals(response.size(), 1);
assertEquals(Iterables.get(response, 0).getName(), containerName + ".hello"); assertEquals(Iterables.get(response, 0).getName(), containerName + ".hello");
@ -316,7 +303,8 @@ public class CloudFilesClientLiveTest extends BaseBlobStoreIntegrationTest {
byte[] md5 = object.getPayload().getContentMD5(); byte[] md5 = object.getPayload().getContentMD5();
String newEtag = getApi().putObject(containerName, object); String newEtag = getApi().putObject(containerName, object);
assert newEtag != null; assert newEtag != null;
assertEquals(encryptionService.hex(md5), encryptionService.hex(object.getPayload().getContentMD5())); assertEquals(context.utils().encryption().hex(md5), context.utils().encryption().hex(
object.getPayload().getContentMD5()));
// Test HEAD of missing object // Test HEAD of missing object
assert getApi().getObjectInfo(containerName, "non-existent-object") == null; assert getApi().getObjectInfo(containerName, "non-existent-object") == null;
@ -332,8 +320,8 @@ public class CloudFilesClientLiveTest extends BaseBlobStoreIntegrationTest {
// 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.hex(md5), encryptionService.hex(metadata.getHash())); assertEquals(context.utils().encryption().hex(md5), context.utils().encryption().hex(metadata.getHash()));
assertEquals(metadata.getHash(), encryptionService.fromHex(newEtag)); assertEquals(metadata.getHash(), context.utils().encryption().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");
@ -352,8 +340,9 @@ public class CloudFilesClientLiveTest extends BaseBlobStoreIntegrationTest {
// object.getMetadata().getName()); // object.getMetadata().getName());
assertEquals(getBlob.getInfo().getBytes(), new Long(data.length())); assertEquals(getBlob.getInfo().getBytes(), new Long(data.length()));
assertEquals(getBlob.getInfo().getContentType(), "text/plain"); assertEquals(getBlob.getInfo().getContentType(), "text/plain");
assertEquals(encryptionService.hex(md5), encryptionService.hex(getBlob.getInfo().getHash())); assertEquals(context.utils().encryption().hex(md5), context.utils().encryption().hex(
assertEquals(encryptionService.fromHex(newEtag), getBlob.getInfo().getHash()); getBlob.getInfo().getHash()));
assertEquals(context.utils().encryption().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");
@ -362,7 +351,7 @@ public class CloudFilesClientLiveTest extends BaseBlobStoreIntegrationTest {
// transit) // transit)
String correctEtag = newEtag; String correctEtag = newEtag;
String incorrectEtag = "0" + correctEtag.substring(1); String incorrectEtag = "0" + correctEtag.substring(1);
object.getInfo().setHash(encryptionService.fromHex(incorrectEtag)); object.getInfo().setHash(context.utils().encryption().fromHex(incorrectEtag));
try { try {
getApi().putObject(containerName, object); getApi().putObject(containerName, object);
} catch (HttpResponseException e) { } catch (HttpResponseException e) {
@ -375,21 +364,23 @@ 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.hex(md5), encryptionService.hex(getBlob.getInfo().getHash())); assertEquals(context.utils().encryption().hex(md5), context.utils().encryption().hex(
getBlob.getInfo().getHash()));
// Test GET with options // Test GET with options
// Non-matching ETag // Non-matching ETag
try { try {
getApi() getApi()
.getObject(containerName, object.getInfo().getName(), GetOptions.Builder.ifETagDoesntMatch(newEtag)); .getObject(containerName, object.getInfo().getName(),
GetOptions.Builder.ifETagDoesntMatch(newEtag));
} catch (HttpResponseException e) { } catch (HttpResponseException e) {
assertEquals(e.getResponse().getStatusCode(), 304); assertEquals(e.getResponse().getStatusCode(), 304);
} }
// 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.fromHex(newEtag)); assertEquals(getBlob.getInfo().getHash(), context.utils().encryption().fromHex(newEtag));
getBlob = getApi().getObject(containerName, object.getInfo().getName(), GetOptions.Builder.startAt(8)); getBlob = getApi().getObject(containerName, object.getInfo().getName(), GetOptions.Builder.startAt(8));
assertEquals(Utils.toStringAndClose(getBlob.getPayload().getInput()), data.substring(8)); assertEquals(Utils.toStringAndClose(getBlob.getPayload().getInput()), data.substring(8));