Issue 191: updated javadocs and annotations on chef stuff

This commit is contained in:
Adrian Cole 2010-06-16 18:34:59 -04:00
parent 3631c9c365
commit 0fca2cba0c
7 changed files with 659 additions and 248 deletions

View File

@ -49,6 +49,7 @@ import org.jclouds.rest.annotations.PartParam;
import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.rest.annotations.ResponseParser;
import org.jclouds.rest.functions.ReturnFalseOnNotFoundOr404;
import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
import org.jclouds.rest.functions.ReturnVoidOnNotFoundOr404;
import com.google.common.util.concurrent.ListenableFuture;
@ -77,8 +78,9 @@ public interface ChefAsyncClient {
* @see ChefClient#createCookbook(String,File)
*/
@POST
@Path("name")
ListenableFuture<Void> createCookbook(@FormParam("name") String cookbookName,
@Path("cookbooks")
ListenableFuture<Void> createCookbook(
@FormParam("name") String cookbookName,
@PartParam(name = "file", contentType = MediaType.APPLICATION_OCTET_STREAM) File content);
/**
@ -114,16 +116,17 @@ public interface ChefAsyncClient {
@DELETE
@Path("cookbooks/{cookbookname}")
@ExceptionParser(ReturnVoidOnNotFoundOr404.class)
ListenableFuture<Void> deleteCookbook(@PathParam("cookbookname") String cookbookName);
ListenableFuture<Void> deleteCookbook(
@PathParam("cookbookname") String cookbookName);
/**
* @see ChefCookbook#getCookbook
*/
@GET
@Path("cookbooks/{cookbookname}")
ListenableFuture<String> getCookbook(@PathParam("cookbookname") String cookbookName);
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
ListenableFuture<String> getCookbook(
@PathParam("cookbookname") String cookbookName);
/**
* @see ChefClient#createClient
@ -149,15 +152,26 @@ public interface ChefAsyncClient {
@HEAD
@Path("clients/{clientname}")
@ExceptionParser(ReturnFalseOnNotFoundOr404.class)
ListenableFuture<Boolean> clientExists(@PathParam("clientname") String clientname);
ListenableFuture<Boolean> clientExists(
@PathParam("clientname") String clientname);
/**
* @see ChefClient#getClient
*/
@GET
@Path("clients/{clientname}")
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
ListenableFuture<Boolean> getClient(
@PathParam("clientname") String clientname);
/**
* @see ChefClient#deleteClient
*/
@DELETE
@Path("clients/{clientname}")
@ExceptionParser(ReturnVoidOnNotFoundOr404.class)
ListenableFuture<Void> deleteClient(@PathParam("clientname") String clientname);
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
ListenableFuture<String> deleteClient(
@PathParam("clientname") String clientname);
/**
* @see ChefClient#listClients

View File

@ -48,6 +48,7 @@ import java.util.concurrent.TimeUnit;
import org.jclouds.concurrent.Timeout;
import org.jclouds.http.HttpResponseException;
import org.jclouds.rest.AuthorizationException;
import org.jclouds.rest.ResourceNotFoundException;
/**
* Provides synchronous access to Chef.
@ -59,47 +60,174 @@ import org.jclouds.rest.AuthorizationException;
*/
@Timeout(duration = 30, timeUnit = TimeUnit.SECONDS)
public interface ChefClient {
/**
*
* @return a list of all the cookbook names
* @throws AuthorizationException
* <p/>
* "401 Unauthorized" if the caller is not a recognized user.
* <p/>
* "403 Forbidden" if you do not have permission to see the
* cookbook list.
*/
Set<String> listCookbooks();
/**
* Creates (uploads) a cookbook with the name present from the tar/gz file.
*
* @param cookbookName
* matches the root directory path of the archive
* @param tgzArchive
* tar gz archive, with a base path of {@code cookbookName}
* <p/>
* "401 Unauthorized" if the caller is not a recognized user.
* <p/>
* "403 Forbidden" if you do not have permission to create
* cookbooks.
* @throws HttpResponseException
* "409 Conflict" if the cookbook already exists
*/
@Timeout(duration = 10, timeUnit = TimeUnit.MINUTES)
void createCookbook(String cookbookName, File content);
void createCookbook(String cookbookName, File tgzArchive);
/**
* like {@link #createCookbook(String, File)}, except that a byte stream is
* allowed.
*/
@Timeout(duration = 10, timeUnit = TimeUnit.MINUTES)
void createCookbook(String cookbookName, byte[] content);
void createCookbook(String cookbookName, byte[] tgzArchive);
/**
* Overrides (uploads) a cookbook with the content in the tar/gz file.
*
* @param cookbookName
* matches the root directory path of the archive
* @param tgzArchive
* tar gz archive, with a base path of {@code cookbookName}
* <p/>
* "401 Unauthorized" if the caller is not a recognized user.
* <p/>
* "403 Forbidden" if you do not have permission to update
* cookbooks.
* @throws ResourceNotFoundException
* if the cookbook does not exist
*/
@Timeout(duration = 10, timeUnit = TimeUnit.MINUTES)
void updateCookbook(String cookbookName, File content);
void updateCookbook(String cookbookName, File tgzArchive);
/**
* like {@link #updateCookbook(String, File)}, except that a byte stream is
* allowed.
*/
@Timeout(duration = 10, timeUnit = TimeUnit.MINUTES)
void updateCookbook(String cookbookName, byte[] content);
void updateCookbook(String cookbookName, byte[] tgzArchive);
void deleteCookbook(String cookbookName);
/**
* deletes an existing cookbook.
*
* @return last state of the client you deleted or null, if not found
* @throws AuthorizationException
* <p/>
* "401 Unauthorized" if you are not a recognized user.
* <p/>
* "403 Forbidden" if you do not have Delete rights on the
* cookbook.
*/
String deleteCookbook(String cookbookName);
/**
* Returns a description of the cookbook, with links to all of its component
* parts, and the metadata.
*
* @return the cookbook or null, if not found
*
* @throws AuthorizationException
* <p/>
* "401 Unauthorized" if the caller is not a recognized user.
* <p/>
* "403 Forbidden" if the caller is not authorized to view the
* cookbook.
*/
String getCookbook(String cookbookName);
/**
* creates a new client
*
* @return the private key of the client. You can then use this client name and private key to
* access the Opscode API.
* @return the private key of the client. You can then use this client name
* and private key to access the Opscode API.
* @throws AuthorizationException
* <p/>
* "401 Unauthorized" if the caller is not a recognized user.
* <p/>
* "403 Forbidden" if the caller is not authorized to create a client.
* "403 Forbidden" if the caller is not authorized to create a
* client.
* @throws HttpResponseException
* "409 Conflict" if the client already exists
*/
@Timeout(duration = 120, timeUnit = TimeUnit.SECONDS)
String createClient(String name);
/**
* generate a new key-pair for this client, and return the new private key in
* the response body.
*
* @return the new private key
*
* @throws AuthorizationException
* <p/>
* "401 Unauthorized" if the caller is not a recognized user.
* <p/>
* "403 Forbidden" if the caller is not authorized to modify the
* client.
*/
@Timeout(duration = 120, timeUnit = TimeUnit.SECONDS)
String generateKeyForClient(String name);
/**
* @return list of client names.
*
* @throws AuthorizationException
* <p/>
* "401 Unauthorized" if you are not a recognized user.
* <p/>
* "403 Forbidden" if you do not have rights to list clients.
*/
Set<String> listClients();
/**
*
* @return true if the specified client name exists.
*
* @throws AuthorizationException
* <p/>
* "401 Unauthorized" if you are not a recognized user.
* <p/>
* "403 Forbidden" if you do not have rights to view the client.
*/
boolean clientExists(String name);
void deleteClient(String name);
/**
* deletes an existing client.
*
* @return last state of the client you deleted or null, if not found
*
* @throws AuthorizationException
* <p/>
* "401 Unauthorized" if you are not a recognized user.
* <p/>
* "403 Forbidden" if you do not have Delete rights on the client.
*/
String deleteClient(String name);
/**
* gets an existing client.
*
* @throws AuthorizationException
* <p/>
* "401 Unauthorized" if you are not a recognized user.
* <p/>
* "403 Forbidden" if you do not have view rights on the client.
*/
String getClient(String name);
}

View File

@ -11,7 +11,7 @@
* "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
*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
@ -25,6 +25,7 @@ package org.jclouds.chef;
import static org.testng.Assert.assertEquals;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Method;
@ -35,19 +36,22 @@ import org.jclouds.chef.functions.ParseKeyFromJson;
import org.jclouds.chef.functions.ParseKeySetFromJson;
import org.jclouds.date.TimeStamp;
import org.jclouds.http.functions.CloseContentAndReturn;
import org.jclouds.http.functions.ReturnStringIf200;
import org.jclouds.http.functions.ReturnTrueIf2xx;
import org.jclouds.logging.config.NullLoggingModule;
import org.jclouds.rest.RestClientTest;
import org.jclouds.rest.functions.ReturnFalseOnNotFoundOr404;
import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
import org.jclouds.rest.functions.ReturnVoidOnNotFoundOr404;
import org.jclouds.rest.internal.GeneratedHttpRequest;
import org.jclouds.rest.internal.RestAnnotationProcessor;
import com.google.inject.name.Names;
import org.testng.annotations.Test;
import com.google.common.base.Supplier;
import com.google.common.io.Files;
import com.google.inject.Module;
import com.google.inject.TypeLiteral;
import com.google.inject.name.Names;
/**
* Tests annotation parsing of {@code ChefAsyncClient}
@ -56,29 +60,40 @@ import com.google.inject.TypeLiteral;
*/
@Test(groups = "unit", testName = "chef.ChefAsyncClientTest")
public class ChefAsyncClientTest extends RestClientTest<ChefAsyncClient> {
public void testClientExists() throws SecurityException, NoSuchMethodException, IOException {
Method method = ChefAsyncClient.class.getMethod("clientExists", String.class);
GeneratedHttpRequest<ChefAsyncClient> httpRequest = processor.createRequest(method, "client");
assertRequestLineEquals(httpRequest, "HEAD http://localhost:4000/clients/client HTTP/1.1");
public void testGetCookbook() throws SecurityException,
NoSuchMethodException, IOException {
Method method = ChefAsyncClient.class.getMethod("getCookbook",
String.class);
GeneratedHttpRequest<ChefAsyncClient> httpRequest = processor
.createRequest(method, "cookbook");
assertRequestLineEquals(httpRequest,
"GET http://localhost:4000/cookbooks/cookbook HTTP/1.1");
assertHeadersEqual(httpRequest, "Accept: application/json\n");
assertPayloadEquals(httpRequest, null);
assertResponseParserClassEquals(method, httpRequest, ReturnTrueIf2xx.class);
assertResponseParserClassEquals(method, httpRequest,
ReturnStringIf200.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, ReturnFalseOnNotFoundOr404.class);
assertExceptionParserClassEquals(method, ReturnNullOnNotFoundOr404.class);
checkFilters(httpRequest);
}
public void testDeleteClient() throws SecurityException, NoSuchMethodException, IOException {
Method method = ChefAsyncClient.class.getMethod("deleteClient", String.class);
GeneratedHttpRequest<ChefAsyncClient> httpRequest = processor.createRequest(method, "client");
assertRequestLineEquals(httpRequest, "DELETE http://localhost:4000/clients/client HTTP/1.1");
public void testDeleteCookbook() throws SecurityException,
NoSuchMethodException, IOException {
Method method = ChefAsyncClient.class.getMethod("deleteCookbook",
String.class);
GeneratedHttpRequest<ChefAsyncClient> httpRequest = processor
.createRequest(method, "cookbook");
assertRequestLineEquals(httpRequest,
"DELETE http://localhost:4000/cookbooks/cookbook HTTP/1.1");
assertHeadersEqual(httpRequest, "Accept: application/json\n");
assertPayloadEquals(httpRequest, null);
assertResponseParserClassEquals(method, httpRequest, CloseContentAndReturn.class);
assertResponseParserClassEquals(method, httpRequest,
CloseContentAndReturn.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, ReturnVoidOnNotFoundOr404.class);
@ -86,16 +101,39 @@ public class ChefAsyncClientTest extends RestClientTest<ChefAsyncClient> {
}
public void testGenerateKeyForClient() throws SecurityException, NoSuchMethodException,
IOException {
Method method = ChefAsyncClient.class.getMethod("generateKeyForClient", String.class);
GeneratedHttpRequest<ChefAsyncClient> httpRequest = processor.createRequest(method, "client");
assertRequestLineEquals(httpRequest, "PUT http://localhost:4000/clients/client HTTP/1.1");
assertHeadersEqual(httpRequest,
"Accept: application/json\nContent-Length: 44\nContent-Type: application/json\n");
assertPayloadEquals(httpRequest, "{\"clientname\":\"client\", \"private_key\": true}");
private static final String COOOKBOOK_BODY =
assertResponseParserClassEquals(method, httpRequest, ParseKeyFromJson.class);
"----JCLOUDS--\r\n"
+ "Content-Disposition: form-data; name=\"name\"\r\n\r\n"
+ "cookbook\r\n"
+ "----JCLOUDS--\r\n"
+ "Content-Disposition: form-data; name=\"file\"; filename=\"cookbook.tar.gz\"\r\n"
+ "Content-Type: application/octet-stream\r\n\r\n\r\n"
+ "----JCLOUDS----\r\n";
public void testCreateCookbookFile() throws SecurityException,
NoSuchMethodException, IOException {
Method method = ChefAsyncClient.class.getMethod("createCookbook",
String.class, File.class);
File file = File.createTempFile("jclouds-chef=test", ".tar.gz");
file.deleteOnExit();
Files.write("".getBytes(), file);
GeneratedHttpRequest<ChefAsyncClient> httpRequest = processor
.createRequest(method, "cookbook", file);
assertRequestLineEquals(httpRequest,
"POST http://localhost:4000/cookbooks HTTP/1.1");
assertHeadersEqual(
httpRequest,
"Accept: application/json\nContent-Length: "
+ (file.getName().length() + 206)
+ "\nContent-Type: multipart/form-data; boundary=--JCLOUDS--\n");
assertPayloadEquals(httpRequest, COOOKBOOK_BODY.replace(
"cookbook.tar.gz", file.getName()));
assertResponseParserClassEquals(method, httpRequest,
CloseContentAndReturn.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, null);
@ -103,16 +141,22 @@ public class ChefAsyncClientTest extends RestClientTest<ChefAsyncClient> {
}
public void testCreateClient() throws SecurityException, NoSuchMethodException, IOException {
Method method = ChefAsyncClient.class.getMethod("createClient", String.class);
GeneratedHttpRequest<ChefAsyncClient> httpRequest = processor.createRequest(method, "client");
public void testCreateCookbookByte() throws SecurityException,
NoSuchMethodException, IOException {
Method method = ChefAsyncClient.class.getMethod("createCookbook",
String.class, byte[].class);
GeneratedHttpRequest<ChefAsyncClient> httpRequest = processor
.createRequest(method, "cookbook", "".getBytes());
assertRequestLineEquals(httpRequest, "POST http://localhost:4000/clients HTTP/1.1");
assertHeadersEqual(httpRequest,
"Accept: application/json\nContent-Length: 23\nContent-Type: application/json\n");
assertPayloadEquals(httpRequest, "{\"clientname\":\"client\"}");
assertRequestLineEquals(httpRequest,
"POST http://localhost:4000/cookbooks HTTP/1.1");
assertHeadersEqual(
httpRequest,
"Accept: application/json\nContent-Length: 221\nContent-Type: multipart/form-data; boundary=--JCLOUDS--\n");
assertPayloadEquals(httpRequest, COOOKBOOK_BODY);
assertResponseParserClassEquals(method, httpRequest, ParseKeyFromJson.class);
assertResponseParserClassEquals(method, httpRequest,
CloseContentAndReturn.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, null);
@ -120,15 +164,178 @@ public class ChefAsyncClientTest extends RestClientTest<ChefAsyncClient> {
}
public void testListClients() throws SecurityException, NoSuchMethodException, IOException {
Method method = ChefAsyncClient.class.getMethod("listClients");
GeneratedHttpRequest<ChefAsyncClient> httpRequest = processor.createRequest(method);
public void testUpdateCookbookFile() throws SecurityException,
NoSuchMethodException, IOException {
Method method = ChefAsyncClient.class.getMethod("updateCookbook",
String.class, File.class);
assertRequestLineEquals(httpRequest, "GET http://localhost:4000/clients HTTP/1.1");
File file = File.createTempFile("jclouds-chef=test", ".tar.gz");
file.deleteOnExit();
Files.write("".getBytes(), file);
GeneratedHttpRequest<ChefAsyncClient> httpRequest = processor
.createRequest(method, "cookbook", file);
assertRequestLineEquals(httpRequest,
"PUT http://localhost:4000/cookbooks/cookbook/_content HTTP/1.1");
assertHeadersEqual(
httpRequest,
"Accept: application/json\nContent-Length: "
+ (file.getName().length() + 206)
+ "\nContent-Type: multipart/form-data; boundary=--JCLOUDS--\n");
assertPayloadEquals(httpRequest, COOOKBOOK_BODY.replace(
"cookbook.tar.gz", file.getName()));
assertResponseParserClassEquals(method, httpRequest,
CloseContentAndReturn.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, null);
checkFilters(httpRequest);
}
public void testUpdateCookbookByte() throws SecurityException,
NoSuchMethodException, IOException {
Method method = ChefAsyncClient.class.getMethod("updateCookbook",
String.class, byte[].class);
GeneratedHttpRequest<ChefAsyncClient> httpRequest = processor
.createRequest(method, "cookbook", "".getBytes());
assertRequestLineEquals(httpRequest,
"PUT http://localhost:4000/cookbooks/cookbook/_content HTTP/1.1");
assertHeadersEqual(
httpRequest,
"Accept: application/json\nContent-Length: 221\nContent-Type: multipart/form-data; boundary=--JCLOUDS--\n");
assertPayloadEquals(httpRequest, COOOKBOOK_BODY);
assertResponseParserClassEquals(method, httpRequest,
CloseContentAndReturn.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, null);
checkFilters(httpRequest);
}
public void testListCookbooks() throws SecurityException,
NoSuchMethodException, IOException {
Method method = ChefAsyncClient.class.getMethod("listCookbooks");
GeneratedHttpRequest<ChefAsyncClient> httpRequest = processor
.createRequest(method);
assertRequestLineEquals(httpRequest,
"GET http://localhost:4000/cookbooks HTTP/1.1");
assertHeadersEqual(httpRequest, "Accept: application/json\n");
assertPayloadEquals(httpRequest, null);
assertResponseParserClassEquals(method, httpRequest, ParseKeySetFromJson.class);
assertResponseParserClassEquals(method, httpRequest,
ParseKeySetFromJson.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, null);
checkFilters(httpRequest);
}
public void testClientExists() throws SecurityException,
NoSuchMethodException, IOException {
Method method = ChefAsyncClient.class.getMethod("clientExists",
String.class);
GeneratedHttpRequest<ChefAsyncClient> httpRequest = processor
.createRequest(method, "client");
assertRequestLineEquals(httpRequest,
"HEAD http://localhost:4000/clients/client HTTP/1.1");
assertHeadersEqual(httpRequest, "Accept: application/json\n");
assertPayloadEquals(httpRequest, null);
assertResponseParserClassEquals(method, httpRequest,
ReturnTrueIf2xx.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, ReturnFalseOnNotFoundOr404.class);
checkFilters(httpRequest);
}
public void testDeleteClient() throws SecurityException,
NoSuchMethodException, IOException {
Method method = ChefAsyncClient.class.getMethod("deleteClient",
String.class);
GeneratedHttpRequest<ChefAsyncClient> httpRequest = processor
.createRequest(method, "client");
assertRequestLineEquals(httpRequest,
"DELETE http://localhost:4000/clients/client HTTP/1.1");
assertHeadersEqual(httpRequest, "Accept: application/json\n");
assertPayloadEquals(httpRequest, null);
assertResponseParserClassEquals(method, httpRequest,
ReturnStringIf200.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, ReturnNullOnNotFoundOr404.class);
checkFilters(httpRequest);
}
public void testGenerateKeyForClient() throws SecurityException,
NoSuchMethodException, IOException {
Method method = ChefAsyncClient.class.getMethod("generateKeyForClient",
String.class);
GeneratedHttpRequest<ChefAsyncClient> httpRequest = processor
.createRequest(method, "client");
assertRequestLineEquals(httpRequest,
"PUT http://localhost:4000/clients/client HTTP/1.1");
assertHeadersEqual(
httpRequest,
"Accept: application/json\nContent-Length: 44\nContent-Type: application/json\n");
assertPayloadEquals(httpRequest,
"{\"clientname\":\"client\", \"private_key\": true}");
assertResponseParserClassEquals(method, httpRequest,
ParseKeyFromJson.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, null);
checkFilters(httpRequest);
}
public void testCreateClient() throws SecurityException,
NoSuchMethodException, IOException {
Method method = ChefAsyncClient.class.getMethod("createClient",
String.class);
GeneratedHttpRequest<ChefAsyncClient> httpRequest = processor
.createRequest(method, "client");
assertRequestLineEquals(httpRequest,
"POST http://localhost:4000/clients HTTP/1.1");
assertHeadersEqual(
httpRequest,
"Accept: application/json\nContent-Length: 23\nContent-Type: application/json\n");
assertPayloadEquals(httpRequest, "{\"clientname\":\"client\"}");
assertResponseParserClassEquals(method, httpRequest,
ParseKeyFromJson.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, null);
checkFilters(httpRequest);
}
public void testListClients() throws SecurityException,
NoSuchMethodException, IOException {
Method method = ChefAsyncClient.class.getMethod("listClients");
GeneratedHttpRequest<ChefAsyncClient> httpRequest = processor
.createRequest(method);
assertRequestLineEquals(httpRequest,
"GET http://localhost:4000/clients HTTP/1.1");
assertHeadersEqual(httpRequest, "Accept: application/json\n");
assertPayloadEquals(httpRequest, null);
assertResponseParserClassEquals(method, httpRequest,
ParseKeySetFromJson.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, null);
@ -139,7 +346,8 @@ public class ChefAsyncClientTest extends RestClientTest<ChefAsyncClient> {
@Override
protected void checkFilters(GeneratedHttpRequest<ChefAsyncClient> httpRequest) {
assertEquals(httpRequest.getFilters().size(), 1);
assertEquals(httpRequest.getFilters().get(0).getClass(), SignedHeaderAuth.class);
assertEquals(httpRequest.getFilters().get(0).getClass(),
SignedHeaderAuth.class);
}
@Override
@ -153,8 +361,8 @@ public class ChefAsyncClientTest extends RestClientTest<ChefAsyncClient> {
return new ChefRestClientModule() {
@Override
protected void configure() {
Names.bindProperties(binder(), new ChefPropertiesBuilder("chef-validator",
SignedHeaderAuthTest.PRIVATE_KEY).build());
Names.bindProperties(binder(), new ChefPropertiesBuilder(
"chef-validator", SignedHeaderAuthTest.PRIVATE_KEY).build());
install(new NullLoggingModule());
super.configure();
}

View File

@ -63,37 +63,42 @@ public class ChefClientLiveTest {
private byte[] cookbookContent;
private File cookbookFile;
public static final String PREFIX = System.getProperty("user.name") + "-jcloudstest";
public static final String PREFIX = System.getProperty("user.name")
+ "-jcloudstest";
@BeforeClass(groups = { "live" })
public void setupClient() throws IOException {
endpoint = checkNotNull(System.getProperty("jclouds.test.endpoint"), "jclouds.test.endpoint");
endpoint = checkNotNull(System.getProperty("jclouds.test.endpoint"),
"jclouds.test.endpoint");
validator = System.getProperty("jclouds.test.validator");
if (validator == null || validator.equals(""))
validator = "chef-validator";
String validatorKey = System.getProperty("jclouds.test.validator.key");
if (validatorKey == null || validatorKey.equals(""))
validatorKey = "/etc/chef/validation.pem";
validatorKey = System.getProperty("user.home")
+ "/.chef/validation.pem";
user = checkNotNull(System.getProperty("jclouds.test.user"));
String keyfile = System.getProperty("jclouds.test.key");
if (keyfile == null || keyfile.equals(""))
keyfile = System.getProperty("user.home") + "/.chef/" + user + ".pem";
validatorConnection = createConnection(validator, Files.toString(new File(validatorKey),
Charsets.UTF_8));
adminConnection = createConnection(user, Files.toString(new File(keyfile), Charsets.UTF_8));
validatorConnection = createConnection(validator, Files.toString(
new File(validatorKey), Charsets.UTF_8));
adminConnection = createConnection(user, Files.toString(
new File(keyfile), Charsets.UTF_8));
}
private RestContext<ChefClient, ChefAsyncClient> createConnection(String identity, String key)
throws IOException {
return ChefContextFactory.createContext(URI.create(endpoint), identity, key,
new Log4JLoggingModule());
private RestContext<ChefClient, ChefAsyncClient> createConnection(
String identity, String key) throws IOException {
return ChefContextFactory.createContext(URI.create(endpoint), identity,
key, new Log4JLoggingModule());
}
@Test
public void testListClients() throws Exception {
Set<String> clients = validatorConnection.getApi().listClients();
assertNotNull(clients);
assert clients.contains(validator) : "validator: " + validator + " not in: " + clients;
assert clients.contains(validator) : "validator: " + validator
+ " not in: " + clients;
}
@Test(dependsOnMethods = "testListClients")
@ -135,7 +140,8 @@ public class ChefClientLiveTest {
adminConnection.getApi().createCookbook(COOKBOOK_NAME, cookbookFile);
adminConnection.getApi().deleteCookbook(COOKBOOK_NAME);
adminConnection.getApi().createCookbook(COOKBOOK_NAME, cookbookContent);
adminConnection.getApi()
.createCookbook(COOKBOOK_NAME, cookbookContent);
} finally {
if (in != null)
@ -158,6 +164,8 @@ public class ChefClientLiveTest {
@AfterClass(groups = { "live" })
public void teardownClient() throws IOException {
if (validatorConnection.getApi().clientExists(PREFIX))
validatorConnection.getApi().deleteClient(PREFIX);
if (clientConnection != null)
clientConnection.close();
if (validatorConnection != null)

View File

@ -79,7 +79,8 @@ public interface OpscodePlatformAsyncClient {
@POST
@Path("/users")
@ResponseParser(ParseKeyFromJson.class)
ListenableFuture<String> createUser(@BinderParam(BindToJsonPayload.class) User user);
ListenableFuture<String> createUser(
@BinderParam(BindToJsonPayload.class) User user);
/**
* @see ChefClient#updateUser
@ -104,6 +105,7 @@ public interface OpscodePlatformAsyncClient {
*/
@DELETE
@Path("/users/{username}")
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
@ResponseParser(ParseUserFromJson.class)
ListenableFuture<User> deleteUser(@PathParam("username") String username);
@ -113,7 +115,8 @@ public interface OpscodePlatformAsyncClient {
@POST
@Path("/organizations")
@ResponseParser(ParseKeyFromJson.class)
ListenableFuture<String> createOrg(@BinderParam(BindToJsonPayload.class) Organization org);
ListenableFuture<String> createOrg(
@BinderParam(BindToJsonPayload.class) Organization org);
/**
* @see ChefClient#updateOrg
@ -138,6 +141,7 @@ public interface OpscodePlatformAsyncClient {
*/
@DELETE
@Path("/organizations/{orgname}")
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
@ResponseParser(ParseOrganizationFromJson.class)
ListenableFuture<Organization> deleteOrg(@PathParam("orgname") String orgname);

View File

@ -58,13 +58,14 @@ public interface OpscodePlatformClient {
/**
* creates a new user
*
* @return the private key of the user. You can then use this user name and private key to access
* the Opscode API.
* @return the private key of the user. You can then use this user name and
* private key to access the Opscode API.
* @throws AuthorizationException
* <p/>
* "401 Unauthorized" if the caller is not a recognized user.
* <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);
@ -73,9 +74,9 @@ public interface OpscodePlatformClient {
*
* @throws AuthorizationException
* <p/>
* 401 Unauthorized if you are not a recognized user.
* "401 Unauthorized" if you are not a recognized user.
* <p/>
* 403 Forbidden if you do not have Update rights on the user.
* "403 Forbidden" if you do not have Update rights on the user.
* @throws ResourceNotFoundException
* if the user does not exist.
*/
@ -91,62 +92,64 @@ public interface OpscodePlatformClient {
/**
* deletes an existing user. Note: you must have delete rights on the user.
*
* @return the last state of the User object in question. * @throws AuthorizationException
* @return last state of the user you deleted or null, if not found
* @throws AuthorizationException
* <p/>
* 401 Unauthorized if you are not a recognized user.
* "401 Unauthorized" if you are not a recognized user.
* <p/>
* 403 Forbidden if you do not have Delete rights on the user.
* @throws ResourceNotFoundException
* <p/>
* 404 Not Found if the user does not exist.
* "403 Forbidden" if you do not have Delete rights on the user.
*/
User deleteUser(String username);
/**
* creates a new organization
*
* @return the private key of the organization. You can then use this organization name and
* private key to access the Opscode API.
* @return the private key of the organization. You can then use this
* organization name and private key to access the Opscode API.
* @throws AuthorizationException
* <p/>
* "401 Unauthorized" if the caller is not a recognized organization.
* "401 Unauthorized" if the caller is not a recognized
* organization.
* <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);
/**
* 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.
*
* @throws AuthorizationException
* <p/>
* 401 Unauthorized if you are not a recognized organization.
* "401 Unauthorized" if you are not a recognized organization.
* <p/>
* 403 Forbidden if you do not have Update rights on the organization.
* "403 Forbidden" if you do not have Update rights on the
* organization.
* @throws ResourceNotFoundException
* if the organization does not exist.
*/
Organization updateOrg(Organization organization);
/**
* retrieves an existing organization. Note: you must have update rights on the organization.
* retrieves an existing organization. Note: you must have update rights on
* the organization.
*
* @return null, if the organization is not found
*/
Organization getOrg(String organizationname);
/**
* deletes an existing organization. Note: you must have delete rights on the organization.
* deletes an existing organization. Note: you must have delete rights on the
* organization.
*
* @return the last state of the Organization object in question. * @throws
* AuthorizationException
* @return last state of the org you deleted or null, if not found
* @throws AuthorizationException
* <p/>
* 401 Unauthorized if you are not a recognized organization.
* "401 Unauthorized" if you are not a recognized organization.
* <p/>
* 403 Forbidden if you do not have Delete rights on the organization.
* @throws ResourceNotFoundException
* <p/>
* 404 Not Found if the organization does not exist.
* "403 Forbidden" if you do not have Delete rights on the
* organization.
*/
Organization deleteOrg(String organizationname);
}

View File

@ -49,7 +49,6 @@ import org.jclouds.rest.config.RestModule;
import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
import org.jclouds.rest.internal.GeneratedHttpRequest;
import org.jclouds.rest.internal.RestAnnotationProcessor;
import com.google.inject.name.Names;
import org.testng.annotations.Test;
import com.google.common.base.Supplier;
@ -58,6 +57,7 @@ import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Module;
import com.google.inject.TypeLiteral;
import com.google.inject.name.Names;
/**
* Tests annotation parsing of {@code OpscodePlatformAsyncClient}
@ -65,44 +65,56 @@ import com.google.inject.TypeLiteral;
* @author Adrian Cole
*/
@Test(groups = "unit", testName = "opscodeplatform.OpscodePlatformAsyncClientTest")
public class OpscodePlatformAsyncClientTest extends RestClientTest<OpscodePlatformAsyncClient> {
public class OpscodePlatformAsyncClientTest extends
RestClientTest<OpscodePlatformAsyncClient> {
public void testDelegatedChefCallsResolveProperly() throws SecurityException,
NoSuchMethodException, InterruptedException, ExecutionException {
public void testDelegatedChefCallsResolveProperly()
throws SecurityException, NoSuchMethodException, InterruptedException,
ExecutionException {
final TransformingHttpCommandExecutorService httpExecutor = createMock(TransformingHttpCommandExecutorService.class);
Injector injector = Guice.createInjector(createModule(), new RestModule() {
Injector injector = Guice.createInjector(createModule(),
new RestModule() {
@Override
protected void configure() {
bind(TransformingHttpCommandExecutorService.class).toInstance(httpExecutor);
bind(TransformingHttpCommandExecutorService.class)
.toInstance(httpExecutor);
super.configure();
}
}, new ExecutorServiceModule(sameThreadExecutor(), sameThreadExecutor()));
}, new ExecutorServiceModule(sameThreadExecutor(),
sameThreadExecutor()));
replay(httpExecutor);
OpscodePlatformAsyncClient caller = injector.getInstance(OpscodePlatformAsyncClient.class);
OpscodePlatformAsyncClient caller = injector
.getInstance(OpscodePlatformAsyncClient.class);
try {
caller.getChefClientForOrg("goo").listClients().get();
assert false : "shouldn't have connected as this url should be dummy";
} catch (AssertionError e) {
assert e.getMessage().indexOf(
assert e
.getMessage()
.indexOf(
"[request=GET https://api.opscode.com/organizations/goo/clients HTTP/1.1]") != -1 : e
.getMessage();
}
}
public void testCreateUser() throws SecurityException, NoSuchMethodException, IOException {
Method method = OpscodePlatformAsyncClient.class.getMethod("createUser", User.class);
GeneratedHttpRequest<OpscodePlatformAsyncClient> httpRequest = processor.createRequest(
method, new User("myuser"));
public void testCreateUser() throws SecurityException,
NoSuchMethodException, IOException {
Method method = OpscodePlatformAsyncClient.class.getMethod("createUser",
User.class);
GeneratedHttpRequest<OpscodePlatformAsyncClient> httpRequest = processor
.createRequest(method, new User("myuser"));
assertRequestLineEquals(httpRequest, "POST https://api.opscode.com/users HTTP/1.1");
assertHeadersEqual(httpRequest,
assertRequestLineEquals(httpRequest,
"POST https://api.opscode.com/users HTTP/1.1");
assertHeadersEqual(
httpRequest,
"Accept: application/json\nContent-Length: 21\nContent-Type: application/json\n");
assertPayloadEquals(httpRequest, "{\"username\":\"myuser\"}");
@ -110,7 +122,8 @@ public class OpscodePlatformAsyncClientTest extends RestClientTest<OpscodePlatfo
Iterables.getOnlyElement(httpRequest.getFilters()).filter(httpRequest);
Iterables.getOnlyElement(httpRequest.getFilters()).filter(httpRequest);
assertRequestLineEquals(httpRequest, "POST https://api.opscode.com/users HTTP/1.1");
assertRequestLineEquals(httpRequest,
"POST https://api.opscode.com/users HTTP/1.1");
assertHeadersEqual(
httpRequest,
new StringBuilder("Accept: application/json")
@ -136,13 +149,15 @@ public class OpscodePlatformAsyncClientTest extends RestClientTest<OpscodePlatfo
.append("\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(
.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\"}");
assertResponseParserClassEquals(method, httpRequest, ParseKeyFromJson.class);
assertResponseParserClassEquals(method, httpRequest,
ParseKeyFromJson.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, null);
@ -150,17 +165,22 @@ public class OpscodePlatformAsyncClientTest extends RestClientTest<OpscodePlatfo
}
public void testUpdateUser() throws SecurityException, NoSuchMethodException, IOException {
Method method = OpscodePlatformAsyncClient.class.getMethod("updateUser", User.class);
GeneratedHttpRequest<OpscodePlatformAsyncClient> httpRequest = processor.createRequest(
method, new User("myuser"));
public void testUpdateUser() throws SecurityException,
NoSuchMethodException, IOException {
Method method = OpscodePlatformAsyncClient.class.getMethod("updateUser",
User.class);
GeneratedHttpRequest<OpscodePlatformAsyncClient> httpRequest = processor
.createRequest(method, new User("myuser"));
assertRequestLineEquals(httpRequest, "PUT https://api.opscode.com/users/myuser HTTP/1.1");
assertHeadersEqual(httpRequest,
assertRequestLineEquals(httpRequest,
"PUT https://api.opscode.com/users/myuser HTTP/1.1");
assertHeadersEqual(
httpRequest,
"Accept: application/json\nContent-Length: 21\nContent-Type: application/json\n");
assertPayloadEquals(httpRequest, "{\"username\":\"myuser\"}");
assertResponseParserClassEquals(method, httpRequest, ParseUserFromJson.class);
assertResponseParserClassEquals(method, httpRequest,
ParseUserFromJson.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, null);
@ -168,16 +188,20 @@ public class OpscodePlatformAsyncClientTest extends RestClientTest<OpscodePlatfo
}
public void testGetUser() throws SecurityException, NoSuchMethodException, IOException {
Method method = OpscodePlatformAsyncClient.class.getMethod("getUser", String.class);
GeneratedHttpRequest<OpscodePlatformAsyncClient> httpRequest = processor.createRequest(
method, "myuser");
public void testGetUser() throws SecurityException, NoSuchMethodException,
IOException {
Method method = OpscodePlatformAsyncClient.class.getMethod("getUser",
String.class);
GeneratedHttpRequest<OpscodePlatformAsyncClient> httpRequest = processor
.createRequest(method, "myuser");
assertRequestLineEquals(httpRequest, "GET https://api.opscode.com/users/myuser HTTP/1.1");
assertRequestLineEquals(httpRequest,
"GET https://api.opscode.com/users/myuser HTTP/1.1");
assertHeadersEqual(httpRequest, "Accept: application/json\n");
assertPayloadEquals(httpRequest, null);
assertResponseParserClassEquals(method, httpRequest, ParseUserFromJson.class);
assertResponseParserClassEquals(method, httpRequest,
ParseUserFromJson.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, ReturnNullOnNotFoundOr404.class);
@ -185,34 +209,43 @@ public class OpscodePlatformAsyncClientTest extends RestClientTest<OpscodePlatfo
}
public void testDeleteUser() throws SecurityException, NoSuchMethodException, IOException {
Method method = OpscodePlatformAsyncClient.class.getMethod("deleteUser", String.class);
GeneratedHttpRequest<OpscodePlatformAsyncClient> httpRequest = processor.createRequest(
method, "myuser");
public void testDeleteUser() throws SecurityException,
NoSuchMethodException, IOException {
Method method = OpscodePlatformAsyncClient.class.getMethod("deleteUser",
String.class);
GeneratedHttpRequest<OpscodePlatformAsyncClient> httpRequest = processor
.createRequest(method, "myuser");
assertRequestLineEquals(httpRequest, "DELETE https://api.opscode.com/users/myuser HTTP/1.1");
assertRequestLineEquals(httpRequest,
"DELETE https://api.opscode.com/users/myuser HTTP/1.1");
assertHeadersEqual(httpRequest, "Accept: application/json\n");
assertPayloadEquals(httpRequest, null);
assertResponseParserClassEquals(method, httpRequest, ParseUserFromJson.class);
assertResponseParserClassEquals(method, httpRequest,
ParseUserFromJson.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, null);
assertExceptionParserClassEquals(method, ReturnNullOnNotFoundOr404.class);
checkFilters(httpRequest);
}
public void testCreateOrg() throws SecurityException, NoSuchMethodException, IOException {
Method method = OpscodePlatformAsyncClient.class.getMethod("createOrg", Organization.class);
GeneratedHttpRequest<OpscodePlatformAsyncClient> httpRequest = processor.createRequest(
method, new Organization("myorganization"));
public void testCreateOrg() throws SecurityException, NoSuchMethodException,
IOException {
Method method = OpscodePlatformAsyncClient.class.getMethod("createOrg",
Organization.class);
GeneratedHttpRequest<OpscodePlatformAsyncClient> httpRequest = processor
.createRequest(method, new Organization("myorganization"));
assertRequestLineEquals(httpRequest, "POST https://api.opscode.com/organizations HTTP/1.1");
assertHeadersEqual(httpRequest,
assertRequestLineEquals(httpRequest,
"POST https://api.opscode.com/organizations HTTP/1.1");
assertHeadersEqual(
httpRequest,
"Accept: application/json\nContent-Length: 25\nContent-Type: application/json\n");
assertPayloadEquals(httpRequest, "{\"name\":\"myorganization\"}");
assertResponseParserClassEquals(method, httpRequest, ParseKeyFromJson.class);
assertResponseParserClassEquals(method, httpRequest,
ParseKeyFromJson.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, null);
@ -220,18 +253,22 @@ public class OpscodePlatformAsyncClientTest extends RestClientTest<OpscodePlatfo
}
public void testUpdateOrg() throws SecurityException, NoSuchMethodException, IOException {
Method method = OpscodePlatformAsyncClient.class.getMethod("updateOrg", Organization.class);
GeneratedHttpRequest<OpscodePlatformAsyncClient> httpRequest = processor.createRequest(
method, new Organization("myorganization"));
public void testUpdateOrg() throws SecurityException, NoSuchMethodException,
IOException {
Method method = OpscodePlatformAsyncClient.class.getMethod("updateOrg",
Organization.class);
GeneratedHttpRequest<OpscodePlatformAsyncClient> httpRequest = processor
.createRequest(method, new Organization("myorganization"));
assertRequestLineEquals(httpRequest,
"PUT https://api.opscode.com/organizations/myorganization HTTP/1.1");
assertHeadersEqual(httpRequest,
assertHeadersEqual(
httpRequest,
"Accept: application/json\nContent-Length: 25\nContent-Type: application/json\n");
assertPayloadEquals(httpRequest, "{\"name\":\"myorganization\"}");
assertResponseParserClassEquals(method, httpRequest, ParseOrganizationFromJson.class);
assertResponseParserClassEquals(method, httpRequest,
ParseOrganizationFromJson.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, null);
@ -239,17 +276,20 @@ public class OpscodePlatformAsyncClientTest extends RestClientTest<OpscodePlatfo
}
public void testGetOrg() throws SecurityException, NoSuchMethodException, IOException {
Method method = OpscodePlatformAsyncClient.class.getMethod("getOrg", String.class);
GeneratedHttpRequest<OpscodePlatformAsyncClient> httpRequest = processor.createRequest(
method, "myorganization");
public void testGetOrg() throws SecurityException, NoSuchMethodException,
IOException {
Method method = OpscodePlatformAsyncClient.class.getMethod("getOrg",
String.class);
GeneratedHttpRequest<OpscodePlatformAsyncClient> httpRequest = processor
.createRequest(method, "myorganization");
assertRequestLineEquals(httpRequest,
"GET https://api.opscode.com/organizations/myorganization HTTP/1.1");
assertHeadersEqual(httpRequest, "Accept: application/json\n");
assertPayloadEquals(httpRequest, null);
assertResponseParserClassEquals(method, httpRequest, ParseOrganizationFromJson.class);
assertResponseParserClassEquals(method, httpRequest,
ParseOrganizationFromJson.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, ReturnNullOnNotFoundOr404.class);
@ -257,28 +297,33 @@ public class OpscodePlatformAsyncClientTest extends RestClientTest<OpscodePlatfo
}
public void testDeleteOrg() throws SecurityException, NoSuchMethodException, IOException {
Method method = OpscodePlatformAsyncClient.class.getMethod("deleteOrg", String.class);
GeneratedHttpRequest<OpscodePlatformAsyncClient> httpRequest = processor.createRequest(
method, "myorganization");
public void testDeleteOrg() throws SecurityException, NoSuchMethodException,
IOException {
Method method = OpscodePlatformAsyncClient.class.getMethod("deleteOrg",
String.class);
GeneratedHttpRequest<OpscodePlatformAsyncClient> httpRequest = processor
.createRequest(method, "myorganization");
assertRequestLineEquals(httpRequest,
"DELETE https://api.opscode.com/organizations/myorganization HTTP/1.1");
assertHeadersEqual(httpRequest, "Accept: application/json\n");
assertPayloadEquals(httpRequest, null);
assertResponseParserClassEquals(method, httpRequest, ParseOrganizationFromJson.class);
assertResponseParserClassEquals(method, httpRequest,
ParseOrganizationFromJson.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, null);
assertExceptionParserClassEquals(method, ReturnNullOnNotFoundOr404.class);
checkFilters(httpRequest);
}
@Override
protected void checkFilters(GeneratedHttpRequest<OpscodePlatformAsyncClient> httpRequest) {
protected void checkFilters(
GeneratedHttpRequest<OpscodePlatformAsyncClient> httpRequest) {
assertEquals(httpRequest.getFilters().size(), 1);
assertEquals(httpRequest.getFilters().get(0).getClass(), SignedHeaderAuth.class);
assertEquals(httpRequest.getFilters().get(0).getClass(),
SignedHeaderAuth.class);
}
@Override
@ -292,7 +337,8 @@ public class OpscodePlatformAsyncClientTest extends RestClientTest<OpscodePlatfo
return new OpscodePlatformRestClientModule() {
@Override
protected void configure() {
Names.bindProperties(binder(), new OpscodePlatformPropertiesBuilder("user",
Names.bindProperties(binder(),
new OpscodePlatformPropertiesBuilder("user",
SignedHeaderAuthTest.PRIVATE_KEY).build());
install(new NullLoggingModule());
super.configure();