Issue 348: replaced custom-packaged resteasy with jersey-core

This commit is contained in:
Adrian Cole 2010-09-10 15:40:04 -07:00
parent 623423ae7c
commit 53adab1ab4
51 changed files with 444 additions and 2335 deletions

View File

@ -70,6 +70,7 @@ import com.google.common.util.concurrent.ListenableFuture;
*/
@RequestFilters(SignRequest.class)
@SkipEncoding('/')
@Path("/rest/namespace")
public interface AtmosStorageAsyncClient {
/**
* Creates a default implementation of AtmosObject
@ -80,17 +81,16 @@ public interface AtmosStorageAsyncClient {
* @see AtmosStorageClient#listDirectories
*/
@GET
@Path("/rest/namespace")
@Path("")
@ResponseParser(ParseDirectoryListFromContentAndHeaders.class)
@Consumes(MediaType.TEXT_XML)
ListenableFuture<BoundedSet<? extends DirectoryEntry>> listDirectories(
ListOptions... options);
ListenableFuture<BoundedSet<? extends DirectoryEntry>> listDirectories(ListOptions... options);
/**
* @see AtmosStorageClient#listDirectory
*/
@GET
@Path("/rest/namespace/{directoryName}/")
@Path("/{directoryName}/")
@ResponseParser(ParseDirectoryListFromContentAndHeaders.class)
@ExceptionParser(ThrowContainerNotFoundOn404.class)
@Consumes(MediaType.TEXT_XML)
@ -101,7 +101,7 @@ public interface AtmosStorageAsyncClient {
* @see AtmosStorageClient#createDirectory
*/
@POST
@Path("/rest/namespace/{directoryName}/")
@Path("/{directoryName}/")
@ExceptionParser(ReturnEndpointIfAlreadyExists.class)
@Consumes(MediaType.WILDCARD)
ListenableFuture<URI> createDirectory(@PathParam("directoryName") String directoryName);
@ -110,7 +110,7 @@ public interface AtmosStorageAsyncClient {
* @see AtmosStorageClient#createFile
*/
@POST
@Path("/rest/namespace/{parent}/{name}")
@Path("/{parent}/{name}")
@Consumes(MediaType.WILDCARD)
ListenableFuture<URI> createFile(
@PathParam("parent") String parent,
@ -120,7 +120,7 @@ public interface AtmosStorageAsyncClient {
* @see AtmosStorageClient#updateFile
*/
@PUT
@Path("/rest/namespace/{parent}/{name}")
@Path("/{parent}/{name}")
@ExceptionParser(ThrowKeyNotFoundOn404.class)
@Consumes(MediaType.WILDCARD)
ListenableFuture<Void> updateFile(
@ -133,7 +133,7 @@ public interface AtmosStorageAsyncClient {
@GET
@ResponseParser(ParseObjectFromHeadersAndHttpContent.class)
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
@Path("/rest/namespace/{path}")
@Path("/{path}")
@Consumes(MediaType.WILDCARD)
ListenableFuture<AtmosObject> readFile(@PathParam("path") String path, GetOptions... options);
@ -143,7 +143,7 @@ public interface AtmosStorageAsyncClient {
@HEAD
@ResponseParser(ParseObjectFromHeadersAndHttpContent.class)
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
@Path("/rest/namespace/{path}")
@Path("/{path}")
@Consumes(MediaType.WILDCARD)
ListenableFuture<AtmosObject> headFile(@PathParam("path") String path);
@ -154,7 +154,7 @@ public interface AtmosStorageAsyncClient {
@ResponseParser(ParseSystemMetadataFromHeaders.class)
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
// currently throws 403 errors @QueryParams(keys = "metadata/system")
@Path("/rest/namespace/{path}")
@Path("/{path}")
@Consumes(MediaType.WILDCARD)
ListenableFuture<SystemMetadata> getSystemMetadata(@PathParam("path") String path);
@ -164,7 +164,7 @@ public interface AtmosStorageAsyncClient {
@HEAD
@ResponseParser(ParseSystemMetadataFromHeaders.class)
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
@Path("/rest/namespace/{path}")
@Path("/{path}")
@QueryParams(keys = "metadata/user")
@Consumes(MediaType.WILDCARD)
ListenableFuture<UserMetadata> getUserMetadata(@PathParam("path") String path);
@ -174,7 +174,7 @@ public interface AtmosStorageAsyncClient {
*/
@DELETE
@ExceptionParser(ReturnVoidOnNotFoundOr404.class)
@Path("/rest/namespace/{path}")
@Path("/{path}")
@Consumes(MediaType.WILDCARD)
ListenableFuture<Void> deletePath(@PathParam("path") String path);
@ -183,7 +183,7 @@ public interface AtmosStorageAsyncClient {
*/
@HEAD
@ExceptionParser(ReturnFalseOnNotFoundOr404.class)
@Path("/rest/namespace/{path}")
@Path("/{path}")
@Consumes(MediaType.WILDCARD)
ListenableFuture<Boolean> pathExists(@PathParam("path") String path);

View File

@ -116,7 +116,7 @@ public interface S3AsyncClient {
* @see S3Client#getObject
*/
@GET
@Path("{key}")
@Path("/{key}")
@ExceptionParser(ReturnNullOnKeyNotFound.class)
@ResponseParser(ParseObjectFromHeadersAndHttpContent.class)
ListenableFuture<S3Object> getObject(
@ -127,7 +127,7 @@ public interface S3AsyncClient {
* @see S3Client#headObject
*/
@HEAD
@Path("{key}")
@Path("/{key}")
@ExceptionParser(ReturnNullOnKeyNotFound.class)
@ResponseParser(ParseObjectMetadataFromHeaders.class)
ListenableFuture<ObjectMetadata> headObject(
@ -138,7 +138,7 @@ public interface S3AsyncClient {
* @see S3Client#objectExists
*/
@HEAD
@Path("{key}")
@Path("/{key}")
@ExceptionParser(ReturnFalseOnKeyNotFound.class)
ListenableFuture<Boolean> objectExists(
@Bucket @BinderParam(BindAsHostPrefixIfConfigured.class) @ParamValidators( { BucketNameValidator.class }) String bucketName,
@ -148,7 +148,7 @@ public interface S3AsyncClient {
* @see S3Client#deleteObject
*/
@DELETE
@Path("{key}")
@Path("/{key}")
@ExceptionParser(ReturnVoidOnNotFoundOr404.class)
ListenableFuture<Void> deleteObject(
@Bucket @BinderParam(BindAsHostPrefixIfConfigured.class) @ParamValidators( { BucketNameValidator.class }) String bucketName,
@ -158,7 +158,7 @@ public interface S3AsyncClient {
* @see S3Client#putObject
*/
@PUT
@Path("{key}")
@Path("/{key}")
@ResponseParser(ParseETagHeader.class)
ListenableFuture<String> putObject(
@Bucket @BinderParam(BindAsHostPrefixIfConfigured.class) @ParamValidators( { BucketNameValidator.class }) String bucketName,
@ -249,7 +249,7 @@ public interface S3AsyncClient {
* @see S3Client#copyObject
*/
@PUT
@Path("{destinationObject}")
@Path("/{destinationObject}")
@Headers(keys = "x-amz-copy-source", values = "/{sourceBucket}/{sourceObject}")
@XMLResponseParser(CopyObjectHandler.class)
ListenableFuture<ObjectMetadata> copyObject(
@ -284,7 +284,7 @@ public interface S3AsyncClient {
*/
@GET
@QueryParams(keys = "acl")
@Path("{key}")
@Path("/{key}")
@XMLResponseParser(AccessControlListHandler.class)
@ExceptionParser(ThrowKeyNotFoundOn404.class)
ListenableFuture<AccessControlList> getObjectACL(
@ -296,7 +296,7 @@ public interface S3AsyncClient {
*/
@PUT
@QueryParams(keys = "acl")
@Path("{key}")
@Path("/{key}")
ListenableFuture<Boolean> putObjectACL(
@Bucket @BinderParam(BindAsHostPrefixIfConfigured.class) @ParamValidators( { BucketNameValidator.class }) String bucketName,
@PathParam("key") String key,

View File

@ -33,7 +33,6 @@ import java.util.Set;
import javax.inject.Singleton;
import javax.ws.rs.core.UriBuilder;
import org.jboss.resteasy.specimpl.UriBuilderImpl;
import org.jclouds.PerformanceTest;
import org.jclouds.aws.domain.Region;
import org.jclouds.aws.sqs.domain.Queue;
@ -55,6 +54,7 @@ import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Provides;
import com.sun.jersey.api.uri.UriBuilderImpl;
/**
* Tests behavior of {@code ListQueuesResponseHandlerr}

View File

@ -83,6 +83,7 @@ import com.google.common.util.concurrent.ListenableFuture;
@SkipEncoding('/')
@RequestFilters(SharedKeyLiteAuthentication.class)
@Headers(keys = AzureStorageHeaders.VERSION, values = "2009-09-19")
@Path("/")
public interface AzureBlobAsyncClient {
public org.jclouds.azure.storage.blob.domain.AzureBlob newBlob();
@ -92,7 +93,7 @@ public interface AzureBlobAsyncClient {
*/
@GET
@XMLResponseParser(AccountNameEnumerationResultsHandler.class)
@Path("/")
@Path("")
@QueryParams(keys = "comp", values = "list")
ListenableFuture<? extends BoundedSet<ContainerProperties>> listContainers(
ListOptions... listOptions);

View File

@ -88,14 +88,14 @@ public interface AzureQueueAsyncClient {
* @see AzureQueueClient#createQueue
*/
@PUT
@Path("{queue}")
@Path("/{queue}")
ListenableFuture<Boolean> createQueue(@PathParam("queue") String queue, CreateOptions... options);
/**
* @see AzureQueueClient#getMessages
*/
@GET
@Path("{queue}/messages")
@Path("/{queue}/messages")
@XMLResponseParser(QueueMessagesListHandler.class)
ListenableFuture<Set<QueueMessage>> getMessages(@PathParam("queue") String queue,
GetOptions... options);
@ -104,14 +104,14 @@ public interface AzureQueueAsyncClient {
* @see AzureQueueClient#deleteQueue
*/
@DELETE
@Path("{queue}")
@Path("/{queue}")
ListenableFuture<Void> deleteQueue(@PathParam("queue") String queue);
/**
* @see AzureQueueClient#putMessage
*/
@POST
@Path("{queue}/messages")
@Path("/{queue}/messages")
ListenableFuture<Void> putMessage(@PathParam("queue") String queue,
@BinderParam(BindToXmlStringPayload.class) String message, PutMessageOptions... options);
@ -119,6 +119,6 @@ public interface AzureQueueAsyncClient {
* @see AzureQueueClient#clearMessages
*/
@DELETE
@Path("{queue}/messages")
@Path("/{queue}/messages")
ListenableFuture<Void> clearMessages(@PathParam("queue") String queue);
}

View File

@ -140,7 +140,7 @@ public class AzureBlobAsyncClientTest extends RestClientTest<AzureBlobAsyncClien
HttpRequest request = processor.createRequest(method);
assertRequestLineEquals(request, "PUT https://identity.blob.core.windows.net/%24root?restype=container HTTP/1.1");
assertRequestLineEquals(request, "PUT https://identity.blob.core.windows.net/$root?restype=container HTTP/1.1");
assertNonPayloadHeadersEqual(request, "x-ms-version: 2009-09-19\n");
assertPayloadEquals(request, null, null, false);
@ -154,7 +154,7 @@ public class AzureBlobAsyncClientTest extends RestClientTest<AzureBlobAsyncClien
HttpRequest request = processor.createRequest(method);
assertRequestLineEquals(request,
"DELETE https://identity.blob.core.windows.net/%24root?restype=container HTTP/1.1");
"DELETE https://identity.blob.core.windows.net/$root?restype=container HTTP/1.1");
assertNonPayloadHeadersEqual(request, "x-ms-version: 2009-09-19\n");
assertPayloadEquals(request, null, null, false);
@ -168,7 +168,7 @@ public class AzureBlobAsyncClientTest extends RestClientTest<AzureBlobAsyncClien
HttpRequest request = processor.createRequest(method, withPublicAcl().withMetadata(
ImmutableMultimap.of("foo", "bar")));
assertRequestLineEquals(request, "PUT https://identity.blob.core.windows.net/%24root?restype=container HTTP/1.1");
assertRequestLineEquals(request, "PUT https://identity.blob.core.windows.net/$root?restype=container HTTP/1.1");
assertNonPayloadHeadersEqual(request,
"x-ms-meta-foo: bar\nx-ms-prop-publicaccess: true\nx-ms-version: 2009-09-19\n");
assertPayloadEquals(request, null, null, false);
@ -197,7 +197,7 @@ public class AzureBlobAsyncClientTest extends RestClientTest<AzureBlobAsyncClien
HttpRequest request = processor.createRequest(method);
assertRequestLineEquals(request,
"GET https://identity.blob.core.windows.net/%24root?restype=container&comp=list HTTP/1.1");
"GET https://identity.blob.core.windows.net/$root?restype=container&comp=list HTTP/1.1");
assertNonPayloadHeadersEqual(request, "x-ms-version: 2009-09-19\n");
assertPayloadEquals(request, null, null, false);

View File

@ -166,7 +166,7 @@ public class AzureBlobClientLiveTest {
}
}
ListBlobsResponse list = client.listBlobs();
assertEquals(list.getUrl(), URI.create(String.format("https://%s.blob.core.windows.net/%%24root", identity)));
assertEquals(list.getUrl(), URI.create(String.format("https://%s.blob.core.windows.net/$root", identity)));
}
@Test

View File

@ -87,26 +87,27 @@ public interface ChefAsyncClient {
* @see ChefClient#getUploadSandboxForChecksums
*/
@POST
@Path("sandboxes")
@Path("/sandboxes")
ListenableFuture<UploadSandbox> getUploadSandboxForChecksums(
@BinderParam(BindChecksumsToJsonPayload.class) Set<List<Byte>> md5s);
@BinderParam(BindChecksumsToJsonPayload.class) Set<List<Byte>> md5s);
@PUT
@Path("")
ListenableFuture<Void> uploadContent(@BinderParam(BindChecksumsToJsonPayload.class) Set<List<Byte>> md5s);
/**
* @see ChefClient#commitSandbox
*/
@PUT
@Path("sandboxes/{id}")
@Path("/sandboxes/{id}")
ListenableFuture<Sandbox> commitSandbox(@PathParam("id") String id,
@BinderParam(BindIsCompletedToJsonPayload.class) boolean isCompleted);
@BinderParam(BindIsCompletedToJsonPayload.class) boolean isCompleted);
/**
* @see ChefCookbooks#listCookbooks
*/
@GET
@Path("cookbooks")
@Path("/cookbooks")
@ResponseParser(ParseKeySetFromJson.class)
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
ListenableFuture<Set<String>> listCookbooks();
@ -115,24 +116,24 @@ public interface ChefAsyncClient {
* @see ChefClient#updateCookbook
*/
@PUT
@Path("cookbooks/{cookbookname}/{version}")
@Path("/cookbooks/{cookbookname}/{version}")
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)
*/
@DELETE
@Path("cookbooks/{cookbookname}/{version}")
@Path("/cookbooks/{cookbookname}/{version}")
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
ListenableFuture<CookbookVersion> deleteCookbook(@PathParam("cookbookname") String cookbookName,
@PathParam("version") String version);
@PathParam("version") String version);
/**
* @see ChefCookbook#getVersionsOfCookbook
*/
@GET
@Path("cookbooks/{cookbookname}")
@Path("/cookbooks/{cookbookname}")
@Unwrap
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
ListenableFuture<Set<String>> getVersionsOfCookbook(@PathParam("cookbookname") String cookbookName);
@ -141,31 +142,31 @@ public interface ChefAsyncClient {
* @see ChefCookbook#getCookbook
*/
@GET
@Path("cookbooks/{cookbookname}/{version}")
@Path("/cookbooks/{cookbookname}/{version}")
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
ListenableFuture<CookbookVersion> getCookbook(@PathParam("cookbookname") String cookbookName,
@PathParam("version") String version);
@PathParam("version") String version);
/**
* @see ChefClient#createClient
*/
@POST
@Path("clients")
@Path("/clients")
ListenableFuture<Client> createClient(@BinderParam(BindClientnameToJsonPayload.class) String clientname);
/**
* @see ChefClient#generateKeyForClient
*/
@PUT
@Path("clients/{clientname}")
@Path("/clients/{clientname}")
ListenableFuture<Client> generateKeyForClient(
@PathParam("clientname") @BinderParam(BindGenerateKeyForClientToJsonPayload.class) String clientname);
@PathParam("clientname") @BinderParam(BindGenerateKeyForClientToJsonPayload.class) String clientname);
/**
* @see ChefClient#clientExists
*/
@HEAD
@Path("clients/{clientname}")
@Path("/clients/{clientname}")
@ExceptionParser(ReturnFalseOnNotFoundOr404.class)
ListenableFuture<Boolean> clientExists(@PathParam("clientname") String clientname);
@ -173,7 +174,7 @@ public interface ChefAsyncClient {
* @see ChefClient#getClient
*/
@GET
@Path("clients/{clientname}")
@Path("/clients/{clientname}")
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
ListenableFuture<Client> getClient(@PathParam("clientname") String clientname);
@ -181,7 +182,7 @@ public interface ChefAsyncClient {
* @see ChefClient#deleteClient
*/
@DELETE
@Path("clients/{clientname}")
@Path("/clients/{clientname}")
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
ListenableFuture<Client> deleteClient(@PathParam("clientname") String clientname);
@ -189,7 +190,7 @@ public interface ChefAsyncClient {
* @see ChefClient#listClients
*/
@GET
@Path("clients")
@Path("/clients")
@ResponseParser(ParseKeySetFromJson.class)
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
ListenableFuture<Set<String>> listClients();
@ -198,22 +199,22 @@ public interface ChefAsyncClient {
* @see ChefClient#createNode
*/
@POST
@Path("nodes")
@Path("/nodes")
ListenableFuture<Void> createNode(@BinderParam(BindToJsonPayload.class) Node node);
/**
* @see ChefClient#updateNode
*/
@PUT
@Path("nodes/{nodename}")
@Path("/nodes/{nodename}")
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
*/
@HEAD
@Path("nodes/{nodename}")
@Path("/nodes/{nodename}")
@ExceptionParser(ReturnFalseOnNotFoundOr404.class)
ListenableFuture<Boolean> nodeExists(@PathParam("nodename") String nodename);
@ -221,7 +222,7 @@ public interface ChefAsyncClient {
* @see ChefNode#getNode
*/
@GET
@Path("nodes/{nodename}")
@Path("/nodes/{nodename}")
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
ListenableFuture<Node> getNode(@PathParam("nodename") String nodename);
@ -229,7 +230,7 @@ public interface ChefAsyncClient {
* @see ChefNode#deleteNode
*/
@DELETE
@Path("nodes/{nodename}")
@Path("/nodes/{nodename}")
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
ListenableFuture<Node> deleteNode(@PathParam("nodename") String nodename);
@ -237,7 +238,7 @@ public interface ChefAsyncClient {
* @see ChefNode#listNodes
*/
@GET
@Path("nodes")
@Path("/nodes")
@ResponseParser(ParseKeySetFromJson.class)
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
ListenableFuture<Set<String>> listNodes();
@ -246,22 +247,22 @@ public interface ChefAsyncClient {
* @see ChefClient#createRole
*/
@POST
@Path("roles")
@Path("/roles")
ListenableFuture<Void> createRole(@BinderParam(BindToJsonPayload.class) Role role);
/**
* @see ChefClient#updateRole
*/
@PUT
@Path("roles/{rolename}")
@Path("/roles/{rolename}")
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
*/
@HEAD
@Path("roles/{rolename}")
@Path("/roles/{rolename}")
@ExceptionParser(ReturnFalseOnNotFoundOr404.class)
ListenableFuture<Boolean> roleExists(@PathParam("rolename") String rolename);
@ -269,7 +270,7 @@ public interface ChefAsyncClient {
* @see ChefRole#getRole
*/
@GET
@Path("roles/{rolename}")
@Path("/roles/{rolename}")
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
ListenableFuture<Role> getRole(@PathParam("rolename") String rolename);
@ -277,7 +278,7 @@ public interface ChefAsyncClient {
* @see ChefRole#deleteRole
*/
@DELETE
@Path("roles/{rolename}")
@Path("/roles/{rolename}")
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
ListenableFuture<Role> deleteRole(@PathParam("rolename") String rolename);
@ -285,7 +286,7 @@ public interface ChefAsyncClient {
* @see ChefRole#listRoles
*/
@GET
@Path("roles")
@Path("/roles")
@ResponseParser(ParseKeySetFromJson.class)
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
ListenableFuture<Set<String>> listRoles();
@ -294,7 +295,7 @@ public interface ChefAsyncClient {
* @see ChefClient#listDatabags
*/
@GET
@Path("data")
@Path("/data")
@ResponseParser(ParseKeySetFromJson.class)
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
ListenableFuture<Set<String>> listDatabags();
@ -303,14 +304,14 @@ public interface ChefAsyncClient {
* @see ChefClient#createDatabag
*/
@POST
@Path("data")
@Path("/data")
ListenableFuture<Void> createDatabag(@BinderParam(BindNameToJsonPayload.class) String databagName);
/**
* @see ChefClient#databagExists
*/
@HEAD
@Path("data/{name}")
@Path("/data/{name}")
@ExceptionParser(ReturnFalseOnNotFoundOr404.class)
ListenableFuture<Boolean> databagExists(@PathParam("name") String databagName);
@ -318,7 +319,7 @@ public interface ChefAsyncClient {
* @see ChefClient#deleteDatabag
*/
@DELETE
@Path("data/{name}")
@Path("/data/{name}")
@ExceptionParser(ReturnVoidOnNotFoundOr404.class)
ListenableFuture<Void> deleteDatabag(@PathParam("name") String databagName);
@ -326,7 +327,7 @@ public interface ChefAsyncClient {
* @see ChefClient#listDatabagItems
*/
@GET
@Path("data/{name}")
@Path("/data/{name}")
@ResponseParser(ParseKeySetFromJson.class)
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
ListenableFuture<Set<String>> listDatabagItems(@PathParam("name") String databagName);
@ -335,51 +336,51 @@ public interface ChefAsyncClient {
* @see ChefClient#createDatabagItem
*/
@POST
@Path("data/{databagName}")
@Path("/data/{databagName}")
ListenableFuture<DatabagItem> createDatabagItem(@PathParam("databagName") String databagName,
@BinderParam(BindToJsonPayload.class) DatabagItem databagItem);
@BinderParam(BindToJsonPayload.class) DatabagItem databagItem);
/**
* @see ChefClient#updateDatabagItem
*/
@PUT
@Path("data/{databagName}/{databagItemId}")
@Path("/data/{databagName}/{databagItemId}")
ListenableFuture<DatabagItem> updateDatabagItem(
@PathParam("databagName") String databagName,
@PathParam("databagItemId") @ParamParser(DatabagItemId.class) @BinderParam(BindToJsonPayload.class) DatabagItem item);
@PathParam("databagName") String databagName,
@PathParam("databagItemId") @ParamParser(DatabagItemId.class) @BinderParam(BindToJsonPayload.class) DatabagItem item);
/**
* @see ChefClient#databagItemExists
*/
@HEAD
@Path("data/{databagName}/{databagItemId}")
@Path("/data/{databagName}/{databagItemId}")
@ExceptionParser(ReturnFalseOnNotFoundOr404.class)
ListenableFuture<Boolean> databagItemExists(@PathParam("databagName") String databagName,
@PathParam("databagItemId") String databagItemId);
@PathParam("databagItemId") String databagItemId);
/**
* @see ChefClient#getDatabagItem
*/
@GET
@Path("data/{databagName}/{databagItemId}")
@Path("/data/{databagName}/{databagItemId}")
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
ListenableFuture<DatabagItem> getDatabagItem(@PathParam("databagName") String databagName,
@PathParam("databagItemId") String databagItemId);
@PathParam("databagItemId") String databagItemId);
/**
* @see ChefClient#deleteDatabagItem
*/
@DELETE
@Path("data/{databagName}/{databagItemId}")
@Path("/data/{databagName}/{databagItemId}")
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
ListenableFuture<DatabagItem> deleteDatabagItem(@PathParam("databagName") String databagName,
@PathParam("databagItemId") String databagItemId);
@PathParam("databagItemId") String databagItemId);
/**
* @see ChefClient#listSearchIndexes
*/
@GET
@Path("search")
@Path("/search")
@ResponseParser(ParseKeySetFromJson.class)
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
ListenableFuture<Set<String>> listSearchIndexes();
@ -388,7 +389,7 @@ public interface ChefAsyncClient {
* @see ChefClient#searchRoles
*/
@GET
@Path("search/role")
@Path("/search/role")
@ResponseParser(ParseSearchRolesFromJson.class)
ListenableFuture<? extends SearchResult<? extends Role>> searchRoles();
@ -396,7 +397,7 @@ public interface ChefAsyncClient {
* @see ChefClient#searchClients
*/
@GET
@Path("search/client")
@Path("/search/client")
@ResponseParser(ParseSearchClientsFromJson.class)
ListenableFuture<? extends SearchResult<? extends Client>> searchClients();
@ -404,7 +405,7 @@ public interface ChefAsyncClient {
* @see ChefClient#searchNodes
*/
@GET
@Path("search/node")
@Path("/search/node")
@ResponseParser(ParseSearchNodesFromJson.class)
ListenableFuture<? extends SearchResult<? extends Node>> searchNodes();
@ -412,8 +413,8 @@ public interface ChefAsyncClient {
* @see ChefClient#searchDatabag
*/
@GET
@Path("search/{databagName}")
@Path("/search/{databagName}")
@ResponseParser(ParseSearchDatabagFromJson.class)
ListenableFuture<? extends SearchResult<? extends DatabagItem>> searchDatabag(
@PathParam("databagName") String databagName);
@PathParam("databagName") String databagName);
}

View File

@ -1,24 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
<!--
Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
Copyright (C) 2010 Cloud Conscious, LLC.
<info@cloudconscious.com>
====================================================================
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
====================================================================
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
====================================================================
-->
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.
====================================================================
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
@ -41,23 +40,27 @@
</scm>
<repositories>
<repository>
<id>jersey</id>
<url>http://download.java.net/maven/2</url>
</repository>
<repository>
<id>gson</id>
<url>http://google-gson.googlecode.com/svn/mavenrepo</url>
</repository>
<repository>
<id>oauth</id>
<name>OAuth Repository</name>
<url>http://oauth.googlecode.com/svn/code/maven</url>
</repository>
<repository>
<id>oauth</id>
<name>OAuth Repository</name>
<url>http://oauth.googlecode.com/svn/code/maven</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>net.oauth.core</groupId>
<artifactId>oauth</artifactId>
<version>20100527</version>
</dependency>
<dependency>
<groupId>net.oauth.core</groupId>
<artifactId>oauth</artifactId>
<version>20100527</version>
</dependency>
<!-- only required for Pems.java and only writing a private key file -->
<dependency>
<groupId>org.bouncycastle</groupId>
@ -71,9 +74,9 @@
<version>1.0</version>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jaxrs-client</artifactId>
<version>1.2.1.GA-SNAPSHOT</version>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-core</artifactId>
<version>1.4-ea06</version>
</dependency>
<dependency>
<groupId>com.google.code.guice</groupId>
@ -137,6 +140,6 @@
</plugin>
</plugins>
</build>
</profile>
</profile>
</profiles>
</project>

View File

@ -27,6 +27,7 @@ import javax.ws.rs.GET;
import javax.ws.rs.HEAD;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import org.jclouds.http.functions.ParseETagHeader;
import org.jclouds.http.options.HttpRequestOptions;
@ -49,30 +50,33 @@ public interface HttpAsyncClient {
* @see HttpClient#post
*/
@PUT
@Path("")
@ResponseParser(ParseETagHeader.class)
ListenableFuture<String> put(@EndpointParam URI location, Payload payload);
@PUT
@Path("")
@ResponseParser(ParseETagHeader.class)
ListenableFuture<String> put(@EndpointParam URI location, Payload payload,
HttpRequestOptions options);
ListenableFuture<String> put(@EndpointParam URI location, Payload payload, HttpRequestOptions options);
/**
* @see HttpClient#post
*/
@POST
@Path("")
@ResponseParser(ParseETagHeader.class)
ListenableFuture<String> post(@EndpointParam URI location, Payload payload);
@POST
@Path("")
@ResponseParser(ParseETagHeader.class)
ListenableFuture<String> post(@EndpointParam URI location, Payload payload,
HttpRequestOptions options);
ListenableFuture<String> post(@EndpointParam URI location, Payload payload, HttpRequestOptions options);
/**
* @see HttpClient#exists
*/
@HEAD
@Path("")
@ExceptionParser(ReturnFalseOnNotFoundOr404.class)
ListenableFuture<Boolean> exists(@EndpointParam URI location);
@ -80,10 +84,12 @@ public interface HttpAsyncClient {
* @see HttpClient#get
*/
@GET
@Path("")
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
ListenableFuture<InputStream> get(@EndpointParam URI location);
@GET
@Path("")
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
ListenableFuture<InputStream> get(@EndpointParam URI location, HttpRequestOptions options);
@ -91,6 +97,7 @@ public interface HttpAsyncClient {
* @see HttpClient#delete
*/
@DELETE
@Path("")
@ExceptionParser(ReturnFalseOnNotFoundOr404.class)
ListenableFuture<Boolean> delete(@EndpointParam URI location);

View File

@ -25,7 +25,6 @@ import javax.inject.Named;
import javax.inject.Singleton;
import javax.ws.rs.core.UriBuilder;
import org.jboss.resteasy.specimpl.UriBuilderImpl;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.HttpResponse;
import org.jclouds.http.TransformingHttpCommand;
@ -52,6 +51,7 @@ import com.google.inject.Scopes;
import com.google.inject.TypeLiteral;
import com.google.inject.name.Names;
import com.google.inject.util.Types;
import com.sun.jersey.api.uri.UriBuilderImpl;
/**
*

View File

@ -67,6 +67,7 @@ import javax.inject.Provider;
import javax.ws.rs.Consumes;
import javax.ws.rs.FormParam;
import javax.ws.rs.HeaderParam;
import javax.ws.rs.HttpMethod;
import javax.ws.rs.MatrixParam;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
@ -76,7 +77,6 @@ import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.UriBuilder;
import javax.ws.rs.core.UriBuilderException;
import org.jboss.resteasy.util.IsHttpMethod;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.HttpRequestFilter;
import org.jclouds.http.HttpResponse;
@ -408,9 +408,6 @@ public class RestAnnotationProcessor<T> {
Multimap<String, String> tokenValues = LinkedHashMultimap.create();
if (caller != null) {
builder.path(getPath(caller.getMethod().getDeclaringClass(), caller.getMethod(), caller.getArgs()));
}
tokenValues.putAll(addPathAndGetTokens(declaring, method, args, builder));
Multimap<String, String> formParams = addFormParams(tokenValues.entries(), method, args);
@ -483,15 +480,6 @@ public class RestAnnotationProcessor<T> {
public static final String BOUNDARY = "--JCLOUDS--";
private String getPath(Class<?> clazz, Method method, Object[] args) {
UriBuilder builder = uriBuilderProvider.get();
if (clazz.isAnnotationPresent(Path.class))
builder.path(clazz);
builder.path(method);
return builder.buildFromEncodedMap(convertUnsafe(encodeValues(getPathParamKeyValues(method, args), skips)))
.getPath();
}
private Multimap<String, String> addPathAndGetTokens(Class<?> clazz, Method method, Object[] args, UriBuilder builder) {
if (clazz.isAnnotationPresent(Path.class))
builder.path(clazz);
@ -787,7 +775,7 @@ public class RestAnnotationProcessor<T> {
private Multimap<String, String> constants = LinkedHashMultimap.create();
public boolean isHttpMethod(Method method) {
return method.isAnnotationPresent(Path.class) || IsHttpMethod.getHttpMethods(method) != null;
return method.isAnnotationPresent(Path.class) || getHttpMethods(method) != null;
}
public boolean isConstantDeclaration(Method method) {
@ -800,8 +788,20 @@ public class RestAnnotationProcessor<T> {
constants.put(key, value);
}
public static Set<String> getHttpMethods(Method method) {
HashSet<String> methods = new HashSet<String>();
for (Annotation annotation : method.getAnnotations()) {
HttpMethod http = annotation.annotationType().getAnnotation(HttpMethod.class);
if (http != null)
methods.add(http.value());
}
if (methods.size() == 0)
return null;
return methods;
}
public String getHttpMethodOrConstantOrThrowException(Method method) {
Set<String> requests = IsHttpMethod.getHttpMethods(method);
Set<String> requests = getHttpMethods(method);
if (requests == null || requests.size() != 1) {
throw new IllegalStateException(
"You must use at least one, but no more than one http method or pathparam annotation on: "

View File

@ -65,23 +65,23 @@ public interface IntegrationTestAsyncClient {
}
@ROWDY
@Path("objects/{id}")
@Path("/objects/{id}")
ListenableFuture<String> rowdy(@PathParam("id") String path);
@HEAD
@Path("objects/{id}")
@Path("/objects/{id}")
ListenableFuture<Boolean> exists(@PathParam("id") String path);
@GET
@Path("objects/{id}")
@Path("/objects/{id}")
ListenableFuture<String> download(@PathParam("id") String id);
@GET
@Path("{path}")
@Path("/{path}")
ListenableFuture<String> synch(@PathParam("path") String id);
@GET
@Path("objects/{id}")
@Path("/objects/{id}")
@ExceptionParser(FooOnException.class)
ListenableFuture<String> downloadException(@PathParam("id") String id, HttpRequestOptions options);
@ -94,20 +94,20 @@ public interface IntegrationTestAsyncClient {
}
@GET
@Path("objects/{id}")
@Path("/objects/{id}")
@ExceptionParser(FooOnException.class)
ListenableFuture<String> synchException(@PathParam("id") String id, @HeaderParam("Range") String header);
@PUT
@Path("objects/{id}")
@Path("/objects/{id}")
ListenableFuture<String> upload(@PathParam("id") String id, @BinderParam(BindToStringPayload.class) String toPut);
@POST
@Path("objects/{id}")
@Path("/objects/{id}")
ListenableFuture<String> post(@PathParam("id") String id, @BinderParam(BindToStringPayload.class) String toPut);
@POST
@Path("objects/{id}")
@Path("/objects/{id}")
ListenableFuture<String> postAsInputStream(@PathParam("id") String id,
@BinderParam(BindToInputStreamPayload.class) String toPut);
@ -121,7 +121,7 @@ public interface IntegrationTestAsyncClient {
}
@POST
@Path("objects/{id}")
@Path("/objects/{id}")
ListenableFuture<String> postWithMd5(@PathParam("id") String id, @HeaderParam("Content-MD5") String base64MD5,
@BinderParam(BindToFilePayload.class) File file);
@ -134,17 +134,17 @@ public interface IntegrationTestAsyncClient {
}
@POST
@Path("objects/{id}")
@Path("/objects/{id}")
@MapBinder(BindToJsonPayload.class)
ListenableFuture<String> postJson(@PathParam("id") String id, @MapPayloadParam("key") String toPut);
@POST
@Path("objects/{id}/action/{action}")
@Path("/objects/{id}/action/{action}")
ListenableFuture<String> action(@PathParam("id") String id, @PathParam("action") String action,
@BinderParam(BindMapToMatrixParams.class) Map<String, String> options);
@GET
@Path("objects/{id}")
@Path("/objects/{id}")
@RequestFilters(Filter.class)
ListenableFuture<String> downloadFilter(@PathParam("id") String id, @HeaderParam("filterme") String header);
@ -157,11 +157,11 @@ public interface IntegrationTestAsyncClient {
}
@GET
@Path("objects/{id}")
@Path("/objects/{id}")
ListenableFuture<String> download(@PathParam("id") String id, @HeaderParam("test") String header);
@GET
@Path("objects/{id}")
@Path("/objects/{id}")
@XMLResponseParser(BarHandler.class)
ListenableFuture<String> downloadAndParse(@PathParam("id") String id);

View File

@ -33,7 +33,6 @@ import java.util.concurrent.TimeoutException;
import javax.inject.Provider;
import javax.ws.rs.core.UriBuilder;
import org.jboss.resteasy.specimpl.UriBuilderImpl;
import org.jclouds.http.HttpResponse;
import org.jclouds.io.Payload;
import org.jclouds.rest.internal.GeneratedHttpRequest;
@ -42,6 +41,7 @@ import org.mortbay.jetty.HttpHeaders;
import org.testng.annotations.Test;
import com.google.common.base.Function;
import com.sun.jersey.api.uri.UriBuilderImpl;
@Test(groups = { "unit" })
public class ParseURIFromListOrLocationHeaderIf20xTest {

View File

@ -35,7 +35,6 @@ import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.ws.rs.core.UriBuilder;
import org.jboss.resteasy.specimpl.UriBuilderImpl;
import org.jclouds.http.BaseJettyTest;
import org.jclouds.http.HttpCommand;
import org.jclouds.http.HttpResponse;
@ -54,6 +53,7 @@ import org.testng.annotations.Test;
import com.google.common.base.Supplier;
import com.google.inject.Key;
import com.google.inject.TypeLiteral;
import com.sun.jersey.api.uri.UriBuilderImpl;
@Test(groups = "unit", testName = "core.BackoffLimitedRetryHandler")
public class BackoffLimitedRetryHandlerTest {

View File

@ -26,6 +26,7 @@ import java.lang.reflect.Method;
import java.util.concurrent.TimeUnit;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import org.jclouds.concurrent.Timeout;
@ -52,12 +53,13 @@ public class InputParamValidatorTest {
@SkipEncoding('/')
class InputParamValidatorForm {
@POST
@Path("")
@ParamValidators( { AllLowerCaseValidator.class })
public void allParamsValidated(@PathParam("param1") String param1,
@PathParam("param2") String param2) {
public void allParamsValidated(@PathParam("param1") String param1, @PathParam("param2") String param2) {
}
@POST
@Path("")
public void oneParamValidated(@PathParam("param1") String param1,
@ParamValidators( { AllLowerCaseValidator.class }) @PathParam("param2") String param2) {
}
@ -72,10 +74,10 @@ public class InputParamValidatorTest {
*/
@Test
public void testInputParamsValidation() throws Exception {
Method allParamsValidatedMethod = InputParamValidatorForm.class.getMethod(
"allParamsValidated", String.class, String.class);
Method oneParamValidatedMethod = InputParamValidatorForm.class.getMethod("oneParamValidated",
String.class, String.class);
Method allParamsValidatedMethod = InputParamValidatorForm.class.getMethod("allParamsValidated", String.class,
String.class);
Method oneParamValidatedMethod = InputParamValidatorForm.class.getMethod("oneParamValidated", String.class,
String.class);
RestAnnotationProcessor<InputParamValidatorForm> restAnnotationProcessor = factory(InputParamValidatorForm.class);
restAnnotationProcessor.createRequest(allParamsValidatedMethod, "blah", "blah");
restAnnotationProcessor.createRequest(oneParamValidatedMethod, "blah", "blah");
@ -134,8 +136,8 @@ public class InputParamValidatorTest {
@SuppressWarnings("unchecked")
private <T> RestAnnotationProcessor<T> factory(Class<T> clazz) {
return ((RestAnnotationProcessor<T>) injector.getInstance(Key.get(TypeLiteral.get(Types
.newParameterizedType(RestAnnotationProcessor.class, clazz)))));
return ((RestAnnotationProcessor<T>) injector.getInstance(Key.get(TypeLiteral.get(Types.newParameterizedType(
RestAnnotationProcessor.class, clazz)))));
}
Injector injector;
@ -143,8 +145,8 @@ public class InputParamValidatorTest {
@BeforeClass
void setupFactory() {
ContextSpec<IntegrationTestClient, IntegrationTestAsyncClient> contextSpec = contextSpec(
"test", "http://localhost:9999", "1", "userFoo", null, IntegrationTestClient.class,
ContextSpec<IntegrationTestClient, IntegrationTestAsyncClient> contextSpec = contextSpec("test",
"http://localhost:9999", "1", "userFoo", null, IntegrationTestClient.class,
IntegrationTestAsyncClient.class);
injector = createContextBuilder(contextSpec).buildInjector();

View File

@ -31,12 +31,12 @@ import javax.inject.Provider;
import javax.ws.rs.HttpMethod;
import javax.ws.rs.core.UriBuilder;
import org.jboss.resteasy.specimpl.UriBuilderImpl;
import org.jclouds.http.HttpRequest;
import org.jclouds.rest.internal.GeneratedHttpRequest;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableMap;
import com.sun.jersey.api.uri.UriBuilderImpl;
/**
* Tests behavior of {@code BindMapToMatrixParams}

View File

@ -78,7 +78,6 @@ import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.UriBuilder;
import org.easymock.IArgumentMatcher;
import org.jboss.resteasy.specimpl.UriBuilderImpl;
import org.jclouds.concurrent.Timeout;
import org.jclouds.crypto.Crypto;
import org.jclouds.date.DateService;
@ -106,7 +105,6 @@ import org.jclouds.http.options.HttpRequestOptions;
import org.jclouds.io.Payload;
import org.jclouds.io.PayloadEnclosing;
import org.jclouds.logging.config.NullLoggingModule;
import org.jclouds.rest.AsyncClientFactory;
import org.jclouds.rest.BaseRestClientTest;
import org.jclouds.rest.ConfiguresRestClient;
import org.jclouds.rest.InvocationContext;
@ -155,6 +153,7 @@ import com.google.inject.ConfigurationException;
import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.inject.Module;
import com.sun.jersey.api.uri.UriBuilderImpl;
/**
* Tests behavior of {@code RestAnnotationProcessorTest}
@ -180,10 +179,10 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest {
}
@Path("client")
@Path("/client")
public static interface AsyncCallee {
@GET
@Path("{path}")
@Path("/{path}")
ListenableFuture<Void> onePath(@PathParam("path") String path);
}
@ -191,10 +190,6 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest {
@Timeout(duration = 10, timeUnit = TimeUnit.NANOSECONDS)
public static interface Caller {
@Delegate
@Path("{path}")
public Callee getCallee(@PathParam("path") String path);
@Delegate
public Callee getCallee();
}
@ -207,10 +202,6 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest {
public static interface AsyncCaller {
@Delegate
@Path("{path}")
public AsyncCallee getCallee(@PathParam("path") String path);
@Delegate
public AsyncCallee getCallee();
}
@ -231,13 +222,10 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest {
}
AsyncCaller caller = child.getInstance(AsyncCaller.class);
expect(mock.submit(requestLineEquals("GET http://localhost:9999/goo/client/foo HTTP/1.1"), eq(function)))
.andReturn(createNiceMock(ListenableFuture.class)).atLeastOnce();
expect(mock.submit(requestLineEquals("GET http://localhost:9999/client/foo HTTP/1.1"), eq(function))).andReturn(
createNiceMock(ListenableFuture.class)).atLeastOnce();
replay(mock);
caller.getCallee("goo").onePath("foo");
caller.getCallee().onePath("foo");
verify(mock);
@ -278,14 +266,10 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest {
}
Caller caller = child.getInstance(Caller.class);
expect(mock.submit(requestLineEquals("GET http://localhost:1111/goo/client/foo HTTP/1.1"), eq(function)))
.andReturn(Futures.<Void> immediateFuture(null)).atLeastOnce();
expect(mock.submit(requestLineEquals("GET http://localhost:1111/client/foo HTTP/1.1"), eq(function))).andReturn(
Futures.<Void> immediateFuture(null)).atLeastOnce();
replay(mock);
caller.getCallee("goo").onePath("foo");
caller.getCallee().onePath("foo");
verify(mock);
@ -302,47 +286,6 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest {
}
@Path("caller")
public static interface CallerWithPathOnClass {
@Delegate
@Path("{path}")
public AsyncCallee getCallee(@PathParam("path") String path);
@Delegate
public AsyncCallee getCallee();
}
@SuppressWarnings("unchecked")
public void testDelegateWithPathOnClass() throws SecurityException, NoSuchMethodException, InterruptedException,
ExecutionException {
Injector child = injectorForClient();
TransformingHttpCommandExecutorService mock = child.getInstance(TransformingHttpCommandExecutorService.class);
ReleasePayloadAndReturn function = child.getInstance(ReleasePayloadAndReturn.class);
AsyncClientFactory factory = child.getInstance(AsyncClientFactory.class);
try {
child.getInstance(AsyncCallee.class);
assert false : "Callee shouldn't be bound yet";
} catch (ConfigurationException e) {
}
CallerWithPathOnClass caller = factory.create(CallerWithPathOnClass.class);
expect(mock.submit(requestLineEquals("GET http://localhost:9999/caller/goo/client/foo HTTP/1.1"), eq(function)))
.andReturn(createNiceMock(ListenableFuture.class)).atLeastOnce();
expect(mock.submit(requestLineEquals("GET http://localhost:9999/caller/client/foo HTTP/1.1"), eq(function)))
.andReturn(createNiceMock(ListenableFuture.class)).atLeastOnce();
replay(mock);
caller.getCallee("goo").onePath("foo");
caller.getCallee().onePath("foo");
verify(mock);
}
Provider<UriBuilder> uriBuilderProvider = new Provider<UriBuilder>() {
@Override
@ -367,16 +310,19 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest {
@QueryParams(keys = "x-ms-version", values = "2009-07-17")
public class TestQuery {
@FOO
@Path("/")
@QueryParams(keys = "x-ms-rubbish", values = "bin")
public void foo() {
}
@FOO
@Path("/")
@QueryParams(keys = { "foo", "fooble" }, values = { "bar", "baz" })
public void foo2() {
}
@FOO
@Path("/")
@QueryParams(keys = { "foo", "fooble" }, values = { "bar", "baz" })
public void foo3(@QueryParam("robbie") String robbie) {
}
@ -396,7 +342,7 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest {
Method method = TestQuery.class.getMethod("foo");
HttpRequest request = factory(TestQuery.class).createRequest(method, new Object[] {});
assertEquals(request.getEndpoint().getHost(), "localhost");
assertEquals(request.getEndpoint().getPath(), "");
assertEquals(request.getEndpoint().getPath(), "/");
assertEquals(request.getEndpoint().getQuery(), "x-ms-version=2009-07-17&x-ms-rubbish=bin");
assertEquals(request.getMethod(), "FOO");
}
@ -405,7 +351,7 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest {
Method method = TestQuery.class.getMethod("foo2");
HttpRequest request = factory(TestQuery.class).createRequest(method, new Object[] {});
assertEquals(request.getEndpoint().getHost(), "localhost");
assertEquals(request.getEndpoint().getPath(), "");
assertEquals(request.getEndpoint().getPath(), "/");
assertEquals(request.getEndpoint().getQuery(), "x-ms-version=2009-07-17&foo=bar&fooble=baz");
assertEquals(request.getMethod(), "FOO");
}
@ -414,16 +360,18 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest {
Method method = TestQuery.class.getMethod("foo3", String.class);
HttpRequest request = factory(TestQuery.class).createRequest(method, new Object[] { "wonder" });
assertEquals(request.getEndpoint().getHost(), "localhost");
assertEquals(request.getEndpoint().getPath(), "");
assertEquals(request.getEndpoint().getPath(), "/");
assertEquals(request.getEndpoint().getQuery(), "x-ms-version=2009-07-17&foo=bar&fooble=baz&robbie=wonder");
assertEquals(request.getMethod(), "FOO");
}
public interface TestPayloadParamVarargs {
@POST
@Path("")
public void varargs(HttpRequestOptions... options);
@POST
@Path("")
public void post(HttpRequestOptions options);
}
@ -474,6 +422,7 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest {
public class TestCustomMethod {
@FOO
@Path("")
public void foo() {
}
}
@ -492,6 +441,7 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest {
public class TestOverridden implements Parent {
@POST
@Path("")
public void foo() {
}
}
@ -508,10 +458,12 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest {
@POST
@Endpoint(Localhost2.class)
@Path("")
public void foo() {
}
@POST
@Path("")
public void foo(@EndpointParam URI endpoint) {
}
}
@ -537,22 +489,24 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest {
public interface TestPost {
@POST
@Path("")
void post(@Nullable @BinderParam(BindToStringPayload.class) String content);
@POST
@Path("")
public void postAsJson(@BinderParam(BindToJsonPayload.class) String content);
@POST
@Path("{foo}")
@Path("/{foo}")
public void postWithPath(@PathParam("foo") @MapPayloadParam("fooble") String path, MapBinder content);
@POST
@Path("{foo}")
@Path("/{foo}")
@MapBinder(BindToJsonPayload.class)
public void postWithMethodBinder(@PathParam("foo") @MapPayloadParam("fooble") String path);
@POST
@Path("{foo}")
@Path("/{foo}")
@MapPayloadParams(keys = "rat", values = "atat")
@MapBinder(BindToJsonPayload.class)
public void postWithMethodBinderAndDefaults(@PathParam("foo") @MapPayloadParam("fooble") String path);
@ -620,19 +574,24 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest {
static interface TestMultipartForm {
@POST
@Path("")
void withStringPart(@PartParam(name = "fooble") String path);
@POST
@Path("")
void withParamStringPart(@FormParam("name") String name, @PartParam(name = "file") String path);
@POST
@Path("")
void withParamFilePart(@FormParam("name") String name, @PartParam(name = "file") File path);
@POST
@Path("")
void withParamFileBinaryPart(@FormParam("name") String name,
@PartParam(name = "file", contentType = MediaType.APPLICATION_OCTET_STREAM) File path);
@POST
@Path("")
void withParamByteArrayBinaryPart(
@FormParam("name") String name,
@PartParam(name = "file", contentType = MediaType.APPLICATION_OCTET_STREAM, filename = "{name}.tar.gz") byte[] content);
@ -736,49 +695,56 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest {
public interface TestPut {
@PUT
@Path("{foo}")
@Path("/{foo}")
@MapBinder(BindToJsonPayload.class)
void putWithMethodBinder(@PathParam("foo") @MapPayloadParam("fooble") String path);
@PUT
@Path("{foo}")
@Path("/{foo}")
@Produces(MediaType.TEXT_PLAIN)
void putWithMethodBinderProduces(@PathParam("foo") @BinderParam(BindToStringPayload.class) String path);
@PUT
@Path("{foo}")
@Path("/{foo}")
@MapBinder(BindToJsonPayload.class)
@Consumes(MediaType.APPLICATION_JSON)
Wrapper putWithMethodBinderConsumes(@PathParam("foo") @MapPayloadParam("fooble") String path);
@GET
@Path("/")
@Consumes(MediaType.APPLICATION_JSON)
Map<String, String> testGeneric();
@GET
@Path("/")
@Consumes(MediaType.APPLICATION_JSON)
ListenableFuture<Map<String, String>> testGeneric2();
@GET
@Path("/")
@Consumes(MediaType.APPLICATION_JSON)
ListenableFuture<? extends Map<String, String>> testGeneric3();
@GET
@Path("/")
@Unwrap
@Consumes(MediaType.APPLICATION_JSON)
String testUnwrap();
@GET
@Path("/")
@Unwrap
@Consumes(MediaType.APPLICATION_JSON)
ListenableFuture<String> testUnwrap2();
@GET
@Path("/")
@Unwrap
@Consumes(MediaType.APPLICATION_JSON)
ListenableFuture<Set<String>> testUnwrap3();
@GET
@Path("/")
@Unwrap
@Consumes(MediaType.APPLICATION_JSON)
ListenableFuture<? extends Set<String>> testUnwrap4();
@ -790,7 +756,7 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest {
}
@ROWDY
@Path("objects/{id}")
@Path("/objects/{id}")
ListenableFuture<Boolean> rowdy(@PathParam("id") String path);
}
@ -965,11 +931,13 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest {
@RequestFilters(TestRequestFilter1.class)
static class TestRequestFilter {
@GET
@Path("")
@RequestFilters(TestRequestFilter2.class)
public void get() {
}
@GET
@Path("")
@OverrideRequestFilters
@RequestFilters(TestRequestFilter2.class)
public void getOverride() {
@ -995,7 +963,7 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest {
@SkipEncoding('/')
public class TestEncoding {
@GET
@Path("{path1}/{path2}")
@Path("/{path1}/{path2}")
public void twoPaths(@PathParam("path1") String path, @PathParam("path2") String path2) {
}
}
@ -1026,7 +994,7 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest {
void setUsername();
@GET
@Path("{path1}/{path2}")
@Path("/{path1}/{path2}")
public void twoPaths(@PathParam("path1") String path, @PathParam("path2") String path2);
}
@ -1042,22 +1010,22 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest {
public class TestPath {
@GET
@Path("{path}")
@Path("/{path}")
public void onePath(@PathParam("path") String path) {
}
@GET
@Path("{path1}/{path2}")
@Path("/{path1}/{path2}")
public void twoPaths(@PathParam("path1") String path, @PathParam("path2") String path2) {
}
@GET
@Path("{path2}/{path1}")
@Path("/{path2}/{path1}")
public void twoPathsOutOfOrder(@PathParam("path1") String path, @PathParam("path2") String path2) {
}
@GET
@Path("{path}")
@Path("/{path}")
public void onePathParamExtractor(@PathParam("path") @ParamParser(FirstCharacter.class) String path) {
}
@ -1077,7 +1045,7 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest {
}
@GET
@Path("{path}")
@Path("/{path}")
@PathParam("path")
@ParamParser(FirstCharacterFirstElement.class)
public void onePathParamExtractorMethod(String path) {
@ -1143,21 +1111,25 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest {
public class TestHeader {
@GET
@Path("/")
@Headers(keys = "x-amz-copy-source", values = "/{bucket}")
public void oneHeader(@PathParam("bucket") String path) {
}
@GET
@Path("/")
@Headers(keys = { "slash", "hyphen" }, values = { "/{bucket}", "-{bucket}" })
public void twoHeader(@PathParam("bucket") String path) {
}
@GET
@Path("/")
@Headers(keys = "x-amz-copy-source", values = "/{bucket}/{key}")
public void twoHeaders(@PathParam("bucket") String path, @PathParam("key") String path2) {
}
@GET
@Path("/")
@Headers(keys = "x-amz-copy-source", values = "/{bucket}/{key}")
public void twoHeadersOutOfOrder(@PathParam("key") String path, @PathParam("bucket") String path2) {
}
@ -1176,6 +1148,7 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest {
@Headers(keys = "x-amz-copy-source", values = "/{bucket}")
public class TestClassHeader {
@GET
@Path("/")
public void oneHeader(@PathParam("bucket") String path) {
}
}
@ -1233,7 +1206,7 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest {
private interface TestMapMatrixParams {
@POST
@Path("objects/{id}/action/{action}")
@Path("/objects/{id}/action/{action}")
ListenableFuture<String> action(@PathParam("id") String id, @PathParam("action") String action,
@BinderParam(BindMapToMatrixParams.class) Map<String, String> options);
}
@ -1250,25 +1223,30 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest {
public class TestQueryReplace {
@GET
@Path("/")
public void queryInOptions(@PathParam("bucket") String path, TestReplaceQueryOptions options) {
}
@GET
@Path("/")
@QueryParams(keys = "x-amz-copy-source", values = "/{bucket}")
public void oneQuery(@PathParam("bucket") String path) {
}
@GET
@Path("/")
@QueryParams(keys = { "slash", "hyphen" }, values = { "/{bucket}", "-{bucket}" })
public void twoQuery(@PathParam("bucket") String path) {
}
@GET
@Path("/")
@QueryParams(keys = "x-amz-copy-source", values = "/{bucket}/{key}")
public void twoQuerys(@PathParam("bucket") String path, @PathParam("key") String path2) {
}
@GET
@Path("/")
@QueryParams(keys = "x-amz-copy-source", values = "/{bucket}/{key}")
public void twoQuerysOutOfOrder(@PathParam("key") String path, @PathParam("bucket") String path2) {
}
@ -1285,6 +1263,7 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest {
@QueryParams(keys = "x-amz-copy-source", values = "/{bucket}")
public class TestClassQuery {
@GET
@Path("/")
public void oneQuery(@PathParam("bucket") String path) {
}
}
@ -1341,25 +1320,30 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest {
public class TestMatrixReplace {
@GET
@Path("/")
public void matrixInOptions(@PathParam("bucket") String path, TestReplaceMatrixOptions options) {
}
@GET
@Path("/")
@MatrixParams(keys = "x-amz-copy-source", values = "/{bucket}")
public void oneMatrix(@PathParam("bucket") String path) {
}
@GET
@Path("/")
@MatrixParams(keys = { "slash", "hyphen" }, values = { "/{bucket}", "-{bucket}" })
public void twoMatrix(@PathParam("bucket") String path) {
}
@GET
@Path("/")
@MatrixParams(keys = "x-amz-copy-source", values = "/{bucket}/{key}")
public void twoMatrixs(@PathParam("bucket") String path, @PathParam("key") String path2) {
}
@GET
@Path("/")
@MatrixParams(keys = "x-amz-copy-source", values = "/{bucket}/{key}")
public void twoMatrixsOutOfOrder(@PathParam("key") String path, @PathParam("bucket") String path2) {
}
@ -1377,6 +1361,7 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest {
@Path("/")
public class TestClassMatrix {
@GET
@Path("/")
public void oneMatrix(@PathParam("bucket") String path) {
}
}
@ -1417,36 +1402,46 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest {
public interface TestTransformers {
@GET
@Path("")
int noTransformer();
@GET
@Path("")
@ResponseParser(ReturnStringIf2xx.class)
void oneTransformer();
@GET
@Path("")
@ResponseParser(ReturnStringIf200Context.class)
void oneTransformerWithContext();
@GET
@Path("")
InputStream inputStream();
@GET
@Path("")
ListenableFuture<InputStream> futureInputStream();
@GET
@Path("")
URI uri();
@GET
@Path("")
ListenableFuture<URI> futureUri();
@PUT
@Path("")
ListenableFuture<Void> put(Payload payload);
@PUT
@Path("")
@Headers(keys = "Transfer-Encoding", values = "chunked")
ListenableFuture<Void> putXfer(Payload payload);
@PUT
@Path("")
ListenableFuture<Void> put(PayloadEnclosing payload);
}
@ -1925,14 +1920,16 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest {
public interface TestPayload {
@PUT
@Path("")
public void put(@BinderParam(BindToStringPayload.class) String content);
@PUT
@Path("{foo}")
@Path("/{foo}")
public ListenableFuture<Void> putWithPath(@PathParam("foo") String path,
@BinderParam(BindToStringPayload.class) String content);
@PUT
@Path("")
public void twoEntities(@BinderParam(BindToStringPayload.class) String payload1,
@BinderParam(BindToStringPayload.class) String payload2);
}
@ -1969,25 +1966,30 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest {
public class TestFormReplace {
@POST
@Path("/")
public void formInOptions(@PathParam("bucket") String path, TestReplaceFormOptions options) {
}
@POST
@Path("/")
@FormParams(keys = "x-amz-copy-source", values = "/{bucket}")
public void oneForm(@PathParam("bucket") String path) {
}
@POST
@Path("/")
@FormParams(keys = { "slash", "hyphen" }, values = { "/{bucket}", "-{bucket}" })
public void twoForm(@PathParam("bucket") String path) {
}
@POST
@Path("/")
@FormParams(keys = "x-amz-copy-source", values = "/{bucket}/{key}")
public void twoForms(@PathParam("bucket") String path, @PathParam("key") String path2) {
}
@POST
@Path("/")
@FormParams(keys = "x-amz-copy-source", values = "/{bucket}/{key}")
public void twoFormsOutOfOrder(@PathParam("key") String path, @PathParam("bucket") String path2) {
}
@ -2004,6 +2006,7 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest {
@SkipEncoding('/')
public class TestClassForm {
@POST
@Path("/")
public void oneForm(@PathParam("bucket") String path) {
}
}

View File

@ -35,7 +35,6 @@ import javax.inject.Provider;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.UriBuilder;
import org.jboss.resteasy.specimpl.UriBuilderImpl;
import org.jclouds.PerformanceTest;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.HttpResponse;
@ -47,6 +46,7 @@ import com.google.common.collect.HashMultimap;
import com.google.common.collect.Iterables;
import com.google.common.collect.LinkedListMultimap;
import com.google.common.collect.Multimap;
import com.sun.jersey.api.uri.UriBuilderImpl;
/**
* This tests the performance of Digest commands.

View File

@ -24,7 +24,6 @@ import java.util.concurrent.ExecutorService;
import javax.ws.rs.core.UriBuilder;
import org.jboss.resteasy.specimpl.UriBuilderImpl;
import org.jclouds.Constants;
import org.jclouds.PropertiesBuilder;
import org.jclouds.gae.GaeHttpCommandExecutorService;
@ -37,6 +36,7 @@ import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.inject.name.Names;
import com.sun.jersey.api.uri.UriBuilderImpl;
/**
* Tests the ability to configure a {@link GoogleAppEngineConfigurationModule}

View File

@ -26,10 +26,11 @@ import java.net.URI;
import javax.inject.Provider;
import javax.ws.rs.core.UriBuilder;
import org.jboss.resteasy.specimpl.UriBuilderImpl;
import org.jclouds.http.HttpRequest;
import org.testng.annotations.Test;
import com.sun.jersey.api.uri.UriBuilderImpl;
/**
* Tests that id bindings are proper for request
*

View File

@ -26,10 +26,11 @@ import java.net.URI;
import javax.inject.Provider;
import javax.ws.rs.core.UriBuilder;
import org.jboss.resteasy.specimpl.UriBuilderImpl;
import org.jclouds.http.HttpRequest;
import org.testng.annotations.Test;
import com.sun.jersey.api.uri.UriBuilderImpl;
/**
* Tests that name bindings are proper for request
*

View File

@ -40,7 +40,6 @@ import org.jclouds.opscodeplatform.config.Username;
import org.jclouds.opscodeplatform.domain.Organization;
import org.jclouds.opscodeplatform.domain.User;
import org.jclouds.rest.annotations.BinderParam;
import org.jclouds.rest.annotations.Delegate;
import org.jclouds.rest.annotations.ExceptionParser;
import org.jclouds.rest.annotations.Headers;
import org.jclouds.rest.annotations.ParamParser;
@ -65,18 +64,12 @@ import com.google.common.util.concurrent.ListenableFuture;
@Consumes(MediaType.APPLICATION_JSON)
@Headers(keys = "X-Chef-Version", values = ChefAsyncClient.VERSION)
public interface OpscodePlatformAsyncClient {
/**
* @see ChefCookbooks#listCookbooksInOrganization
*/
@Delegate
@Path("organizations/{orgname}")
ChefAsyncClient getChefClientForOrganization(@PathParam("orgname") String orgname);
/**
* @see ChefUser#listUsers
*/
@GET
@Path("users")
@Path("/users")
@ResponseParser(ParseKeySetFromJson.class)
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
ListenableFuture<Set<String>> listUsers();
@ -85,7 +78,7 @@ public interface OpscodePlatformAsyncClient {
* @see ChefRole#userExists
*/
@HEAD
@Path("users/{username}")
@Path("/users/{username}")
@ExceptionParser(ReturnFalseOnNotFoundOr404.class)
ListenableFuture<Boolean> userExists(@PathParam("username") String username);
@ -93,14 +86,14 @@ public interface OpscodePlatformAsyncClient {
* @see ChefClient#createUser
*/
@POST
@Path("users")
@Path("/users")
ListenableFuture<User> createUser(@BinderParam(BindToJsonPayload.class) User user);
/**
* @see ChefClient#updateUser
*/
@PUT
@Path("users/{username}")
@Path("/users/{username}")
@Consumes(MediaType.APPLICATION_JSON)
ListenableFuture<User> updateUser(
@PathParam("username") @ParamParser(Username.class) @BinderParam(BindToJsonPayload.class) User user);
@ -109,7 +102,7 @@ public interface OpscodePlatformAsyncClient {
* @see ChefClient#getUser
*/
@GET
@Path("users/{username}")
@Path("/users/{username}")
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
@Consumes(MediaType.APPLICATION_JSON)
ListenableFuture<User> getUser(@PathParam("username") String username);
@ -118,7 +111,7 @@ public interface OpscodePlatformAsyncClient {
* @see ChefClient#deleteUser
*/
@DELETE
@Path("users/{username}")
@Path("/users/{username}")
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
@Consumes(MediaType.APPLICATION_JSON)
ListenableFuture<User> deleteUser(@PathParam("username") String username);
@ -127,7 +120,7 @@ public interface OpscodePlatformAsyncClient {
* @see ChefOrganization#listOrganizations
*/
@GET
@Path("organizations")
@Path("/organizations")
@ResponseParser(ParseKeySetFromJson.class)
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
ListenableFuture<Set<String>> listOrganizations();
@ -136,7 +129,7 @@ public interface OpscodePlatformAsyncClient {
* @see ChefRole#organizationExists
*/
@HEAD
@Path("organizations/{organizationname}")
@Path("/organizations/{organizationname}")
@ExceptionParser(ReturnFalseOnNotFoundOr404.class)
ListenableFuture<Boolean> organizationExists(@PathParam("organizationname") String organizationname);
@ -144,14 +137,14 @@ public interface OpscodePlatformAsyncClient {
* @see ChefClient#createOrganization
*/
@POST
@Path("organizations")
@Path("/organizations")
ListenableFuture<Organization> createOrganization(@BinderParam(BindToJsonPayload.class) Organization org);
/**
* @see ChefClient#updateOrganization
*/
@PUT
@Path("organizations/{orgname}")
@Path("/organizations/{orgname}")
@Consumes(MediaType.APPLICATION_JSON)
ListenableFuture<Organization> updateOrganization(
@PathParam("orgname") @ParamParser(OrganizationName.class) @BinderParam(BindToJsonPayload.class) Organization org);
@ -160,7 +153,7 @@ public interface OpscodePlatformAsyncClient {
* @see ChefClient#getOrganization
*/
@GET
@Path("organizations/{orgname}")
@Path("/organizations/{orgname}")
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
@Consumes(MediaType.APPLICATION_JSON)
ListenableFuture<Organization> getOrganization(@PathParam("orgname") String orgname);
@ -169,7 +162,7 @@ public interface OpscodePlatformAsyncClient {
* @see ChefClient#deleteOrganization
*/
@DELETE
@Path("organizations/{orgname}")
@Path("/organizations/{orgname}")
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
@Consumes(MediaType.APPLICATION_JSON)
ListenableFuture<Organization> deleteOrganization(@PathParam("orgname") String orgname);

View File

@ -43,13 +43,6 @@ import org.jclouds.rest.annotations.Delegate;
*/
@Timeout(duration = 30, timeUnit = TimeUnit.SECONDS)
public interface OpscodePlatformClient {
/**
* @return a chef client appropriate for the organization specified.
*/
@Delegate
@Path("/organizations/{orgname}")
ChefClient getChefClientForOrganization(@PathParam("orgname") String orgname);
/**
* @return list of user names.
*
@ -76,14 +69,13 @@ 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.
*/
User createUser(User user);
@ -126,8 +118,7 @@ public interface OpscodePlatformClient {
* <p/>
* "401 Unauthorized" if you are not a recognized user.
* <p/>
* "403 Forbidden" if you do not have rights to list
* organizations.
* "403 Forbidden" if you do not have rights to list organizations.
*/
Set<String> listOrganizations();
@ -139,60 +130,52 @@ public interface OpscodePlatformClient {
* <p/>
* "401 Unauthorized" if you are not a recognized user.
* <p/>
* "403 Forbidden" if you do not have rights to view the
* organization.
* "403 Forbidden" if you do not have rights to view the organization.
*/
boolean organizationExists(String name);
/**
* 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.
*/
Organization createOrganization(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.
* <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 updateOrganization(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 getOrganization(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 last state of the org you deleted or null, if not found
* @throws AuthorizationException
* <p/>
* "401 Unauthorized" if you are not a recognized organization.
* <p/>
* "403 Forbidden" if you do not have Delete rights on the
* organization.
* "403 Forbidden" if you do not have Delete rights on the organization.
*/
Organization deleteOrganization(String organizationname);
}

View File

@ -19,15 +19,11 @@
package org.jclouds.opscodeplatform;
import static org.easymock.classextension.EasyMock.createMock;
import static org.easymock.classextension.EasyMock.replay;
import static org.jclouds.rest.RestContextFactory.createContextBuilder;
import static org.testng.Assert.assertEquals;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.Properties;
import java.util.concurrent.ExecutionException;
import org.jclouds.chef.filters.SignedHeaderAuth;
import org.jclouds.chef.filters.SignedHeaderAuthTest;
@ -42,7 +38,6 @@ import org.jclouds.http.TransformingHttpCommandExecutorService;
import org.jclouds.http.config.ConfiguresHttpCommandExecutorService;
import org.jclouds.http.functions.ParseJson;
import org.jclouds.http.functions.ReturnTrueIf2xx;
import org.jclouds.logging.config.NullLoggingModule;
import org.jclouds.opscodeplatform.domain.Organization;
import org.jclouds.opscodeplatform.domain.User;
import org.jclouds.opscodeplatform.functions.OpscodePlatformRestClientModule;
@ -58,10 +53,8 @@ import org.jclouds.rest.internal.RestAnnotationProcessor;
import org.testng.annotations.Test;
import com.google.common.base.Supplier;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.inject.AbstractModule;
import com.google.inject.Injector;
import com.google.inject.Module;
import com.google.inject.TypeLiteral;
@ -73,28 +66,6 @@ import com.google.inject.TypeLiteral;
@Test(groups = "unit", testName = "opscodeplatform.OpscodePlatformAsyncClientTest")
public class OpscodePlatformAsyncClientTest extends RestClientTest<OpscodePlatformAsyncClient> {
public void testDelegatedOpscodePlatformCallsResolveProperly() throws SecurityException, NoSuchMethodException,
InterruptedException, ExecutionException {
final TransformingHttpCommandExecutorService httpExecutor = createMock(TransformingHttpCommandExecutorService.class);
Injector injector = createContextBuilder(createContextSpec(),
ImmutableSet.of(new HttpExecutorModule(httpExecutor), new NullLoggingModule(), createModule()))
.buildInjector();
replay(httpExecutor);
OpscodePlatformAsyncClient caller = injector.getInstance(OpscodePlatformAsyncClient.class);
try {
caller.getChefClientForOrganization("goo").listClients().get();
assert false : "shouldn't have connected as this url should be dummy";
} catch (AssertionError e) {
assert e.getMessage().indexOf("[request=GET https://api.opscode.com/organizations/goo/clients HTTP/1.1]") != -1 : e
.getMessage();
}
}
public void testListUsers() throws SecurityException, NoSuchMethodException, IOException {
Method method = OpscodePlatformAsyncClient.class.getMethod("listUsers");
GeneratedHttpRequest<OpscodePlatformAsyncClient> httpRequest = processor.createRequest(method);
@ -160,7 +131,7 @@ public class OpscodePlatformAsyncClientTest extends RestClientTest<OpscodePlatfo
public void testCreateUser() throws SecurityException, NoSuchMethodException, IOException {
Method method = OpscodePlatformAsyncClient.class.getMethod("createUser", User.class);
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");
assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\nX-Chef-Version: 0.9.8\n");
@ -172,16 +143,19 @@ public class OpscodePlatformAsyncClientTest extends RestClientTest<OpscodePlatfo
assertRequestLineEquals(httpRequest, "POST https://api.opscode.com/users HTTP/1.1");
assertNonPayloadHeadersEqual(httpRequest, new StringBuilder("Accept: application/json").append("\n").append(
"X-Chef-Version: 0.9.8").append("\n").append(
"X-Ops-Authorization-1: kfrkDpfgNU26k70R1vl1bEWk0Q0f9Fs/3kxOX7gHd7iNoJq03u7RrcrAOSgL").append("\n").append(
"X-Ops-Authorization-2: ETj5JNeCk18BmFkHMAbCA9hXVo1T4rlHCpbuzAzFlFxUGAT4wj8UoO7V886X").append("\n").append(
"X-Ops-Authorization-3: Kf8DvihP6ElthCNuu1xuhN0B4GEmWC9+ut7UMLe0L2T34VzkbCtuInGbf42/").append("\n").append(
"X-Ops-Authorization-4: G7iu94/xFOT1gN9cex4pNyTnRCHzob4JVU1usxt/2g5grN2SyYwRS5+4MNLN").append("\n").append(
"X-Ops-Authorization-5: WY/iLUPb/9dwtiIQsnUOXqDrs28zNswZulQW4AzYRd7MczJVKU4y4+4XRcB4").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("X-Ops-Userid: user").append("\n")
.toString());
"X-Chef-Version: 0.9.8").append("\n").append(
"X-Ops-Authorization-1: kfrkDpfgNU26k70R1vl1bEWk0Q0f9Fs/3kxOX7gHd7iNoJq03u7RrcrAOSgL").append("\n")
.append("X-Ops-Authorization-2: ETj5JNeCk18BmFkHMAbCA9hXVo1T4rlHCpbuzAzFlFxUGAT4wj8UoO7V886X").append(
"\n").append(
"X-Ops-Authorization-3: Kf8DvihP6ElthCNuu1xuhN0B4GEmWC9+ut7UMLe0L2T34VzkbCtuInGbf42/").append(
"\n").append(
"X-Ops-Authorization-4: G7iu94/xFOT1gN9cex4pNyTnRCHzob4JVU1usxt/2g5grN2SyYwRS5+4MNLN").append(
"\n").append(
"X-Ops-Authorization-5: WY/iLUPb/9dwtiIQsnUOXqDrs28zNswZulQW4AzYRd7MczJVKU4y4+4XRcB4").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("X-Ops-Userid: user").append("\n").toString());
assertPayloadEquals(httpRequest, "{\"username\":\"myuser\"}", "application/json", false);
assertResponseParserClassEquals(method, httpRequest, ParseJson.class);
@ -195,7 +169,7 @@ 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"));
.createRequest(method, new User("myuser"));
assertRequestLineEquals(httpRequest, "PUT https://api.opscode.com/users/myuser HTTP/1.1");
assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\nX-Chef-Version: 0.9.8\n");
@ -244,13 +218,14 @@ public class OpscodePlatformAsyncClientTest extends RestClientTest<OpscodePlatfo
public void testCreateOrg() throws SecurityException, NoSuchMethodException, IOException {
Method method = OpscodePlatformAsyncClient.class.getMethod("createOrganization", Organization.class);
GeneratedHttpRequest<OpscodePlatformAsyncClient> httpRequest = processor.createRequest(method, new Organization(
"myorganization", "myorganization", "myorganization-validator", Organization.Type.BUSINESS));
"myorganization", "myorganization", "myorganization-validator", Organization.Type.BUSINESS));
assertRequestLineEquals(httpRequest, "POST https://api.opscode.com/organizations HTTP/1.1");
assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\nX-Chef-Version: 0.9.8\n");
assertPayloadEquals(httpRequest,
"{\"name\":\"myorganization\",\"full_name\":\"myorganization\",\"clientname\":\"myorganization-validator\",\"org_type\":\"Business\"}",
"application/json", false);
assertPayloadEquals(
httpRequest,
"{\"name\":\"myorganization\",\"full_name\":\"myorganization\",\"clientname\":\"myorganization-validator\",\"org_type\":\"Business\"}",
"application/json", false);
assertResponseParserClassEquals(method, httpRequest, ParseJson.class);
assertSaxResponseParserClassEquals(method, null);
@ -263,13 +238,14 @@ public class OpscodePlatformAsyncClientTest extends RestClientTest<OpscodePlatfo
public void testUpdateOrg() throws SecurityException, NoSuchMethodException, IOException {
Method method = OpscodePlatformAsyncClient.class.getMethod("updateOrganization", Organization.class);
GeneratedHttpRequest<OpscodePlatformAsyncClient> httpRequest = processor.createRequest(method, new Organization(
"myorganization", "myorganization", "myorganization-validator", Organization.Type.BUSINESS));
"myorganization", "myorganization", "myorganization-validator", Organization.Type.BUSINESS));
assertRequestLineEquals(httpRequest, "PUT https://api.opscode.com/organizations/myorganization HTTP/1.1");
assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\nX-Chef-Version: 0.9.8\n");
assertPayloadEquals(httpRequest,
"{\"name\":\"myorganization\",\"full_name\":\"myorganization\",\"clientname\":\"myorganization-validator\",\"org_type\":\"Business\"}",
"application/json", false);
assertPayloadEquals(
httpRequest,
"{\"name\":\"myorganization\",\"full_name\":\"myorganization\",\"clientname\":\"myorganization-validator\",\"org_type\":\"Business\"}",
"application/json", false);
assertResponseParserClassEquals(method, httpRequest, ParseJson.class);
assertSaxResponseParserClassEquals(method, null);
@ -357,6 +333,6 @@ public class OpscodePlatformAsyncClientTest extends RestClientTest<OpscodePlatfo
@Override
public ContextSpec<OpscodePlatformClient, OpscodePlatformAsyncClient> createContextSpec() {
return new RestContextFactory().createContextSpec("opscodeplatform", "user", SignedHeaderAuthTest.PRIVATE_KEY,
new Properties());
new Properties());
}
}

View File

@ -63,30 +63,35 @@ public class OpscodePlatformClientLiveTest extends BaseChefClientLiveTest {
private OpscodePlatformContext adminConnection;
private String validator;
private String adminKey;
private String validatorKey;
@Override
@BeforeClass(groups = { "live" })
public void setupClient() throws IOException {
validator = checkNotNull(System.getProperty("jclouds.test.validator"), "jclouds.test.validator");
orgname = validator.substring(0, validator.lastIndexOf('-'));
String validatorKey = System.getProperty("jclouds.test.validator.key");
if (validatorKey == null || validatorKey.equals(""))
validatorKey = System.getProperty("user.home") + "/.chef/" + orgname + "-validator.pem";
String validatorKeyFile = System.getProperty("jclouds.test.validator.key");
if (validatorKeyFile == null || validatorKeyFile.equals(""))
validatorKeyFile = System.getProperty("user.home") + "/.chef/" + orgname + "-validator.pem";
user = checkNotNull(System.getProperty("jclouds.test.identity"), "jclouds.test.identity");
String keyfile = System.getProperty("jclouds.test.credential");
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));
validatorKey = Files.toString(new File(validatorKeyFile), Charsets.UTF_8);
adminKey = Files.toString(new File(keyfile), Charsets.UTF_8);
validatorConnection = createConnection(validator, validatorKey);
adminConnection = createConnection(user, adminKey);
json = Guice.createInjector(new GsonModule(), new ChefParserModule()).getInstance(Json.class);
}
private OpscodePlatformContext createConnection(String identity, String key) throws IOException {
Properties props = new Properties();
return (OpscodePlatformContext) new RestContextFactory()
.<OpscodePlatformClient, OpscodePlatformAsyncClient> createContext("opscodeplatform", identity, key,
ImmutableSet.<Module> of(new Log4JLoggingModule()), props);
.<OpscodePlatformClient, OpscodePlatformAsyncClient> createContext("opscodeplatform", identity, key,
ImmutableSet.<Module> of(new Log4JLoggingModule()), props);
}
@Override
@ -96,17 +101,24 @@ public class OpscodePlatformClientLiveTest extends BaseChefClientLiveTest {
@Override
protected ChefClient getAdminConnection() {
return adminConnection.getApi().getChefClientForOrganization(orgname);
return createChefClient(user, adminKey);
}
private ChefClient createChefClient(String user, String adminKey) {
Properties props = new Properties();
props.setProperty("chef.endpoint", "https://api.opscode.com/organizations/" + orgname);
return (ChefClient) new RestContextFactory().createContext("chef", user, adminKey,
ImmutableSet.<Module> of(new Log4JLoggingModule()), props).getApi();
}
@Override
protected ChefClient getValidatorConnection() {
return validatorConnection.getApi().getChefClientForOrganization(orgname);
return createChefClient(validator, validatorKey);
}
@Override
protected ChefClient getClientConnection() {
return clientConnection.getApi().getChefClientForOrganization(orgname);
return createChefClient(PREFIX, clientKey);
}
@Override
@ -142,8 +154,7 @@ public class OpscodePlatformClientLiveTest extends BaseChefClientLiveTest {
}
/**
* this test only works when you have a super user not yet supported in the
* official api
* this test only works when you have a super user not yet supported in the official api
*/
@Test(enabled = false, expectedExceptions = AuthorizationException.class)
public void testCreateOrganization() throws Exception {

View File

@ -34,7 +34,6 @@
<module>project</module>
<module>assemblies</module>
<module>archetypes</module>
<module>thirdparty</module>
<module>core</module>
<module>compute</module>
<module>blobstore</module>

View File

@ -91,13 +91,6 @@
<enabled>true</enabled>
</snapshots>
</repository>
<repository>
<id>jboss</id>
<url>http://repository.jboss.org/nexus/content/groups/public-jboss</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<repository>
<id>googlecode.java-xmlbuilder</id>
<url>http://java-xmlbuilder.googlecode.com/svn/repo</url>

View File

@ -35,12 +35,10 @@ import com.google.common.util.concurrent.ListenableFuture;
* Provides access to Rackspace resources via their REST API.
* <p/>
*
* @see <a
* href="http://docs.rackspacecloud.com/servers/api/cs-devguide-latest.pdf"
* />
* @see <a href="http://docs.rackspacecloud.com/servers/api/cs-devguide-latest.pdf" />
* @author Adrian Cole
*/
@Path("v" + RackspaceAuthAsyncClient.VERSION)
@Path("/v" + RackspaceAuthAsyncClient.VERSION)
public interface RackspaceAuthAsyncClient {
public static final String VERSION = "1.0";
@ -59,7 +57,8 @@ public interface RackspaceAuthAsyncClient {
}
@GET
@Path("")
@ResponseParser(ParseAuthenticationResponseFromHeaders.class)
ListenableFuture<AuthenticationResponse> authenticate(@HeaderParam(RackspaceHeaders.AUTH_USER) String user,
@HeaderParam(RackspaceHeaders.AUTH_KEY) String key);
@HeaderParam(RackspaceHeaders.AUTH_KEY) String key);
}

View File

@ -117,7 +117,7 @@ public interface CloudFilesAsyncClient {
* @see CloudFilesClient#setObjectInfo
*/
@POST
@Path("{container}/{name}")
@Path("/{container}/{name}")
ListenableFuture<Boolean> setObjectInfo(
@PathParam("container") String container,
@PathParam("name") String name,
@ -143,7 +143,7 @@ public interface CloudFilesAsyncClient {
@HEAD
@ResponseParser(ParseContainerCDNMetadataFromHeaders.class)
@ExceptionParser(ThrowContainerNotFoundOn404.class)
@Path("{container}")
@Path("/{container}")
@Endpoint(CloudFilesCDN.class)
ListenableFuture<ContainerCDNMetadata> getCDNMetadata(
@PathParam("container") String container);
@ -152,7 +152,7 @@ public interface CloudFilesAsyncClient {
* @see CloudFilesClient#enableCDN(String, long);
*/
@PUT
@Path("{container}")
@Path("/{container}")
@Headers(keys = CloudFilesHeaders.CDN_ENABLED, values = "True")
@ResponseParser(ParseCdnUriFromHeaders.class)
@Endpoint(CloudFilesCDN.class)
@ -163,7 +163,7 @@ public interface CloudFilesAsyncClient {
* @see CloudFilesClient#enableCDN(String)
*/
@PUT
@Path("{container}")
@Path("/{container}")
@Headers(keys = CloudFilesHeaders.CDN_ENABLED, values = "True")
@ResponseParser(ParseCdnUriFromHeaders.class)
@Endpoint(CloudFilesCDN.class)
@ -173,7 +173,7 @@ public interface CloudFilesAsyncClient {
* @see CloudFilesClient#updateCDN
*/
@POST
@Path("{container}")
@Path("/{container}")
@ResponseParser(ParseCdnUriFromHeaders.class)
@Endpoint(CloudFilesCDN.class)
ListenableFuture<URI> updateCDN(@PathParam("container") String container,
@ -183,7 +183,7 @@ public interface CloudFilesAsyncClient {
* @see CloudFilesClient#disableCDN
*/
@POST
@Path("{container}")
@Path("/{container}")
@Headers(keys = CloudFilesHeaders.CDN_ENABLED, values = "False")
@Endpoint(CloudFilesCDN.class)
ListenableFuture<Boolean> disableCDN(@PathParam("container") String container);
@ -192,7 +192,7 @@ public interface CloudFilesAsyncClient {
* @see CloudFilesClient#createContainer
*/
@PUT
@Path("{container}")
@Path("/{container}")
ListenableFuture<Boolean> createContainer(
@PathParam("container") String container);
@ -201,7 +201,7 @@ public interface CloudFilesAsyncClient {
*/
@DELETE
@ExceptionParser(ReturnTrueOn404FalseOn409.class)
@Path("{container}")
@Path("/{container}")
ListenableFuture<Boolean> deleteContainerIfEmpty(
@PathParam("container") String container);
@ -211,7 +211,7 @@ public interface CloudFilesAsyncClient {
@GET
@QueryParams(keys = "format", values = "json")
@ResponseParser(ParseObjectInfoListFromJsonResponse.class)
@Path("{container}")
@Path("/{container}")
ListenableFuture<PageSet<ObjectInfo>> listObjects(
@PathParam("container") String container,
ListContainerOptions... options);
@ -220,7 +220,7 @@ public interface CloudFilesAsyncClient {
* @see CloudFilesClient#containerExists
*/
@HEAD
@Path("{container}")
@Path("/{container}")
@ExceptionParser(ReturnFalseOnContainerNotFound.class)
ListenableFuture<Boolean> containerExists(
@PathParam("container") String container);
@ -229,7 +229,7 @@ public interface CloudFilesAsyncClient {
* @see CloudFilesClient#putObject
*/
@PUT
@Path("{container}/{name}")
@Path("/{container}/{name}")
@ResponseParser(ParseETagHeader.class)
ListenableFuture<String> putObject(
@PathParam("container") String container,
@ -241,7 +241,7 @@ public interface CloudFilesAsyncClient {
@GET
@ResponseParser(ParseObjectFromHeadersAndHttpContent.class)
@ExceptionParser(ReturnNullOnKeyNotFound.class)
@Path("{container}/{name}")
@Path("/{container}/{name}")
ListenableFuture<CFObject> getObject(
@PathParam("container") String container,
@PathParam("name") String name, GetOptions... options);
@ -252,7 +252,7 @@ public interface CloudFilesAsyncClient {
@HEAD
@ResponseParser(ParseObjectInfoFromHeaders.class)
@ExceptionParser(ReturnNullOnKeyNotFound.class)
@Path("{container}/{name}")
@Path("/{container}/{name}")
ListenableFuture<MutableObjectInfoWithMetadata> getObjectInfo(
@PathParam("container") String container,
@PathParam("name") String name);
@ -262,7 +262,7 @@ public interface CloudFilesAsyncClient {
*/
@HEAD
@ExceptionParser(ReturnFalseOnKeyNotFound.class)
@Path("{container}/{name}")
@Path("/{container}/{name}")
ListenableFuture<Boolean> objectExists(
@PathParam("container") String container,
@PathParam("name") String name);
@ -272,7 +272,7 @@ public interface CloudFilesAsyncClient {
*/
@DELETE
@ExceptionParser(ReturnVoidOnNotFoundOr404.class)
@Path("{container}/{name}")
@Path("/{container}/{name}")
ListenableFuture<Void> removeObject(
@PathParam("container") String container,
@PathParam("name") String name);

View File

@ -258,13 +258,8 @@ public class CloudFilesClientLiveTest extends BaseBlobStoreIntegrationTest {
String containerName2 = containerName + "?should-be-illegal-question-char";
assert getApi().createContainer(containerName2);
// TODO: Should throw a specific exception, not
// UndeclaredThrowableException
try {
getApi().createContainer(containerName + "/illegal-slash-char");
fail("Should not be able to create container with illegal '/' character");
} catch (Exception e) {
}
assert getApi().createContainer(containerName + "/illegal-slash-char");
assertTrue(getApi().deleteContainerIfEmpty(containerName1));
assertTrue(getApi().deleteContainerIfEmpty(containerName2));
} finally {
@ -313,14 +308,10 @@ public class CloudFilesClientLiveTest extends BaseBlobStoreIntegrationTest {
// Test HEAD of object
MutableObjectInfoWithMetadata metadata = getApi().getObjectInfo(containerName, object.getInfo().getName());
// TODO assertEquals(metadata.getName(),
// object.getMetadata().getName());
assertEquals(metadata.getName(), object.getInfo().getName());
// rackspace recently doesn't return a content-length or type on head
assertEquals(metadata.getBytes(), null);
assertEquals(metadata.getContentType(), null);
// assertEquals(metadata.getBytes(), new Long(data.length()));
// assertEquals(metadata.getContentType(), "text/plain");
assertEquals(metadata.getBytes(), new Long(data.length()));
assertEquals(metadata.getContentType(), "text/plain; charset=UTF-8");
assertEquals(CryptoStreams.hex(md5), CryptoStreams.hex(metadata.getHash()));
assertEquals(metadata.getHash(), CryptoStreams.hex(newEtag));
@ -341,7 +332,7 @@ public class CloudFilesClientLiveTest extends BaseBlobStoreIntegrationTest {
// TODO assertEquals(getBlob.getName(),
// object.getMetadata().getName());
assertEquals(getBlob.getInfo().getBytes(), new Long(data.length()));
assertEquals(getBlob.getInfo().getContentType(), "text/plain");
assertEquals(getBlob.getInfo().getContentType(), "text/plain; charset=UTF-8");
assertEquals(CryptoStreams.hex(md5), CryptoStreams.hex(getBlob.getInfo().getHash()));
assertEquals(CryptoStreams.hex(newEtag), getBlob.getInfo().getHash());
assertEquals(getBlob.getInfo().getMetadata().entrySet().size(), 2);

View File

@ -27,11 +27,11 @@ import java.util.Date;
import javax.inject.Provider;
import javax.ws.rs.core.UriBuilder;
import org.jboss.resteasy.specimpl.UriBuilderImpl;
import org.jclouds.http.HttpRequest;
import org.testng.annotations.Test;
import com.google.common.base.Supplier;
import com.sun.jersey.api.uri.UriBuilderImpl;
/**
*

20
thirdparty/README.txt vendored
View File

@ -1,20 +0,0 @@
====
Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
====================================================================
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
====================================================================
====
thirdparty module is code we are temporarily storing as there is no maven module for it (or the code we use from it).
Please publish to maven repos manually as needed.

49
thirdparty/pom.xml vendored
View File

@ -1,49 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
====================================================================
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
====================================================================
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<artifactId>jclouds-project</artifactId>
<groupId>org.jclouds</groupId>
<version>1.0-SNAPSHOT</version>
<relativePath>../project/pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jclouds-thirdparty-project</artifactId>
<packaging>pom</packaging>
<name>jclouds thirdparty project</name>
<modules>
<module>resteasy-jaxrs-client</module>
</modules>
<distributionManagement>
<!-- third-party projects not in org.jclouds can't be deployed to Sonatype -->
<repository>
<id>jclouds-googlecode-deploy</id>
<url>dav:https://jclouds.googlecode.com/svn/repo</url>
<uniqueVersion>false</uniqueVersion>
</repository>
<snapshotRepository>
<id>jclouds-rimu-snapshots-nexus</id>
<url>http://jclouds.rimuhosting.com/nexus/content/repositories/snapshots</url>
</snapshotRepository>
</distributionManagement>
</project>

View File

@ -1,20 +0,0 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.jclouds</groupId>
<artifactId>jclouds-thirdparty-project</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jaxrs-client</artifactId>
<version>1.2.1.GA-SNAPSHOT</version>
<name>RESTEasy JAX-RS Client Implementation</name>
<dependencies>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>jaxrs-api</artifactId>
<version>1.2.1.GA</version>
</dependency>
</dependencies>
</project>

View File

@ -1,38 +0,0 @@
package org.jboss.resteasy.specimpl;
import javax.ws.rs.core.MultivaluedMap;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
public class MultivaluedMapImpl<K, V> extends HashMap<K, List<V>> implements MultivaluedMap<K, V>
{
public void putSingle(K key, V value)
{
List<V> list = new ArrayList<V>(1);
list.add(value);
put(key, list);
}
public void add(K key, V value)
{
List<V> list = get(key);
if (list == null)
{
list = new ArrayList<V>(1);
put(key, list);
}
list.add(value);
}
public V getFirst(K key)
{
List<V> list = get(key);
return (list == null) ? null : list.get(0);
}
}

View File

@ -1,681 +0,0 @@
package org.jboss.resteasy.specimpl;
import org.jboss.resteasy.util.Encode;
import org.jboss.resteasy.util.PathHelper;
import javax.ws.rs.Path;
import javax.ws.rs.core.UriBuilder;
import javax.ws.rs.core.UriBuilderException;
import java.lang.reflect.Method;
import java.net.URI;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
public class UriBuilderImpl extends UriBuilder
{
private String host;
private String scheme;
private int port = -1;
private String userInfo;
private String path;
private String query;
private String fragment;
private String ssp;
public UriBuilder clone()
{
UriBuilderImpl impl = new UriBuilderImpl();
impl.host = host;
impl.scheme = scheme;
impl.port = port;
impl.userInfo = userInfo;
impl.path = path;
impl.query = query;
impl.fragment = fragment;
impl.ssp = ssp;
return impl;
}
private static final Pattern uriPattern = Pattern.compile("([^:]+)://([^/:]+)(:(\\d+))?(/[^?]*)?(\\?([^#]+))?(#(.*))?");
/**
* Must follow the patter scheme://host:port/path?query#fragment
* <p/>
* port, path, query and fragment are optional. Scheme and host must be specified.
* <p/>
* You may put path parameters anywhere within the uriTemplate except port
*
* @param uriTemplate
* @return
*/
public static UriBuilder fromTemplate(String uriTemplate)
{
UriBuilderImpl impl = new UriBuilderImpl();
impl.uriTemplate(uriTemplate);
return impl;
}
/**
* Must follow the patter scheme://host:port/path?query#fragment
* <p/>
* port, path, query and fragment are optional. Scheme and host must be specified.
* <p/>
* You may put path parameters anywhere within the uriTemplate except port
*
* @param uriTemplate
* @return
*/
public UriBuilder uriTemplate(String uriTemplate)
{
Matcher match = uriPattern.matcher(uriTemplate);
if (!match.matches()) throw new RuntimeException("Illegal uri template: " + uriTemplate);
scheme(match.group(1));
host(match.group(2));
if (match.group(4) != null) port(Integer.valueOf(match.group(4)));
if (match.group(5) != null) path(match.group(5));
if (match.group(7) != null) replaceQuery(match.group(7));
if (match.group(9) != null) fragment(match.group(8));
return this;
}
@Override
public UriBuilder uri(URI uri) throws IllegalArgumentException
{
if (uri == null) throw new IllegalArgumentException("URI was null");
if (uri.getScheme() != null) scheme = uri.getScheme();
if (uri.getRawSchemeSpecificPart() != null && uri.getRawPath() == null)
{
ssp = uri.getRawSchemeSpecificPart();
}
else
{
this.ssp = null;
if (uri.getHost() != null) host = uri.getHost();
if (uri.getPort() != -1) port = uri.getPort();
if (uri.getUserInfo() != null) userInfo = uri.getRawUserInfo();
if (uri.getPath() != null && !uri.getPath().equals("")) path = uri.getRawPath();
if (uri.getQuery() != null) query = uri.getRawQuery();
if (uri.getFragment() != null) fragment = uri.getRawFragment();
}
return this;
}
@Override
public UriBuilder scheme(String scheme) throws IllegalArgumentException
{
this.scheme = scheme;
return this;
}
@Override
public UriBuilder schemeSpecificPart(String ssp) throws IllegalArgumentException
{
if (ssp == null) throw new IllegalArgumentException("schemeSpecificPart was null");
StringBuilder sb = new StringBuilder();
if (scheme != null) sb.append(scheme).append(':');
if (ssp != null)
sb.append(ssp);
if (fragment != null && fragment.length() > 0) sb.append('#').append(fragment);
URI uri = URI.create(sb.toString());
if (uri.getRawSchemeSpecificPart() != null && uri.getRawPath() == null)
{
this.ssp = uri.getRawSchemeSpecificPart();
}
else
{
this.ssp = null;
userInfo = uri.getRawUserInfo();
host = uri.getHost();
port = uri.getPort();
path = uri.getRawPath();
query = uri.getRawQuery();
}
return this;
}
@Override
public UriBuilder userInfo(String ui)
{
this.userInfo = ui;
return this;
}
@Override
public UriBuilder host(String host) throws IllegalArgumentException
{
if (host == null) throw new IllegalArgumentException("schemeSpecificPart was null");
this.host = host;
return this;
}
@Override
public UriBuilder port(int port) throws IllegalArgumentException
{
this.port = port;
return this;
}
protected static String paths(boolean encode, String basePath, String... segments)
{
String path = basePath;
if (path == null) path = "";
for (String segment : segments)
{
if ("".equals(segment)) continue;
if (!path.endsWith("/")) path += "/";
if (segment.equals("/")) continue;
if (segment.startsWith("/")) segment = segment.substring(1);
if (encode) segment = Encode.encodePath(segment, true);
path += segment;
}
return path;
}
@Override
public UriBuilder path(String segment) throws IllegalArgumentException
{
if (segment == null) throw new IllegalArgumentException("path was null");
path = paths(true, path, segment);
return this;
}
@SuppressWarnings("unchecked")
@Override
public UriBuilder path(Class resource) throws IllegalArgumentException
{
if (resource == null) throw new IllegalArgumentException("path was null");
Path ann = (Path) resource.getAnnotation(Path.class);
if (ann != null)
{
String[] segments = new String[]{ann.value()};
path = paths(true, path, segments);
}
else
{
throw new IllegalArgumentException("Class must be annotated with @Path to invoke path(Class)");
}
return this;
}
@SuppressWarnings("unchecked")
@Override
public UriBuilder path(Class resource, String method) throws IllegalArgumentException
{
if (resource == null) throw new IllegalArgumentException("resource was null");
if (method == null) throw new IllegalArgumentException("method was null");
for (Method m : resource.getMethods())
{
if (m.getName().equals(method))
{
return path(m);
}
}
return this;
}
@Override
public UriBuilder path(Method method) throws IllegalArgumentException
{
if (method == null) throw new IllegalArgumentException("method was null");
Path ann = method.getAnnotation(Path.class);
if (ann != null)
{
path = paths(true, path, ann.value());
}
return this;
}
@Override
public UriBuilder replaceMatrix(String matrix) throws IllegalArgumentException
{
if (!matrix.startsWith(";")) matrix = ";" + matrix;
if (path == null)
{
path = matrix;
}
else
{
int start = path.lastIndexOf('/');
if (start < 0) start = 0;
int matrixIndex = path.indexOf(';', start);
if (matrixIndex > -1) path = path.substring(0, matrixIndex) + matrix;
else path += matrix;
}
return this;
}
@Override
public UriBuilder replaceQuery(String query) throws IllegalArgumentException
{
this.query = query;
return this;
}
@Override
public UriBuilder fragment(String fragment) throws IllegalArgumentException
{
this.fragment = Encode.encodeSegment(fragment, true);
return this;
}
/**
* Only replace path params in path of URI. This changes state of URIBuilder.
*
* @param name
* @param value
* @param isEncoded
* @return
*/
public UriBuilder substitutePathParam(String name, Object value, boolean isEncoded)
{
if (path != null)
{
StringBuffer buffer = new StringBuffer();
replaceParameter(name, value.toString(), isEncoded, path, buffer);
path = buffer.toString();
}
return this;
}
@Override
public URI buildFromMap(Map<String, ? extends Object> values) throws IllegalArgumentException, UriBuilderException
{
return buildFromMap(values, false);
}
@Override
public URI buildFromEncodedMap(Map<String, ? extends Object> values) throws IllegalArgumentException, UriBuilderException
{
return buildFromMap(values, true);
}
public URI buildFromMap(Map<String, ? extends Object> paramMap, boolean isEncoded) throws IllegalArgumentException, UriBuilderException
{
StringBuffer buffer = new StringBuffer();
if (scheme != null) replaceParameter(paramMap, isEncoded, scheme, buffer).append(":");
if (ssp != null)
{
buffer.append(ssp);
}
else if (userInfo != null || host != null || port != -1)
{
buffer.append("//");
if (userInfo != null) replaceParameter(paramMap, isEncoded, userInfo, buffer).append("@");
if (host != null) replaceParameter(paramMap, isEncoded, host, buffer);
if (port != -1) buffer.append(":").append(Integer.toString(port));
}
if (path != null) replaceParameter(paramMap, isEncoded, path, buffer);
if (query != null)
{
buffer.append("?");
replaceQueryStringParameter(paramMap, isEncoded, query, buffer);
}
if (fragment != null)
{
buffer.append("#");
replaceParameter(paramMap, isEncoded, fragment, buffer);
}
String buf = buffer.toString();
try
{
return URI.create(buf);
}
catch (Exception e)
{
throw new RuntimeException("Failed to create URI: " + buf, e);
}
}
protected StringBuffer replaceParameter(String name, String value, boolean isEncoded, String string, StringBuffer buffer)
{
Matcher matcher = createUriParamMatcher(string);
while (matcher.find())
{
String param = matcher.group(1);
if (!param.equals(name)) continue;
if (!isEncoded)
{
value = Encode.encodeSegment(value, false);
value = Encode.encodeNonCodes(value);
}
matcher.appendReplacement(buffer, value);
}
matcher.appendTail(buffer);
return buffer;
}
protected Matcher createUriParamMatcher(String string)
{
Matcher matcher = PathHelper.URI_PARAM_PATTERN.matcher(PathHelper.replaceEnclosedCurlyBraces(string));
return matcher;
}
protected StringBuffer replaceParameter(Map<String, ? extends Object> paramMap, boolean isEncoded, String string, StringBuffer buffer)
{
Matcher matcher = createUriParamMatcher(string);
while (matcher.find())
{
String param = matcher.group(1);
String value = paramMap.get(param).toString();
if (value != null)
{
if (!isEncoded)
{
value = Encode.encodeSegment(value, false);
value = Encode.encodeNonCodes(value);
}
matcher.appendReplacement(buffer, value);
}
else
{
throw new IllegalArgumentException("path param " + param + " has not been provided by the parameter map");
}
}
matcher.appendTail(buffer);
return buffer;
}
protected StringBuffer replaceQueryStringParameter(Map<String, ? extends Object> paramMap, boolean isEncoded, String string, StringBuffer buffer)
{
Matcher matcher = createUriParamMatcher(string);
while (matcher.find())
{
String param = matcher.group(1);
String value = paramMap.get(param).toString();
if (value != null)
{
if (!isEncoded)
{
value = Encode.encodeQueryStringNameOrValue(value);
}
matcher.appendReplacement(buffer, value);
}
else
{
throw new IllegalArgumentException("path param " + param + " has not been provided by the parameter map");
}
}
matcher.appendTail(buffer);
return buffer;
}
/**
* Return a unique order list of path params
*
* @return
*/
public List<String> getPathParamNamesInDeclarationOrder()
{
List<String> params = new ArrayList<String>();
HashSet<String> set = new HashSet<String>();
if (scheme != null) addToPathParamList(params, set, scheme);
if (userInfo != null) addToPathParamList(params, set, userInfo);
if (host != null) addToPathParamList(params, set, host);
if (path != null) addToPathParamList(params, set, path);
if (query != null) addToPathParamList(params, set, query);
if (fragment != null) addToPathParamList(params, set, fragment);
return params;
}
private void addToPathParamList(List<String> params, HashSet<String> set, String string)
{
Matcher matcher = PathHelper.URI_PARAM_PATTERN.matcher(PathHelper.replaceEnclosedCurlyBraces(string));
while (matcher.find())
{
String param = matcher.group(1);
if (set.contains(param)) continue;
else
{
set.add(param);
params.add(param);
}
}
}
@Override
public URI build(Object... values) throws IllegalArgumentException, UriBuilderException
{
return buildFromValues(false, values);
}
protected URI buildFromValues(boolean encoded, Object... values)
{
List<String> params = getPathParamNamesInDeclarationOrder();
if (values.length < params.size())
throw new IllegalArgumentException("You did not supply enough values to fill path parameters");
if (values.length > params.size()) throw new IllegalArgumentException("You provided too many values");
Map<String, Object> pathParams = new HashMap<String, Object>();
int i = 0;
for (Object val : values)
{
if (val == null) throw new IllegalArgumentException("A value was null");
String pathParam = params.get(i++);
pathParams.put(pathParam, val.toString());
}
return buildFromMap(pathParams, encoded);
}
@Override
public UriBuilder matrixParam(String name, Object... values) throws IllegalArgumentException
{
if (path == null) path = "";
for (Object val : values)
{
path += ";" + Encode.encodeSegment(name, false) + "=" + Encode.encodeSegment(val.toString(), true);
}
return this;
}
private static final Pattern PARAM_REPLACEMENT = Pattern.compile("_resteasy_uri_parameter");
@Override
public UriBuilder replaceMatrixParam(String name, Object... values) throws IllegalArgumentException
{
if (path == null) return matrixParam(name, values);
// remove all path param expressions so we don't accidentally start replacing within a regular expression
ArrayList<String> pathParams = new ArrayList<String>();
boolean foundParam = false;
Matcher matcher = PathHelper.URI_TEMPLATE_PATTERN.matcher(PathHelper.replaceEnclosedCurlyBraces(path));
StringBuffer newSegment = new StringBuffer();
while (matcher.find())
{
foundParam = true;
String group = matcher.group();
pathParams.add(PathHelper.recoverEnclosedCurlyBraces(group));
matcher.appendReplacement(newSegment, "_resteasy_uri_parameter");
}
matcher.appendTail(newSegment);
path = newSegment.toString();
// Find last path segment
int start = path.lastIndexOf('/');
if (start < 0) start = 0;
int matrixIndex = path.indexOf(';', start);
if (matrixIndex > -1)
{
String matrixParams = path.substring(matrixIndex + 1);
path = path.substring(0, matrixIndex);
MultivaluedMapImpl<String, String> map = new MultivaluedMapImpl<String, String>();
String[] params = matrixParams.split(";");
for (String param : params)
{
String[] namevalue = param.split("=");
if (namevalue != null && namevalue.length > 0)
{
String theName = namevalue[0];
String value = "";
if (namevalue.length > 1)
{
value = namevalue[1];
}
map.add(theName, value);
}
}
map.remove(name);
for (String theName : map.keySet())
{
List<String> vals = map.get(theName);
for (Object val : vals)
{
path += ";" + theName + "=" + val.toString();
}
}
}
matrixParam(name, values);
// put back all path param expressions
if (foundParam)
{
matcher = PARAM_REPLACEMENT.matcher(path);
newSegment = new StringBuffer();
int i = 0;
while (matcher.find())
{
matcher.appendReplacement(newSegment, pathParams.get(i++));
}
matcher.appendTail(newSegment);
path = newSegment.toString();
}
return this;
}
@Override
public UriBuilder queryParam(String name, Object... values) throws IllegalArgumentException
{
for (Object value : values)
{
if (query == null) query = "";
else query += "&";
query += Encode.encodeQueryStringNameOrValue(name) + "=" + Encode.encodeQueryStringNameOrValue(value.toString());
}
return this;
}
@Override
public UriBuilder replaceQueryParam(String name, Object... values) throws IllegalArgumentException
{
if (query == null || query.equals("")) return queryParam(name, values);
String[] params = query.split("&");
query = null;
String replacedName = Encode.encodeSegment(name, false);
for (String param : params)
{
if (param.indexOf('=') >= 0)
{
String[] nv = param.split("=");
String paramName = nv[0];
if (paramName.equals(replacedName)) continue;
if (query == null) query = "";
else query += "&";
query += nv[0] + "=" + nv[1];
}
else
{
if (param.equals(replacedName)) continue;
if (query == null) query = "";
else query += "&";
query += param;
}
}
return queryParam(name, values);
}
public String getHost()
{
return host;
}
public String getScheme()
{
return scheme;
}
public int getPort()
{
return port;
}
public String getUserInfo()
{
return userInfo;
}
public String getPath()
{
return path;
}
public String getQuery()
{
return query;
}
public String getFragment()
{
return fragment;
}
@Override
public UriBuilder segment(String... segments) throws IllegalArgumentException
{
for (String segment : segments)
{
path(Encode.encodeSegment(segment, true));
}
return this;
}
@Override
public URI buildFromEncoded(Object... values) throws IllegalArgumentException, UriBuilderException
{
return buildFromValues(true, values);
}
@Override
public UriBuilder replacePath(String path)
{
if (path == null) throw new IllegalArgumentException("path was null");
this.path = Encode.encodePath(path, true);
return this;
}
}

View File

@ -1,106 +0,0 @@
package org.jboss.resteasy.spi;
import org.jboss.resteasy.util.HttpResponseCodes;
import javax.ws.rs.core.Response;
/**
* This exception should only be used by Resteasy integrators. Applications code should use WebApplicationException.
* <p/>
* This is thrown by Restasy runtime when a failure occurs.
*
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
public class Failure extends RuntimeException
{
protected int errorCode = -1;
protected boolean loggable;
protected Response response;
public Failure(String s, Response response)
{
super(s);
this.response = response;
}
public Failure(String s, Throwable throwable, Response response)
{
super(s, throwable);
this.response = response;
}
public Failure(Throwable throwable, Response response)
{
super(throwable);
this.response = response;
}
public Failure(String s, Throwable throwable)
{
super(s, throwable);
this.errorCode = HttpResponseCodes.SC_INTERNAL_SERVER_ERROR;
}
public Failure(Throwable throwable)
{
super(throwable);
this.errorCode = HttpResponseCodes.SC_INTERNAL_SERVER_ERROR;
}
public Failure(String s)
{
super(s);
this.errorCode = HttpResponseCodes.SC_INTERNAL_SERVER_ERROR;
}
public Failure(int errorCode)
{
this.errorCode = errorCode;
}
public Failure(String s, int errorCode)
{
super(s);
this.errorCode = errorCode;
}
public Failure(String s, Throwable throwable, int errorCode)
{
super(s, throwable);
this.errorCode = errorCode;
}
public Failure(Throwable throwable, int errorCode)
{
super(throwable);
this.errorCode = errorCode;
}
public int getErrorCode()
{
return errorCode;
}
public void setErrorCode(int errorCode)
{
this.errorCode = errorCode;
}
public boolean isLoggable()
{
return loggable;
}
public void setLoggable(boolean loggable)
{
this.loggable = loggable;
}
public Response getResponse()
{
return response;
}
}

View File

@ -1,71 +0,0 @@
package org.jboss.resteasy.spi;
import javax.ws.rs.core.Response;
/**
* This exception should only be used by Resteasy integrators. Applications code should use WebApplicationException
* <p/>
* This is thrown by Resteasy runtime when a failure occurs. It will be logged by the runtime
*
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
public class LoggableFailure extends Failure
{
public LoggableFailure(String s, Response response)
{
super(s, response);
}
public LoggableFailure(String s, Throwable throwable, Response response)
{
super(s, throwable, response);
}
public LoggableFailure(Throwable throwable, Response response)
{
super(throwable, response);
}
public LoggableFailure(String s, Throwable throwable)
{
super(s, throwable);
loggable = true;
}
public LoggableFailure(Throwable throwable)
{
super(throwable);
loggable = true;
}
public LoggableFailure(String s)
{
super(s);
loggable = true;
}
public LoggableFailure(int errorCode)
{
super(errorCode);
loggable = true;
}
public LoggableFailure(String s, int errorCode)
{
super(s, errorCode);
loggable = true;
}
public LoggableFailure(String s, Throwable throwable, int errorCode)
{
super(s, throwable, errorCode);
loggable = true;
}
public LoggableFailure(Throwable throwable, int errorCode)
{
super(throwable, errorCode);
loggable = true;
}
}

View File

@ -1,245 +0,0 @@
package org.jboss.resteasy.util;
import org.jboss.resteasy.specimpl.MultivaluedMapImpl;
import javax.ws.rs.core.MultivaluedMap;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
public class Encode
{
private static final Pattern PARAM_REPLACEMENT = Pattern.compile("_resteasy_uri_parameter");
/**
* Keep encoded values "%...", matrix parameters, and '/' characters intact.
*
* @param value
* @return
* @Param params whether or not to encode stuff between '{' and '}' false means don't encode
*/
public static String encodePath(String value, boolean ignorePathParams)
{
ArrayList<String> params = new ArrayList<String>();
boolean foundParam = false;
if (ignorePathParams)
{
StringBuffer newPath = new StringBuffer();
if (savePathParams(value, newPath, params))
{
foundParam = true;
value = newPath.toString();
}
}
String[] segments = value.split("/");
StringBuilder buffer = new StringBuilder();
boolean first = true;
for (String segment : segments)
{
if (!first)
{
buffer.append("/");
}
segment = encodeSegment(segment, ignorePathParams);
buffer.append(segment);
first = false;
}
String result = buffer.toString();
if (value.endsWith("/")) result += "/";
if (ignorePathParams && foundParam)
{
result = pathParamReplacement(result, params);
}
return result;
}
private static final Pattern nonCodes = Pattern.compile("%([^a-fA-F0-9]|$)");
public static String encodeNonCodes(String string)
{
Matcher matcher = nonCodes.matcher(string);
StringBuffer buf = new StringBuffer();
while (matcher.find())
{
matcher.appendReplacement(buf, "%25$1");
}
matcher.appendTail(buf);
return buf.toString();
}
public static String encodeQueryStringNameOrValue(String string)
{
StringBuffer buf = new StringBuffer();
List<String> params = new ArrayList<String>();
boolean foundParam = false;
if (savePathParams(string, buf, params))
{
foundParam = true;
string = buf.toString();
}
try
{
string = URLEncoder.encode(string, "UTF-8").replace("%25", "%");
}
catch (UnsupportedEncodingException e)
{
throw new RuntimeException(e);
}
string = encodeNonCodes(string);
if (foundParam)
{
return pathParamReplacement(string, params);
}
return string;
}
private static boolean savePathParams(String segment, StringBuffer newSegment, List<String> params)
{
boolean foundParam = false;
// Regular expressions can have '{' and '}' characters. Replace them to do match
segment = PathHelper.replaceEnclosedCurlyBraces(segment);
Matcher matcher = PathHelper.URI_TEMPLATE_PATTERN.matcher(segment);
while (matcher.find())
{
foundParam = true;
String group = matcher.group();
// Regular expressions can have '{' and '}' characters. Recover earlier replacement
params.add(PathHelper.recoverEnclosedCurlyBraces(group));
matcher.appendReplacement(newSegment, "_resteasy_uri_parameter");
}
matcher.appendTail(newSegment);
return foundParam;
}
/**
* Keep encoded values "%...", matrix parameters, and '/' characters intact.
*
* @param segment
* @return
* @Param params whether or not to encode stuff between '{' and '}' false means don't encode
*/
public static String encodeSegment(String segment, boolean ignorePathParams)
{
ArrayList<String> params = new ArrayList<String>();
boolean foundParam = false;
if (ignorePathParams)
{
StringBuffer newSegment = new StringBuffer();
if (savePathParams(segment, newSegment, params))
{
foundParam = true;
segment = newSegment.toString();
}
}
String result;
try
{
result = URLEncoder.encode(segment, "UTF-8").replace("+", "%20").replace("%3B", ";").replace("%3D", "=").replace("%25", "%");
}
catch (UnsupportedEncodingException e)
{
throw new RuntimeException(e);
}
segment = result;
if (ignorePathParams && foundParam)
{
segment = pathParamReplacement(segment, params);
}
return segment;
}
private static String pathParamReplacement(String segment, List<String> params)
{
StringBuffer newSegment = new StringBuffer();
Matcher matcher = PARAM_REPLACEMENT.matcher(segment);
int i = 0;
while (matcher.find())
{
String replacement = params.get(i++);
// double encode slashes, so that slashes stay where they are
replacement = replacement.replace("\\", "\\\\");
matcher.appendReplacement(newSegment, replacement);
}
matcher.appendTail(newSegment);
segment = newSegment.toString();
return segment;
}
/**
* decode an encoded map
*
* @param map
* @return
*/
public static MultivaluedMap<String, String> decode(MultivaluedMap<String, String> map)
{
MultivaluedMapImpl<String, String> decoded = new MultivaluedMapImpl<String, String>();
for (Map.Entry<String, List<String>> entry : map.entrySet())
{
List<String> values = entry.getValue();
for (String value : values)
{
try
{
decoded.add(URLDecoder.decode(entry.getKey(), "UTF-8"), URLDecoder.decode(value, "UTF-8"));
}
catch (UnsupportedEncodingException e)
{
throw new RuntimeException(e);
}
}
}
return decoded;
}
public static MultivaluedMap<String, String> encode(MultivaluedMap<String, String> map)
{
MultivaluedMapImpl<String, String> decoded = new MultivaluedMapImpl<String, String>();
for (Map.Entry<String, List<String>> entry : map.entrySet())
{
List<String> values = entry.getValue();
for (String value : values)
{
try
{
decoded.add(URLEncoder.encode(entry.getKey(), "UTF-8"), URLEncoder.encode(value, "UTF-8"));
}
catch (UnsupportedEncodingException e)
{
throw new RuntimeException(e);
}
}
}
return decoded;
}
public static String decode(String string)
{
try
{
return URLDecoder.decode(string, "UTF-8");
}
catch (UnsupportedEncodingException e)
{
throw new RuntimeException(e);
}
}
public static void main(String[] args) throws Exception
{
System.out.println(encodePath("foo;bar={bar: .*};stuff={ stuff : .*}", true));
}
}

View File

@ -1,319 +0,0 @@
package org.jboss.resteasy.util;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
public interface HttpResponseCodes
{
/*
* Server status codes; see RFC 2068.
*/
/**
* Status code (100) indicating the client can continue.
*/
public static final int SC_CONTINUE = 100;
/**
* Status code (101) indicating the server is switching protocols
* according to Upgrade header.
*/
public static final int SC_SWITCHING_PROTOCOLS = 101;
/**
* Status code (200) indicating the request succeeded normally.
*/
public static final int SC_OK = 200;
/**
* Status code (201) indicating the request succeeded and created
* a new resource on the server.
*/
public static final int SC_CREATED = 201;
/**
* Status code (202) indicating that a request was accepted for
* processing, but was not completed.
*/
public static final int SC_ACCEPTED = 202;
/**
* Status code (203) indicating that the meta information presented
* by the client did not originate from the server.
*/
public static final int SC_NON_AUTHORITATIVE_INFORMATION = 203;
/**
* Status code (204) indicating that the request succeeded but that
* there was no new information to return.
*/
public static final int SC_NO_CONTENT = 204;
/**
* Status code (205) indicating that the agent <em>SHOULD</em> reset
* the document view which caused the request to be sent.
*/
public static final int SC_RESET_CONTENT = 205;
/**
* Status code (206) indicating that the server has fulfilled
* the partial GET request for the resource.
*/
public static final int SC_PARTIAL_CONTENT = 206;
/**
* Status code (300) indicating that the requested resource
* corresponds to any one of a set of representations, each with
* its own specific location.
*/
public static final int SC_MULTIPLE_CHOICES = 300;
/**
* Status code (301) indicating that the resource has permanently
* moved to a new location, and that future references should use a
* new URI with their requests.
*/
public static final int SC_MOVED_PERMANENTLY = 301;
/**
* Status code (302) indicating that the resource has temporarily
* moved to another location, but that future references should
* still use the original URI to access the resource.
* <p/>
* This definition is being retained for backwards compatibility.
* SC_FOUND is now the preferred definition.
*/
public static final int SC_MOVED_TEMPORARILY = 302;
/**
* Status code (302) indicating that the resource reside
* temporarily under a different URI. Since the redirection might
* be altered on occasion, the client should continue to use the
* Request-URI for future requests.(HTTP/1.1) To represent the
* status code (302), it is recommended to use this variable.
*/
public static final int SC_FOUND = 302;
/**
* Status code (303) indicating that the response to the request
* can be found under a different URI.
*/
public static final int SC_SEE_OTHER = 303;
/**
* Status code (304) indicating that a conditional GET operation
* found that the resource was available and not modified.
*/
public static final int SC_NOT_MODIFIED = 304;
/**
* Status code (305) indicating that the requested resource
* <em>MUST</em> be accessed through the proxy given by the
* <code><em>Location</em></code> field.
*/
public static final int SC_USE_PROXY = 305;
/**
* Status code (307) indicating that the requested resource
* resides temporarily under a different URI. The temporary URI
* <em>SHOULD</em> be given by the <code><em>Location</em></code>
* field in the response.
*/
public static final int SC_TEMPORARY_REDIRECT = 307;
/**
* Status code (400) indicating the request sent by the client was
* syntactically incorrect.
*/
public static final int SC_BAD_REQUEST = 400;
/**
* Status code (401) indicating that the request requires HTTP
* authentication.
*/
public static final int SC_UNAUTHORIZED = 401;
/**
* Status code (402) reserved for future use.
*/
public static final int SC_PAYMENT_REQUIRED = 402;
/**
* Status code (403) indicating the server understood the request
* but refused to fulfill it.
*/
public static final int SC_FORBIDDEN = 403;
/**
* Status code (404) indicating that the requested resource is not
* available.
*/
public static final int SC_NOT_FOUND = 404;
/**
* Status code (405) indicating that the method specified in the
* <code><em>Request-Line</em></code> is not allowed for the resource
* identified by the <code><em>Request-URI</em></code>.
*/
public static final int SC_METHOD_NOT_ALLOWED = 405;
/**
* Status code (406) indicating that the resource identified by the
* request is only capable of generating response entities which have
* content characteristics not acceptable according to the accept
* headers sent in the request.
*/
public static final int SC_NOT_ACCEPTABLE = 406;
/**
* Status code (407) indicating that the client <em>MUST</em> first
* authenticate itself with the proxy.
*/
public static final int SC_PROXY_AUTHENTICATION_REQUIRED = 407;
/**
* Status code (408) indicating that the client did not produce a
* request within the time that the server was prepared to wait.
*/
public static final int SC_REQUEST_TIMEOUT = 408;
/**
* Status code (409) indicating that the request could not be
* completed due to a conflict with the current state of the
* resource.
*/
public static final int SC_CONFLICT = 409;
/**
* Status code (410) indicating that the resource is no longer
* available at the server and no forwarding address is known.
* This condition <em>SHOULD</em> be considered permanent.
*/
public static final int SC_GONE = 410;
/**
* Status code (411) indicating that the request cannot be handled
* without a defined <code><em>Content-Length</em></code>.
*/
public static final int SC_LENGTH_REQUIRED = 411;
/**
* Status code (412) indicating that the precondition given in one
* or more of the request-header fields evaluated to false when it
* was tested on the server.
*/
public static final int SC_PRECONDITION_FAILED = 412;
/**
* Status code (413) indicating that the server is refusing to process
* the request because the request entity is larger than the server is
* willing or able to process.
*/
public static final int SC_REQUEST_ENTITY_TOO_LARGE = 413;
/**
* Status code (414) indicating that the server is refusing to service
* the request because the <code><em>Request-URI</em></code> is longer
* than the server is willing to interpret.
*/
public static final int SC_REQUEST_URI_TOO_LONG = 414;
/**
* Status code (415) indicating that the server is refusing to service
* the request because the entity of the request is in a format not
* supported by the requested resource for the requested method.
*/
public static final int SC_UNSUPPORTED_MEDIA_TYPE = 415;
/**
* Status code (416) indicating that the server cannot serve the
* requested byte range.
*/
public static final int SC_REQUESTED_RANGE_NOT_SATISFIABLE = 416;
/**
* Status code (417) indicating that the server could not meet the
* expectation given in the Expect request header.
*/
public static final int SC_EXPECTATION_FAILED = 417;
/**
* Status code (500) indicating an error inside the HTTP server
* which prevented it from fulfilling the request.
*/
public static final int SC_INTERNAL_SERVER_ERROR = 500;
/**
* Status code (501) indicating the HTTP server does not support
* the functionality needed to fulfill the request.
*/
public static final int SC_NOT_IMPLEMENTED = 501;
/**
* Status code (502) indicating that the HTTP server received an
* invalid response from a server it consulted when acting as a
* proxy or gateway.
*/
public static final int SC_BAD_GATEWAY = 502;
/**
* Status code (503) indicating that the HTTP server is
* temporarily overloaded, and unable to handle the request.
*/
public static final int SC_SERVICE_UNAVAILABLE = 503;
/**
* Status code (504) indicating that the server did not receive
* a timely response from the upstream server while acting as
* a gateway or proxy.
*/
public static final int SC_GATEWAY_TIMEOUT = 504;
/**
* Status code (505) indicating that the server does not support
* or refuses to support the HTTP protocol version that was used
* in the request message.
*/
public static final int SC_HTTP_VERSION_NOT_SUPPORTED = 505;
}

View File

@ -1,26 +0,0 @@
package org.jboss.resteasy.util;
import javax.ws.rs.HttpMethod;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.HashSet;
import java.util.Set;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
public class IsHttpMethod
{
public static Set<String> getHttpMethods(Method method)
{
HashSet<String> methods = new HashSet<String>();
for (Annotation annotation : method.getAnnotations())
{
HttpMethod http = annotation.annotationType().getAnnotation(HttpMethod.class);
if (http != null) methods.add(http.value());
}
if (methods.size() == 0) return null;
return methods;
}
}

View File

@ -1,247 +0,0 @@
package org.jboss.resteasy.util;
import org.jboss.resteasy.spi.LoggableFailure;
import javax.ws.rs.Consumes;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import java.io.Serializable;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
public class MediaTypeHelper
{
public static MediaType getConsumes(Class declaring, AccessibleObject method)
{
Consumes consume = method.getAnnotation(Consumes.class);
if (consume == null)
{
consume = (Consumes) declaring.getAnnotation(Consumes.class);
if (consume == null) return null;
}
return MediaType.valueOf(consume.value()[0]);
}
public static MediaType getProduces(Class declaring, Method method)
{
Produces consume = method.getAnnotation(Produces.class);
if (consume == null)
{
consume = (Produces) declaring.getAnnotation(Produces.class);
}
if (consume == null) return null;
return MediaType.valueOf(consume.value()[0]);
}
public static float getQ(MediaType type)
{
float rtn = getQWithParamInfo(type);
if (rtn == 2.0F) return 1.0F;
return rtn;
}
public static float getQWithParamInfo(MediaType type)
{
if (type.getParameters() != null)
{
String val = type.getParameters().get("q");
try
{
if (val != null)
{
float rtn = Float.valueOf(val);
if (rtn > 1.0F)
throw new LoggableFailure("MediaType q value cannot be greater than 1.0: " + type.toString(), HttpResponseCodes.SC_BAD_REQUEST);
return rtn;
}
}
catch (NumberFormatException e)
{
throw new RuntimeException("MediaType q parameter must be a float: " + type, e);
}
}
return 2.0f;
}
/**
* subtypes like application/*+xml
*
* @param subtype
* @return
*/
public static boolean isCompositeWildcardSubtype(String subtype)
{
return subtype.startsWith("*+");
}
/**
* subtypes like application/*+xml
*
* @param subtype
* @return
*/
public static boolean isWildcardCompositeSubtype(String subtype)
{
return subtype.endsWith("+*");
}
public static boolean isComposite(String subtype)
{
return (isCompositeWildcardSubtype(subtype) || isWildcardCompositeSubtype(subtype));
}
private static class MediaTypeComparator implements Comparator<MediaType>, Serializable
{
private static final long serialVersionUID = -5828700121582498092L;
public int compare(MediaType mediaType2, MediaType mediaType)
{
float q = getQWithParamInfo(mediaType);
boolean wasQ = q != 2.0f;
if (q == 2.0f) q = 1.0f;
float q2 = getQWithParamInfo(mediaType2);
boolean wasQ2 = q2 != 2.0f;
if (q2 == 2.0f) q2 = 1.0f;
if (q < q2) return -1;
if (q > q2) return 1;
if (mediaType.isWildcardType() && !mediaType2.isWildcardType()) return -1;
if (!mediaType.isWildcardType() && mediaType2.isWildcardType()) return 1;
if (mediaType.isWildcardSubtype() && !mediaType2.isWildcardSubtype()) return -1;
if (!mediaType.isWildcardSubtype() && mediaType2.isWildcardSubtype()) return 1;
if (isComposite(mediaType.getSubtype()) && !isComposite(mediaType2.getSubtype()))
return -1;
if (!isComposite(mediaType.getSubtype()) && isComposite(mediaType2.getSubtype()))
return 1;
if (isCompositeWildcardSubtype(mediaType.getSubtype()) && !isCompositeWildcardSubtype(mediaType2.getSubtype()))
return -1;
if (!isCompositeWildcardSubtype(mediaType.getSubtype()) && isCompositeWildcardSubtype(mediaType2.getSubtype()))
return 1;
if (isWildcardCompositeSubtype(mediaType.getSubtype()) && !isWildcardCompositeSubtype(mediaType2.getSubtype()))
return -1;
if (!isWildcardCompositeSubtype(mediaType.getSubtype()) && isWildcardCompositeSubtype(mediaType2.getSubtype()))
return 1;
int numNonQ = 0;
if (mediaType.getParameters() != null)
{
numNonQ = mediaType.getParameters().size();
if (wasQ) numNonQ--;
}
int numNonQ2 = 0;
if (mediaType2.getParameters() != null)
{
numNonQ2 = mediaType2.getParameters().size();
if (wasQ2) numNonQ2--;
}
if (numNonQ < numNonQ2) return -1;
if (numNonQ > numNonQ2) return 1;
return 0;
}
}
public static int compareWeight(MediaType one, MediaType two)
{
return new MediaTypeComparator().compare(one, two);
}
public static boolean sameWeight(MediaType one, MediaType two)
{
return new MediaTypeComparator().compare(one, two) == 0;
}
public static void sortByWeight(List<MediaType> types)
{
if (types == null || types.size() <= 1) return;
Collections.sort(types, new MediaTypeComparator());
}
public static MediaType getBestMatch(List<MediaType> desired, List<MediaType> provided)
{
sortByWeight(desired);
sortByWeight(provided);
boolean emptyDesired = desired == null || desired.size() == 0;
boolean emptyProvided = provided == null || provided.size() == 0;
if (emptyDesired && emptyProvided) return null;
if (emptyDesired && !emptyProvided) return provided.get(0);
if (emptyProvided && !emptyDesired) return desired.get(0);
for (MediaType desire : desired)
{
for (MediaType provide : provided)
{
if (provide.isCompatible(desire)) return provide;
}
}
return null;
}
public static List<MediaType> parseHeader(String header)
{
ArrayList<MediaType> types = new ArrayList<MediaType>();
String[] medias = header.split(",");
for (int i = 0; i < medias.length; i++)
{
types.add(MediaType.valueOf(medias[i].trim()));
}
return types;
}
public static boolean equivalent(MediaType m1, MediaType m2)
{
if (m1 == m2) return true;
if (!m1.getType().equals(m2.getType())) return false;
if (!m1.getSubtype().equals(m2.getSubtype())) return false;
return equivalentParams(m1, m2);
}
public static boolean equivalentParams(MediaType m1, MediaType m2)
{
Map<String, String> params1 = m1.getParameters();
Map<String, String> params2 = m2.getParameters();
if (params1 == params2) return true;
if (params1 == null || params2 == null) return false;
if (params1.size() == 0 && params2.size() == 0) return true;
int numParams1 = params1.size();
if (params1.containsKey("q")) numParams1--;
int numParams2 = params2.size();
if (params2.containsKey("q")) numParams2--;
if (numParams1 != numParams2) return false;
if (numParams1 == 0) return true;
for (Map.Entry<String, String> entry : params1.entrySet())
{
String key = entry.getKey();
if (key.equals("q")) continue;
String value = entry.getValue();
String value2 = params2.get(key);
if (value == value2) continue; // both null
if (value == null || value2 == null) return false;
if (value.equals(value2) == false) return false;
}
return true;
}
}

View File

@ -1,86 +0,0 @@
/**
*
*/
package org.jboss.resteasy.util;
import java.util.regex.Pattern;
/**
* A utility class for handling URI template parameters. As the Java
* regulare expressions package does not handle named groups, this
* class attempts to simulate that functionality by using groups.
*
* @author Ryan J. McDonough
* @author Bill Burke
* @since 1.0
* Nov 8, 2006
*/
public class PathHelper
{
public static final String URI_PARAM_NAME_REGEX = "\\w[\\w\\.-]*";
public static final String URI_PARAM_REGEX_REGEX = "[^{}][^{}]*";
public static final String URI_PARAM_REGEX = "\\{\\s*(" + URI_PARAM_NAME_REGEX + ")\\s*(:\\s*(" + URI_PARAM_REGEX_REGEX + "))?\\}";
public static final String URI_PARAM_WITH_REGEX = "\\{\\s*(" + URI_PARAM_NAME_REGEX + ")\\s*(:\\s*(" + URI_PARAM_REGEX_REGEX + "))\\}";
public static final String URI_PARAM_WITHOUT_REGEX = "\\{(" + URI_PARAM_NAME_REGEX + ")\\}";
public static final Pattern URI_PARAM_PATTERN = Pattern.compile(URI_PARAM_REGEX);
public static final Pattern URI_PARAM_WITH_REGEX_PATTERN = Pattern.compile(URI_PARAM_WITH_REGEX);
public static final Pattern URI_PARAM_WITHOUT_REGEX_PATTERN = Pattern.compile(URI_PARAM_WITHOUT_REGEX);
/**
* A regex pattern that searches for a URI template parameter in the form of {*}
*/
public static final Pattern URI_TEMPLATE_PATTERN = Pattern.compile("(\\{([^}]+)\\})");
public static final String URI_TEMPLATE_REPLACE_PATTERN = "(.*?)";
public static String getEncodedPathInfo(String path, String contextPath)
{
if (contextPath != null && !"".equals(contextPath) && path.startsWith(contextPath))
{
path = path.substring(contextPath.length());
}
return path;
}
public static final char openCurlyReplacement = 6;
public static final char closeCurlyReplacement = 7;
public static String replaceEnclosedCurlyBraces(String str)
{
char[] chars = str.toCharArray();
int open = 0;
for (int i = 0; i < chars.length; i++)
{
if (chars[i] == '{')
{
if (open != 0) chars[i] = openCurlyReplacement;
open++;
}
else if (chars[i] == '}')
{
open--;
if (open != 0)
{
chars[i] = closeCurlyReplacement;
}
}
}
return new String(chars);
}
public static String recoverEnclosedCurlyBraces(String str)
{
return str.replace(openCurlyReplacement, '{').replace(closeCurlyReplacement, '}');
}
public static void main(String[] args) throws Exception
{
String str = replaceEnclosedCurlyBraces("{hello{world}} {foo : {bar}{{blah}}}");
System.out.println(str);
System.out.println(recoverEnclosedCurlyBraces(str));
}
}

View File

@ -19,9 +19,9 @@
package domain;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import org.jclouds.http.filters.BasicAuthentication;
import org.jclouds.rest.annotations.Endpoint;
@ -49,6 +49,7 @@ public interface VCloudExpressLoginAsyncClient {
* the token expires and you have to request a new token with this call.
*/
@POST
@Path("")
@ResponseParser(ParseLoginResponseFromHeaders.class)
@Consumes(VCloudExpressMediaType.ORGLIST_XML)
ListenableFuture<VCloudSession> login();

View File

@ -78,6 +78,7 @@ public interface CommonVCloudAsyncClient {
* @see CommonVCloudClient#getOrg
*/
@GET
@Path("")
@XMLResponseParser(OrgHandler.class)
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
@Consumes(ORG_XML)
@ -87,6 +88,7 @@ public interface CommonVCloudAsyncClient {
* @see CommonVCloudClient#getOrgNamed
*/
@GET
@Path("")
@XMLResponseParser(OrgHandler.class)
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
@Consumes(ORG_XML)
@ -97,6 +99,7 @@ public interface CommonVCloudAsyncClient {
* @see CommonVCloudClient#getCatalog
*/
@GET
@Path("")
@XMLResponseParser(CatalogHandler.class)
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
@Consumes(CATALOG_XML)
@ -106,6 +109,7 @@ public interface CommonVCloudAsyncClient {
* @see CommonVCloudClient#findCatalogInOrgNamed
*/
@GET
@Path("")
@XMLResponseParser(CatalogHandler.class)
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
@Consumes(CATALOG_XML)
@ -117,6 +121,7 @@ public interface CommonVCloudAsyncClient {
* @see CommonVCloudClient#getCatalogItem
*/
@GET
@Path("")
@Consumes(CATALOGITEM_XML)
@XMLResponseParser(CatalogItemHandler.class)
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
@ -126,6 +131,7 @@ public interface CommonVCloudAsyncClient {
* @see CommonVCloudClient#getCatalogItemInOrg
*/
@GET
@Path("")
@Consumes(CATALOGITEM_XML)
@XMLResponseParser(CatalogItemHandler.class)
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
@ -138,6 +144,7 @@ public interface CommonVCloudAsyncClient {
* @see CommonVCloudClient#findNetworkInOrgVDCNamed
*/
@GET
@Path("")
@Consumes(NETWORK_XML)
@XMLResponseParser(OrgNetworkHandler.class)
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
@ -150,6 +157,7 @@ public interface CommonVCloudAsyncClient {
* @see CommonVCloudClient#getNetwork
*/
@GET
@Path("")
@Consumes(NETWORK_XML)
@XMLResponseParser(OrgNetworkHandler.class)
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
@ -159,6 +167,7 @@ public interface CommonVCloudAsyncClient {
* @see CommonVCloudClient#getVDC(URI)
*/
@GET
@Path("")
@XMLResponseParser(VDCHandler.class)
@Consumes(VDC_XML)
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
@ -168,6 +177,7 @@ public interface CommonVCloudAsyncClient {
* @see CommonVCloudClient#findVDCInOrgNamed(String, String)
*/
@GET
@Path("")
@XMLResponseParser(VDCHandler.class)
@Consumes(VDC_XML)
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
@ -179,6 +189,7 @@ public interface CommonVCloudAsyncClient {
* @see CommonVCloudClient#getTasksList
*/
@GET
@Path("")
@Consumes(TASKSLIST_XML)
@XMLResponseParser(TasksListHandler.class)
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
@ -188,6 +199,7 @@ public interface CommonVCloudAsyncClient {
* @see CommonVCloudClient#findTasksListInOrgNamed
*/
@GET
@Path("")
@Consumes(TASKSLIST_XML)
@XMLResponseParser(TasksListHandler.class)
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
@ -198,6 +210,7 @@ public interface CommonVCloudAsyncClient {
* @see CommonVCloudClient#getTask
*/
@GET
@Path("")
@Consumes(TASK_XML)
@XMLResponseParser(TaskHandler.class)
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
@ -210,5 +223,4 @@ public interface CommonVCloudAsyncClient {
@Path("/action/cancel")
ListenableFuture<Void> cancelTask(@EndpointParam URI taskId);
}

View File

@ -94,6 +94,7 @@ public interface VCloudAsyncClient extends CommonVCloudAsyncClient {
* @see VCloudClient#listOrgs
*/
@GET
@Path("")
@Endpoint(OrgList.class)
@XMLResponseParser(OrgListHandler.class)
@Consumes(VCloudMediaType.ORGLIST_XML)
@ -103,6 +104,7 @@ public interface VCloudAsyncClient extends CommonVCloudAsyncClient {
* @see VCloudClient#getVAppTemplate
*/
@GET
@Path("")
@Consumes(VAPPTEMPLATE_XML)
@XMLResponseParser(VAppTemplateHandler.class)
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
@ -122,6 +124,7 @@ public interface VCloudAsyncClient extends CommonVCloudAsyncClient {
* @see VCloudClient#findVAppTemplateInOrgCatalogNamed
*/
@GET
@Path("")
@Consumes(VAPPTEMPLATE_XML)
@XMLResponseParser(VAppTemplateHandler.class)
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
@ -134,7 +137,7 @@ public interface VCloudAsyncClient extends CommonVCloudAsyncClient {
* @see VCloudClient#instantiateVAppTemplateInVDC
*/
@POST
@Path("action/instantiateVAppTemplate")
@Path("/action/instantiateVAppTemplate")
@Produces("application/vnd.vmware.vcloud.instantiateVAppTemplateParams+xml")
@Consumes(VAPP_XML)
@XMLResponseParser(VAppHandler.class)
@ -161,6 +164,7 @@ public interface VCloudAsyncClient extends CommonVCloudAsyncClient {
* @see VCloudClient#findVAppInOrgVDCNamed
*/
@GET
@Path("")
@Consumes(VAPP_XML)
@XMLResponseParser(VAppHandler.class)
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
@ -173,6 +177,7 @@ public interface VCloudAsyncClient extends CommonVCloudAsyncClient {
* @see VCloudClient#getVApp
*/
@GET
@Path("")
@Consumes(VAPP_XML)
@XMLResponseParser(VAppHandler.class)
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
@ -182,6 +187,7 @@ public interface VCloudAsyncClient extends CommonVCloudAsyncClient {
* @see VCloudClient#getVm
*/
@GET
@Path("")
@Consumes(VM_XML)
@XMLResponseParser(VmHandler.class)
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
@ -299,6 +305,7 @@ public interface VCloudAsyncClient extends CommonVCloudAsyncClient {
* @see CommonVCloudClient#deleteVApp
*/
@DELETE
@Path("")
@ExceptionParser(ReturnVoidOnNotFoundOr404.class)
@XMLResponseParser(TaskHandler.class)
ListenableFuture<? extends Task> deleteVApp(@EndpointParam URI vAppId);

View File

@ -76,6 +76,7 @@ public interface VCloudExpressAsyncClient extends CommonVCloudAsyncClient {
* @see VCloudClient#getVAppTemplate
*/
@GET
@Path("")
@Consumes(VAPPTEMPLATE_XML)
@XMLResponseParser(VCloudExpressVAppTemplateHandler.class)
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
@ -85,6 +86,7 @@ public interface VCloudExpressAsyncClient extends CommonVCloudAsyncClient {
* @see VCloudClient#findVAppTemplateInOrgCatalogNamed
*/
@GET
@Path("")
@Consumes(VAPPTEMPLATE_XML)
@XMLResponseParser(VCloudExpressVAppTemplateHandler.class)
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
@ -98,6 +100,7 @@ public interface VCloudExpressAsyncClient extends CommonVCloudAsyncClient {
*/
@Override
@GET
@Path("")
@Consumes(NETWORK_XML)
@XMLResponseParser(OrgNetworkFromVCloudExpressNetworkHandler.class)
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
@ -111,6 +114,7 @@ public interface VCloudExpressAsyncClient extends CommonVCloudAsyncClient {
*/
@Override
@GET
@Path("")
@Consumes(NETWORK_XML)
@XMLResponseParser(OrgNetworkFromVCloudExpressNetworkHandler.class)
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
@ -120,7 +124,7 @@ public interface VCloudExpressAsyncClient extends CommonVCloudAsyncClient {
* @see VCloudExpressClient#instantiateVAppTemplateInVDC
*/
@POST
@Path("action/instantiateVAppTemplate")
@Path("/action/instantiateVAppTemplate")
@Produces("application/vnd.vmware.vcloud.instantiateVAppTemplateParams+xml")
@Consumes(VAPP_XML)
@XMLResponseParser(VCloudExpressVAppHandler.class)
@ -147,6 +151,7 @@ public interface VCloudExpressAsyncClient extends CommonVCloudAsyncClient {
* @see VCloudClient#findVAppInOrgVDCNamed
*/
@GET
@Path("")
@Consumes(VAPP_XML)
@XMLResponseParser(VCloudExpressVAppHandler.class)
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
@ -159,6 +164,7 @@ public interface VCloudExpressAsyncClient extends CommonVCloudAsyncClient {
* @see VCloudClient#getVApp
*/
@GET
@Path("")
@Consumes(VAPP_XML)
@XMLResponseParser(VCloudExpressVAppHandler.class)
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
@ -229,6 +235,7 @@ public interface VCloudExpressAsyncClient extends CommonVCloudAsyncClient {
* @see CommonVCloudClient#deleteVApp
*/
@DELETE
@Path("")
@ExceptionParser(ReturnVoidOnNotFoundOr404.class)
ListenableFuture<Void> deleteVApp(@EndpointParam URI vAppId);

View File

@ -58,9 +58,7 @@ import com.google.common.util.concurrent.ListenableFuture;
* Provides access to eCloud resources via their REST API.
* <p/>
*
* @see <a href=
* "http://support.theenterprisecloud.com/kb/default.asp?id=645&Lang=1&SID="
* />
* @see <a href= "http://support.theenterprisecloud.com/kb/default.asp?id=645&Lang=1&SID=" />
* @author Adrian Cole
*/
@RequestFilters(SetVCloudTokenCookie.class)
@ -70,22 +68,24 @@ public interface TerremarkECloudAsyncClient extends TerremarkVCloudAsyncClient {
* @see TerremarkVCloudExpressClient#getAllInternetServices
*/
@GET
@Path("")
@Consumes(INTERNETSERVICESLIST_XML)
@XMLResponseParser(InternetServicesHandler.class)
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
@Override
ListenableFuture<? extends Set<InternetService>> getAllInternetServicesInVDC(
@EndpointParam(parser = VDCURIToInternetServicesEndpoint.class) URI vDCId);
@EndpointParam(parser = VDCURIToInternetServicesEndpoint.class) URI vDCId);
/**
* @see TerremarkVCloudExpressClient#activatePublicIpInVDC
*/
@POST
@Path("")
@Consumes(PUBLICIP_XML)
@XMLResponseParser(PublicIpAddressesHandler.class)
@ExceptionParser(ReturnVoidOnNotFoundOr404.class)
ListenableFuture<PublicIpAddress> activatePublicIpInVDC(
@EndpointParam(parser = VDCURIToPublicIPsEndpoint.class) URI vDCId);
@EndpointParam(parser = VDCURIToPublicIPsEndpoint.class) URI vDCId);
/**
* @see TerremarkVCloudExpressClient#addInternetServiceToExistingIp
@ -98,8 +98,8 @@ public interface TerremarkECloudAsyncClient extends TerremarkVCloudAsyncClient {
@MapBinder(AddInternetServiceOptions.class)
@Override
ListenableFuture<? extends InternetService> addInternetServiceToExistingIp(@EndpointParam URI existingIpId,
@MapPayloadParam("name") String serviceName, @MapPayloadParam("protocol") Protocol protocol,
@MapPayloadParam("port") int port, AddInternetServiceOptions... options);
@MapPayloadParam("name") String serviceName, @MapPayloadParam("protocol") Protocol protocol,
@MapPayloadParam("port") int port, AddInternetServiceOptions... options);
/**
* @see TerremarkVCloudExpressClient#getInternetServicesOnPublicIP
@ -116,6 +116,7 @@ public interface TerremarkECloudAsyncClient extends TerremarkVCloudAsyncClient {
* @see TerremarkVCloudExpressClient#getInternetService
*/
@GET
@Path("")
@Consumes(INTERNETSERVICESLIST_XML)
@XMLResponseParser(InternetServiceHandler.class)
@ExceptionParser(ReturnNullOnNotFoundOr404.class)

View File

@ -112,6 +112,7 @@ public interface TerremarkVCloudAsyncClient extends VCloudExpressAsyncClient {
*/
@Override
@GET
@Path("")
@Consumes(CATALOGITEM_XML)
@XMLResponseParser(TerremarkCatalogItemHandler.class)
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
@ -125,6 +126,7 @@ public interface TerremarkVCloudAsyncClient extends VCloudExpressAsyncClient {
*/
@Override
@GET
@Path("")
@Consumes(CATALOGITEM_XML)
@XMLResponseParser(TerremarkCatalogItemHandler.class)
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
@ -132,6 +134,7 @@ public interface TerremarkVCloudAsyncClient extends VCloudExpressAsyncClient {
@Override
@GET
@Path("")
@XMLResponseParser(TerremarkOrgHandler.class)
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
@Consumes(ORG_XML)
@ -142,6 +145,7 @@ public interface TerremarkVCloudAsyncClient extends VCloudExpressAsyncClient {
*/
@Override
@GET
@Path("")
@XMLResponseParser(TerremarkOrgHandler.class)
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
@Consumes(ORG_XML)
@ -152,6 +156,7 @@ public interface TerremarkVCloudAsyncClient extends VCloudExpressAsyncClient {
* Terremark does not have multiple catalogs, so we ignore this parameter.
*/
@GET
@Path("")
@Override
@XMLResponseParser(CatalogHandler.class)
@Consumes(CATALOG_XML)
@ -163,6 +168,7 @@ public interface TerremarkVCloudAsyncClient extends VCloudExpressAsyncClient {
*/
@Override
@GET
@Path("")
@XMLResponseParser(TerremarkVDCHandler.class)
@Consumes(VDC_XML)
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
@ -172,6 +178,7 @@ public interface TerremarkVCloudAsyncClient extends VCloudExpressAsyncClient {
* @see VCloudExpressClient#findVDCInOrgNamed
*/
@GET
@Path("")
@Override
@XMLResponseParser(TerremarkVDCHandler.class)
@Consumes(VDC_XML)
@ -185,7 +192,7 @@ public interface TerremarkVCloudAsyncClient extends VCloudExpressAsyncClient {
*/
@Override
@POST
@Path("action/instantiateVAppTemplate")
@Path("/action/instantiateVAppTemplate")
@Produces("application/vnd.vmware.vcloud.instantiateVAppTemplateParams+xml")
@Consumes(VAPP_XML)
@XMLResponseParser(VCloudExpressVAppHandler.class)
@ -199,6 +206,7 @@ public interface TerremarkVCloudAsyncClient extends VCloudExpressAsyncClient {
* @see TerremarkVCloudExpressClient#getAllInternetServicesInVDC
*/
@GET
@Path("")
@Consumes(INTERNETSERVICESLIST_XML)
@XMLResponseParser(InternetServicesHandler.class)
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
@ -222,6 +230,7 @@ public interface TerremarkVCloudAsyncClient extends VCloudExpressAsyncClient {
* @see TerremarkVCloudExpressClient#deletePublicIp
*/
@DELETE
@Path("")
@ExceptionParser(ReturnVoidOnDeleteDefaultIp.class)
ListenableFuture<Void> deletePublicIp(@EndpointParam URI ipId);
@ -239,6 +248,7 @@ public interface TerremarkVCloudAsyncClient extends VCloudExpressAsyncClient {
* @see TerremarkVCloudExpressClient#getPublicIp
*/
@GET
@Path("")
@Consumes(PUBLICIP_XML)
@XMLResponseParser(InternetServicesHandler.class)
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
@ -259,6 +269,7 @@ public interface TerremarkVCloudAsyncClient extends VCloudExpressAsyncClient {
* @see TerremarkVCloudExpressClient#deleteInternetService
*/
@DELETE
@Path("")
@ExceptionParser(ReturnVoidOnNotFoundOr404.class)
ListenableFuture<Void> deleteInternetService(@EndpointParam URI internetServiceId);
@ -266,6 +277,7 @@ public interface TerremarkVCloudAsyncClient extends VCloudExpressAsyncClient {
* @see TerremarkVCloudExpressClient#getInternetService
*/
@GET
@Path("")
@Consumes(INTERNETSERVICESLIST_XML)
@XMLResponseParser(InternetServiceHandler.class)
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
@ -298,6 +310,7 @@ public interface TerremarkVCloudAsyncClient extends VCloudExpressAsyncClient {
* @see TerremarkVCloudExpressClient#getNode
*/
@GET
@Path("")
@XMLResponseParser(NodeHandler.class)
@Consumes(NODESERVICE_XML)
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
@ -307,6 +320,7 @@ public interface TerremarkVCloudAsyncClient extends VCloudExpressAsyncClient {
* @see TerremarkVCloudExpressClient#configureNode
*/
@PUT
@Path("")
@Produces(NODESERVICE_XML)
@Consumes(NODESERVICE_XML)
@XMLResponseParser(NodeHandler.class)
@ -318,6 +332,7 @@ public interface TerremarkVCloudAsyncClient extends VCloudExpressAsyncClient {
* @see TerremarkVCloudExpressClient#deleteNode
*/
@DELETE
@Path("")
@ExceptionParser(ReturnVoidOnNotFoundOr404.class)
ListenableFuture<Void> deleteNode(@EndpointParam URI nodeId);
@ -325,17 +340,20 @@ public interface TerremarkVCloudAsyncClient extends VCloudExpressAsyncClient {
* @see TerremarkVCloudExpressClient#configureVApp
*/
@PUT
@Path("")
@Produces(VAPP_XML)
@Consumes(VAPP_XML)
@MapBinder(BindVAppConfigurationToXmlPayload.class)
@ResponseParser(ParseTaskFromLocationHeader.class)
ListenableFuture<? extends Task> configureVApp(
@EndpointParam(parser = BindVAppConfigurationToXmlPayload.class) VCloudExpressVApp vApp, VAppConfiguration configuration);
@EndpointParam(parser = BindVAppConfigurationToXmlPayload.class) VCloudExpressVApp vApp,
VAppConfiguration configuration);
/**
* @see TerremarkVCloudClient#getCustomizationOptions
*/
@GET
@Path("")
@XMLResponseParser(CustomizationParametersHandler.class)
@Consumes(CATALOGITEMCUSTOMIZATIONPARAMETERS_XML)
ListenableFuture<? extends CustomizationParameters> getCustomizationOptions(@EndpointParam URI customization);

View File

@ -31,6 +31,7 @@ import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import org.jclouds.rest.annotations.EndpointParam;
@ -61,8 +62,7 @@ import com.google.common.util.concurrent.ListenableFuture;
* Provides access to VCloud resources via their REST API.
* <p/>
*
* @see <a href="https://community.vcloudexpress.terremark.com/en-us/discussion_forums/f/60.aspx"
* />
* @see <a href="https://community.vcloudexpress.terremark.com/en-us/discussion_forums/f/60.aspx" />
* @author Adrian Cole
*/
@RequestFilters(SetVCloudTokenCookie.class)
@ -71,39 +71,43 @@ public interface TerremarkVCloudExpressAsyncClient extends TerremarkVCloudAsyncC
* @see TerremarkVCloudExpressClient#addInternetServiceToVDC
*/
@POST
@Path("")
@Produces(INTERNETSERVICE_XML)
@Consumes(INTERNETSERVICE_XML)
@XMLResponseParser(InternetServiceHandler.class)
@MapBinder(AddInternetServiceOptions.class)
ListenableFuture<? extends InternetService> addInternetServiceToVDC(
@EndpointParam(parser = VDCURIToInternetServicesEndpoint.class) URI vDCId,
@MapPayloadParam("name") String serviceName, @MapPayloadParam("protocol") Protocol protocol,
@MapPayloadParam("port") int port, AddInternetServiceOptions... options);
@EndpointParam(parser = VDCURIToInternetServicesEndpoint.class) URI vDCId,
@MapPayloadParam("name") String serviceName, @MapPayloadParam("protocol") Protocol protocol,
@MapPayloadParam("port") int port, AddInternetServiceOptions... options);
/**
* @see TerremarkVCloudExpressClient#findKeyPairInOrgNamed
*/
@GET
@Path("")
@XMLResponseParser(KeyPairByNameHandler.class)
@Consumes(KEYSLIST_XML)
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
ListenableFuture<? extends KeyPair> findKeyPairInOrg(
@Nullable @EndpointParam(parser = OrgURIToKeysListEndpoint.class) URI org, String keyName);
@Nullable @EndpointParam(parser = OrgURIToKeysListEndpoint.class) URI org, String keyName);
/**
* @see TerremarkVCloudExpressClient#listKeyPairsInOrgNamed
*/
@GET
@Path("")
@Consumes(KEYSLIST_XML)
@XMLResponseParser(KeyPairsHandler.class)
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
ListenableFuture<? extends Set<KeyPair>> listKeyPairsInOrg(
@Nullable @EndpointParam(parser = OrgURIToKeysListEndpoint.class) URI org);
@Nullable @EndpointParam(parser = OrgURIToKeysListEndpoint.class) URI org);
/**
* @see TerremarkVCloudExpressClient#listKeyPairs
*/
@GET
@Path("")
@Consumes(KEYSLIST_XML)
@XMLResponseParser(KeyPairsHandler.class)
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
@ -113,18 +117,20 @@ public interface TerremarkVCloudExpressAsyncClient extends TerremarkVCloudAsyncC
* @see TerremarkVCloudExpressClient#generateKeyPairInOrg
*/
@POST
@Path("")
@Produces(KEYSLIST_XML)
@Consumes(KEYSLIST_XML)
@XMLResponseParser(KeyPairHandler.class)
@MapBinder(BindCreateKeyToXmlPayload.class)
ListenableFuture<? extends KeyPair> generateKeyPairInOrg(
@EndpointParam(parser = OrgURIToKeysListEndpoint.class) URI org, @MapPayloadParam("name") String name,
@MapPayloadParam("isDefault") boolean makeDefault);
@EndpointParam(parser = OrgURIToKeysListEndpoint.class) URI org, @MapPayloadParam("name") String name,
@MapPayloadParam("isDefault") boolean makeDefault);
/**
* @see TerremarkVCloudExpressClient#getKeyPair
*/
@GET
@Path("")
@XMLResponseParser(KeyPairHandler.class)
@Consumes(APPLICATION_XML)
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
@ -149,6 +155,7 @@ public interface TerremarkVCloudExpressAsyncClient extends TerremarkVCloudAsyncC
* @see TerremarkVCloudExpressClient#deleteKeyPair
*/
@DELETE
@Path("")
@ExceptionParser(ReturnVoidOnNotFoundOr404.class)
ListenableFuture<Void> deleteKeyPair(@EndpointParam URI keyId);