mirror of https://github.com/apache/jclouds.git
Issue 76: added support for @Produces and @Consumes, replaced @EntityBinder with @DecoratorParam so that we can manipulate more things then just entities; organized rest module
git-svn-id: http://jclouds.googlecode.com/svn/trunk@1952 3d8758e0-26b5-11de-8745-db77d3ebf521
This commit is contained in:
parent
b3a9e76d21
commit
5b7878b0ea
|
@ -34,7 +34,7 @@ import javax.ws.rs.PUT;
|
||||||
import javax.ws.rs.Path;
|
import javax.ws.rs.Path;
|
||||||
import javax.ws.rs.PathParam;
|
import javax.ws.rs.PathParam;
|
||||||
|
|
||||||
import org.jclouds.aws.s3.binders.S3ObjectBinder;
|
import org.jclouds.aws.s3.decorators.AddS3ObjectEntity;
|
||||||
import org.jclouds.aws.s3.domain.BucketMetadata;
|
import org.jclouds.aws.s3.domain.BucketMetadata;
|
||||||
import org.jclouds.aws.s3.domain.ListBucketResponse;
|
import org.jclouds.aws.s3.domain.ListBucketResponse;
|
||||||
import org.jclouds.aws.s3.domain.ObjectMetadata;
|
import org.jclouds.aws.s3.domain.ObjectMetadata;
|
||||||
|
@ -55,17 +55,17 @@ import org.jclouds.blobstore.functions.ThrowKeyNotFoundOn404;
|
||||||
import org.jclouds.http.functions.ParseETagHeader;
|
import org.jclouds.http.functions.ParseETagHeader;
|
||||||
import org.jclouds.http.functions.ReturnFalseOn404;
|
import org.jclouds.http.functions.ReturnFalseOn404;
|
||||||
import org.jclouds.http.options.GetOptions;
|
import org.jclouds.http.options.GetOptions;
|
||||||
import org.jclouds.rest.Endpoint;
|
import org.jclouds.rest.annotations.DecoratorParam;
|
||||||
import org.jclouds.rest.EntityParam;
|
import org.jclouds.rest.annotations.Endpoint;
|
||||||
import org.jclouds.rest.ExceptionParser;
|
import org.jclouds.rest.annotations.ExceptionParser;
|
||||||
import org.jclouds.rest.HostPrefixParam;
|
import org.jclouds.rest.annotations.HostPrefixParam;
|
||||||
import org.jclouds.rest.ParamParser;
|
import org.jclouds.rest.annotations.ParamParser;
|
||||||
import org.jclouds.rest.QueryParams;
|
import org.jclouds.rest.annotations.QueryParams;
|
||||||
import org.jclouds.rest.RequestFilters;
|
import org.jclouds.rest.annotations.RequestFilters;
|
||||||
import org.jclouds.rest.ResponseParser;
|
import org.jclouds.rest.annotations.ResponseParser;
|
||||||
import org.jclouds.rest.SkipEncoding;
|
import org.jclouds.rest.annotations.SkipEncoding;
|
||||||
import org.jclouds.rest.VirtualHost;
|
import org.jclouds.rest.annotations.VirtualHost;
|
||||||
import org.jclouds.rest.XMLResponseParser;
|
import org.jclouds.rest.annotations.XMLResponseParser;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides access to S3 via their REST API.
|
* Provides access to S3 via their REST API.
|
||||||
|
@ -181,7 +181,7 @@ public interface S3BlobStore extends BlobStore<BucketMetadata, ObjectMetadata, S
|
||||||
@ResponseParser(ParseETagHeader.class)
|
@ResponseParser(ParseETagHeader.class)
|
||||||
Future<byte[]> putBlob(
|
Future<byte[]> putBlob(
|
||||||
@HostPrefixParam String bucketName,
|
@HostPrefixParam String bucketName,
|
||||||
@PathParam("key") @ParamParser(BlobKey.class) @EntityParam(S3ObjectBinder.class) S3Object object);
|
@PathParam("key") @ParamParser(BlobKey.class) @DecoratorParam(AddS3ObjectEntity.class) S3Object object);
|
||||||
|
|
||||||
@PUT
|
@PUT
|
||||||
@Path("/")
|
@Path("/")
|
||||||
|
|
|
@ -34,8 +34,8 @@ import javax.ws.rs.PUT;
|
||||||
import javax.ws.rs.Path;
|
import javax.ws.rs.Path;
|
||||||
import javax.ws.rs.PathParam;
|
import javax.ws.rs.PathParam;
|
||||||
|
|
||||||
import org.jclouds.aws.s3.binders.AccessControlListBinder;
|
import org.jclouds.aws.s3.decorators.AddACLAsXMLEntity;
|
||||||
import org.jclouds.aws.s3.binders.S3ObjectBinder;
|
import org.jclouds.aws.s3.decorators.AddS3ObjectEntity;
|
||||||
import org.jclouds.aws.s3.domain.AccessControlList;
|
import org.jclouds.aws.s3.domain.AccessControlList;
|
||||||
import org.jclouds.aws.s3.domain.BucketMetadata;
|
import org.jclouds.aws.s3.domain.BucketMetadata;
|
||||||
import org.jclouds.aws.s3.domain.ListBucketResponse;
|
import org.jclouds.aws.s3.domain.ListBucketResponse;
|
||||||
|
@ -62,21 +62,18 @@ import org.jclouds.blobstore.functions.ThrowKeyNotFoundOn404;
|
||||||
import org.jclouds.http.functions.ParseETagHeader;
|
import org.jclouds.http.functions.ParseETagHeader;
|
||||||
import org.jclouds.http.functions.ReturnFalseOn404;
|
import org.jclouds.http.functions.ReturnFalseOn404;
|
||||||
import org.jclouds.http.options.GetOptions;
|
import org.jclouds.http.options.GetOptions;
|
||||||
import org.jclouds.rest.Endpoint;
|
import org.jclouds.rest.annotations.DecoratorParam;
|
||||||
import org.jclouds.rest.EntityParam;
|
import org.jclouds.rest.annotations.Endpoint;
|
||||||
import org.jclouds.rest.ExceptionParser;
|
import org.jclouds.rest.annotations.ExceptionParser;
|
||||||
import org.jclouds.rest.Headers;
|
import org.jclouds.rest.annotations.Headers;
|
||||||
import org.jclouds.rest.HostPrefixParam;
|
import org.jclouds.rest.annotations.HostPrefixParam;
|
||||||
import org.jclouds.rest.ParamParser;
|
import org.jclouds.rest.annotations.ParamParser;
|
||||||
import org.jclouds.rest.QueryParams;
|
import org.jclouds.rest.annotations.QueryParams;
|
||||||
import org.jclouds.rest.RequestFilters;
|
import org.jclouds.rest.annotations.RequestFilters;
|
||||||
import org.jclouds.rest.ResponseParser;
|
import org.jclouds.rest.annotations.ResponseParser;
|
||||||
import org.jclouds.rest.SkipEncoding;
|
import org.jclouds.rest.annotations.SkipEncoding;
|
||||||
import org.jclouds.rest.VirtualHost;
|
import org.jclouds.rest.annotations.VirtualHost;
|
||||||
import org.jclouds.rest.XMLResponseParser;
|
import org.jclouds.rest.annotations.XMLResponseParser;
|
||||||
import org.jclouds.rest.binders.HttpRequestOptionsBinder;
|
|
||||||
|
|
||||||
import com.google.inject.internal.Nullable;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides access to S3 via their REST API.
|
* Provides access to S3 via their REST API.
|
||||||
|
@ -209,7 +206,7 @@ public interface S3Connection {
|
||||||
@ResponseParser(ParseETagHeader.class)
|
@ResponseParser(ParseETagHeader.class)
|
||||||
Future<byte[]> putObject(
|
Future<byte[]> putObject(
|
||||||
@HostPrefixParam String bucketName,
|
@HostPrefixParam String bucketName,
|
||||||
@PathParam("key") @ParamParser(BlobKey.class) @EntityParam(S3ObjectBinder.class) S3Object object,
|
@PathParam("key") @ParamParser(BlobKey.class) @DecoratorParam(AddS3ObjectEntity.class) S3Object object,
|
||||||
PutObjectOptions... options);
|
PutObjectOptions... options);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -237,7 +234,7 @@ public interface S3Connection {
|
||||||
@Path("/")
|
@Path("/")
|
||||||
@ExceptionParser(ReturnTrueIfBucketAlreadyOwnedByYou.class)
|
@ExceptionParser(ReturnTrueIfBucketAlreadyOwnedByYou.class)
|
||||||
Future<Boolean> putBucketIfNotExists(@HostPrefixParam String bucketName,
|
Future<Boolean> putBucketIfNotExists(@HostPrefixParam String bucketName,
|
||||||
@Nullable @EntityParam(HttpRequestOptionsBinder.class) PutBucketOptions... options);
|
PutBucketOptions... options);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deletes the bucket, if it is empty.
|
* Deletes the bucket, if it is empty.
|
||||||
|
@ -378,7 +375,7 @@ public interface S3Connection {
|
||||||
@Path("/")
|
@Path("/")
|
||||||
@QueryParams(keys = "acl")
|
@QueryParams(keys = "acl")
|
||||||
Future<Boolean> putBucketACL(@HostPrefixParam String bucketName,
|
Future<Boolean> putBucketACL(@HostPrefixParam String bucketName,
|
||||||
@EntityParam(AccessControlListBinder.class) AccessControlList acl);
|
@DecoratorParam(AddACLAsXMLEntity.class) AccessControlList acl);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A GET request operation directed at an object or bucket URI with the "acl" parameter retrieves
|
* A GET request operation directed at an object or bucket URI with the "acl" parameter retrieves
|
||||||
|
@ -421,6 +418,6 @@ public interface S3Connection {
|
||||||
@QueryParams(keys = "acl")
|
@QueryParams(keys = "acl")
|
||||||
@Path("{key}")
|
@Path("{key}")
|
||||||
Future<Boolean> putObjectACL(@HostPrefixParam String bucketName, @PathParam("key") String key,
|
Future<Boolean> putObjectACL(@HostPrefixParam String bucketName, @PathParam("key") String key,
|
||||||
@EntityParam(AccessControlListBinder.class) AccessControlList acl);
|
@DecoratorParam(AddACLAsXMLEntity.class) AccessControlList acl);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
* under the License.
|
* under the License.
|
||||||
* ====================================================================
|
* ====================================================================
|
||||||
*/
|
*/
|
||||||
package org.jclouds.aws.s3.binders;
|
package org.jclouds.aws.s3.decorators;
|
||||||
|
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
|
@ -37,14 +37,14 @@ import org.jclouds.aws.s3.domain.AccessControlList.Grant;
|
||||||
import org.jclouds.aws.s3.domain.AccessControlList.GroupGrantee;
|
import org.jclouds.aws.s3.domain.AccessControlList.GroupGrantee;
|
||||||
import org.jclouds.aws.s3.reference.S3Constants;
|
import org.jclouds.aws.s3.reference.S3Constants;
|
||||||
import org.jclouds.http.HttpRequest;
|
import org.jclouds.http.HttpRequest;
|
||||||
import org.jclouds.rest.binders.EntityBinder;
|
import org.jclouds.rest.decorators.RequestDecorator;
|
||||||
import org.jclouds.util.Utils;
|
import org.jclouds.util.Utils;
|
||||||
|
|
||||||
import com.jamesmurty.utils.XMLBuilder;
|
import com.jamesmurty.utils.XMLBuilder;
|
||||||
|
|
||||||
public class AccessControlListBinder implements EntityBinder {
|
public class AddACLAsXMLEntity implements RequestDecorator {
|
||||||
|
|
||||||
public void addEntityToRequest(Object entity, HttpRequest request) {
|
public HttpRequest decorateRequest(HttpRequest request, Object entity) {
|
||||||
AccessControlList from = (AccessControlList) entity;
|
AccessControlList from = (AccessControlList) entity;
|
||||||
Properties outputProperties = new Properties();
|
Properties outputProperties = new Properties();
|
||||||
outputProperties.put(javax.xml.transform.OutputKeys.OMIT_XML_DECLARATION, "yes");
|
outputProperties.put(javax.xml.transform.OutputKeys.OMIT_XML_DECLARATION, "yes");
|
||||||
|
@ -57,6 +57,7 @@ public class AccessControlListBinder implements EntityBinder {
|
||||||
Utils.rethrowIfRuntime(e);
|
Utils.rethrowIfRuntime(e);
|
||||||
throw new RuntimeException("error transforming acl: " + from, e);
|
throw new RuntimeException("error transforming acl: " + from, e);
|
||||||
}
|
}
|
||||||
|
return request;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected XMLBuilder generateBuilder(AccessControlList acl) throws ParserConfigurationException,
|
protected XMLBuilder generateBuilder(AccessControlList acl) throws ParserConfigurationException,
|
|
@ -21,28 +21,27 @@
|
||||||
* under the License.
|
* under the License.
|
||||||
* ====================================================================
|
* ====================================================================
|
||||||
*/
|
*/
|
||||||
package org.jclouds.aws.s3.binders;
|
package org.jclouds.aws.s3.decorators;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkArgument;
|
import static com.google.common.base.Preconditions.checkArgument;
|
||||||
import static org.jclouds.blobstore.reference.BlobStoreConstants.PROPERTY_USER_METADATA_PREFIX;
|
import static org.jclouds.blobstore.reference.BlobStoreConstants.PROPERTY_USER_METADATA_PREFIX;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Named;
|
||||||
import javax.ws.rs.core.HttpHeaders;
|
import javax.ws.rs.core.HttpHeaders;
|
||||||
|
|
||||||
import org.jclouds.aws.s3.domain.S3Object;
|
import org.jclouds.aws.s3.domain.S3Object;
|
||||||
import org.jclouds.blobstore.binders.BlobBinder;
|
import org.jclouds.blobstore.decorators.AddBlobEntity;
|
||||||
import org.jclouds.blobstore.domain.Blob;
|
import org.jclouds.blobstore.domain.Blob;
|
||||||
import org.jclouds.http.HttpRequest;
|
import org.jclouds.http.HttpRequest;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
public class AddS3ObjectEntity extends AddBlobEntity {
|
||||||
import javax.inject.Named;
|
|
||||||
|
|
||||||
public class S3ObjectBinder extends BlobBinder {
|
|
||||||
@Inject
|
@Inject
|
||||||
public S3ObjectBinder(@Named(PROPERTY_USER_METADATA_PREFIX) String metadataPrefix) {
|
public AddS3ObjectEntity(@Named(PROPERTY_USER_METADATA_PREFIX) String metadataPrefix) {
|
||||||
super(metadataPrefix);
|
super(metadataPrefix);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addEntityToRequest(Object entity, HttpRequest request) {
|
public HttpRequest decorateRequest(HttpRequest request, Object entity) {
|
||||||
Blob<?> object = (Blob<?>) entity;
|
Blob<?> object = (Blob<?>) entity;
|
||||||
checkArgument(object.getMetadata().getSize() >= 0, "size must be set");
|
checkArgument(object.getMetadata().getSize() >= 0, "size must be set");
|
||||||
checkArgument(object.getContentLength() <= 5 * 1024 * 1024 * 1024,
|
checkArgument(object.getContentLength() <= 5 * 1024 * 1024 * 1024,
|
||||||
|
@ -64,6 +63,6 @@ public class S3ObjectBinder extends BlobBinder {
|
||||||
s3Object.getMetadata().getContentEncoding());
|
s3Object.getMetadata().getContentEncoding());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
super.addEntityToRequest(entity, request);
|
return super.decorateRequest(request, entity);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -48,7 +48,7 @@ import java.util.SortedSet;
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
* @see <a href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html" />
|
* @see <a href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html" />
|
||||||
*/
|
*/
|
||||||
public interface ListBucketResponse extends org.jclouds.rest.BoundedSortedSet<ObjectMetadata> {
|
public interface ListBucketResponse extends org.jclouds.rest.internal.BoundedSortedSet<ObjectMetadata> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Example:
|
* Example:
|
||||||
|
|
|
@ -30,7 +30,7 @@ import java.util.SortedSet;
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class TreeSetListBucketResponse extends org.jclouds.rest.BoundedTreeSet<ObjectMetadata>
|
public class TreeSetListBucketResponse extends org.jclouds.rest.internal.BoundedTreeSet<ObjectMetadata>
|
||||||
implements ListBucketResponse {
|
implements ListBucketResponse {
|
||||||
/** The serialVersionUID */
|
/** The serialVersionUID */
|
||||||
private static final long serialVersionUID = -4475709781001190244L;
|
private static final long serialVersionUID = -4475709781001190244L;
|
||||||
|
|
|
@ -50,24 +50,24 @@ import org.jclouds.azure.storage.domain.BoundedSortedSet;
|
||||||
import org.jclouds.azure.storage.filters.SharedKeyAuthentication;
|
import org.jclouds.azure.storage.filters.SharedKeyAuthentication;
|
||||||
import org.jclouds.azure.storage.options.ListOptions;
|
import org.jclouds.azure.storage.options.ListOptions;
|
||||||
import org.jclouds.azure.storage.reference.AzureStorageHeaders;
|
import org.jclouds.azure.storage.reference.AzureStorageHeaders;
|
||||||
import org.jclouds.blobstore.binders.BlobBinder;
|
import org.jclouds.blobstore.decorators.AddBlobEntity;
|
||||||
import org.jclouds.blobstore.binders.UserMetadataBinder;
|
import org.jclouds.blobstore.decorators.AddHeadersWithPrefix;
|
||||||
import org.jclouds.blobstore.functions.BlobKey;
|
import org.jclouds.blobstore.functions.BlobKey;
|
||||||
import org.jclouds.blobstore.functions.ReturnVoidOnNotFoundOr404;
|
import org.jclouds.blobstore.functions.ReturnVoidOnNotFoundOr404;
|
||||||
import org.jclouds.blobstore.functions.ThrowKeyNotFoundOn404;
|
import org.jclouds.blobstore.functions.ThrowKeyNotFoundOn404;
|
||||||
import org.jclouds.http.functions.ParseETagHeader;
|
import org.jclouds.http.functions.ParseETagHeader;
|
||||||
import org.jclouds.http.functions.ReturnTrueOn404;
|
import org.jclouds.http.functions.ReturnTrueOn404;
|
||||||
import org.jclouds.http.options.GetOptions;
|
import org.jclouds.http.options.GetOptions;
|
||||||
import org.jclouds.rest.Endpoint;
|
import org.jclouds.rest.annotations.DecoratorParam;
|
||||||
import org.jclouds.rest.EntityParam;
|
import org.jclouds.rest.annotations.Endpoint;
|
||||||
import org.jclouds.rest.ExceptionParser;
|
import org.jclouds.rest.annotations.ExceptionParser;
|
||||||
import org.jclouds.rest.Headers;
|
import org.jclouds.rest.annotations.Headers;
|
||||||
import org.jclouds.rest.ParamParser;
|
import org.jclouds.rest.annotations.ParamParser;
|
||||||
import org.jclouds.rest.QueryParams;
|
import org.jclouds.rest.annotations.QueryParams;
|
||||||
import org.jclouds.rest.RequestFilters;
|
import org.jclouds.rest.annotations.RequestFilters;
|
||||||
import org.jclouds.rest.ResponseParser;
|
import org.jclouds.rest.annotations.ResponseParser;
|
||||||
import org.jclouds.rest.SkipEncoding;
|
import org.jclouds.rest.annotations.SkipEncoding;
|
||||||
import org.jclouds.rest.XMLResponseParser;
|
import org.jclouds.rest.annotations.XMLResponseParser;
|
||||||
|
|
||||||
import com.google.common.collect.Multimap;
|
import com.google.common.collect.Multimap;
|
||||||
|
|
||||||
|
@ -144,7 +144,7 @@ public interface AzureBlobConnection {
|
||||||
@Path("{container}")
|
@Path("{container}")
|
||||||
@QueryParams(keys = { "restype", "comp" }, values = { "container", "metadata" })
|
@QueryParams(keys = { "restype", "comp" }, values = { "container", "metadata" })
|
||||||
void setContainerMetadata(@PathParam("container") String container,
|
void setContainerMetadata(@PathParam("container") String container,
|
||||||
@EntityParam(UserMetadataBinder.class) Multimap<String, String> metadata);
|
@DecoratorParam(AddHeadersWithPrefix.class) Multimap<String, String> metadata);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Delete Container operation marks the specified container for deletion. The container and
|
* The Delete Container operation marks the specified container for deletion. The container and
|
||||||
|
@ -272,7 +272,7 @@ public interface AzureBlobConnection {
|
||||||
@Path("{container}/{key}")
|
@Path("{container}/{key}")
|
||||||
@ResponseParser(ParseETagHeader.class)
|
@ResponseParser(ParseETagHeader.class)
|
||||||
Future<byte[]> putBlob(@PathParam("container") String container,
|
Future<byte[]> putBlob(@PathParam("container") String container,
|
||||||
@PathParam("key") @ParamParser(BlobKey.class) @EntityParam(BlobBinder.class) Blob object);
|
@PathParam("key") @ParamParser(BlobKey.class) @DecoratorParam(AddBlobEntity.class) Blob object);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Get Blob operation reads or downloads a blob from the system, including its metadata and
|
* The Get Blob operation reads or downloads a blob from the system, including its metadata and
|
||||||
|
@ -302,7 +302,7 @@ public interface AzureBlobConnection {
|
||||||
@Path("{container}/{key}")
|
@Path("{container}/{key}")
|
||||||
@QueryParams(keys = { "comp" }, values = { "metadata" })
|
@QueryParams(keys = { "comp" }, values = { "metadata" })
|
||||||
void setBlobMetadata(@PathParam("container") String container, @PathParam("key") String key,
|
void setBlobMetadata(@PathParam("container") String container, @PathParam("key") String key,
|
||||||
@EntityParam(UserMetadataBinder.class) Multimap<String, String> metadata);
|
@DecoratorParam(AddHeadersWithPrefix.class) Multimap<String, String> metadata);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Delete Blob operation marks the specified blob for deletion. The blob is later deleted
|
* The Delete Blob operation marks the specified blob for deletion. The blob is later deleted
|
||||||
|
|
|
@ -35,11 +35,11 @@ import javax.ws.rs.Path;
|
||||||
import javax.ws.rs.PathParam;
|
import javax.ws.rs.PathParam;
|
||||||
|
|
||||||
import org.jclouds.azure.storage.AzureBlob;
|
import org.jclouds.azure.storage.AzureBlob;
|
||||||
|
import org.jclouds.azure.storage.blob.decorators.GenerateMD5AndAddBlobEntity;
|
||||||
import org.jclouds.azure.storage.blob.domain.Blob;
|
import org.jclouds.azure.storage.blob.domain.Blob;
|
||||||
import org.jclouds.azure.storage.blob.domain.BlobMetadata;
|
import org.jclouds.azure.storage.blob.domain.BlobMetadata;
|
||||||
import org.jclouds.azure.storage.blob.domain.ContainerMetadata;
|
import org.jclouds.azure.storage.blob.domain.ContainerMetadata;
|
||||||
import org.jclouds.azure.storage.blob.domain.ListBlobsResponse;
|
import org.jclouds.azure.storage.blob.domain.ListBlobsResponse;
|
||||||
import org.jclouds.azure.storage.blob.functions.MD5EnforcingBlobBinder;
|
|
||||||
import org.jclouds.azure.storage.blob.functions.ParseBlobFromHeadersAndHttpContent;
|
import org.jclouds.azure.storage.blob.functions.ParseBlobFromHeadersAndHttpContent;
|
||||||
import org.jclouds.azure.storage.blob.functions.ParseBlobMetadataFromHeaders;
|
import org.jclouds.azure.storage.blob.functions.ParseBlobMetadataFromHeaders;
|
||||||
import org.jclouds.azure.storage.blob.functions.ReturnTrueIfContainerAlreadyExists;
|
import org.jclouds.azure.storage.blob.functions.ReturnTrueIfContainerAlreadyExists;
|
||||||
|
@ -56,16 +56,16 @@ import org.jclouds.blobstore.functions.ThrowKeyNotFoundOn404;
|
||||||
import org.jclouds.http.functions.ParseETagHeader;
|
import org.jclouds.http.functions.ParseETagHeader;
|
||||||
import org.jclouds.http.functions.ReturnFalseOn404;
|
import org.jclouds.http.functions.ReturnFalseOn404;
|
||||||
import org.jclouds.http.options.GetOptions;
|
import org.jclouds.http.options.GetOptions;
|
||||||
import org.jclouds.rest.Endpoint;
|
import org.jclouds.rest.annotations.DecoratorParam;
|
||||||
import org.jclouds.rest.EntityParam;
|
import org.jclouds.rest.annotations.Endpoint;
|
||||||
import org.jclouds.rest.ExceptionParser;
|
import org.jclouds.rest.annotations.ExceptionParser;
|
||||||
import org.jclouds.rest.Headers;
|
import org.jclouds.rest.annotations.Headers;
|
||||||
import org.jclouds.rest.ParamParser;
|
import org.jclouds.rest.annotations.ParamParser;
|
||||||
import org.jclouds.rest.QueryParams;
|
import org.jclouds.rest.annotations.QueryParams;
|
||||||
import org.jclouds.rest.RequestFilters;
|
import org.jclouds.rest.annotations.RequestFilters;
|
||||||
import org.jclouds.rest.ResponseParser;
|
import org.jclouds.rest.annotations.ResponseParser;
|
||||||
import org.jclouds.rest.SkipEncoding;
|
import org.jclouds.rest.annotations.SkipEncoding;
|
||||||
import org.jclouds.rest.XMLResponseParser;
|
import org.jclouds.rest.annotations.XMLResponseParser;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides access to Azure Blob via their REST API.
|
* Provides access to Azure Blob via their REST API.
|
||||||
|
@ -149,7 +149,7 @@ public interface AzureBlobStore extends BlobStore<ContainerMetadata, BlobMetadat
|
||||||
@ResponseParser(ParseETagHeader.class)
|
@ResponseParser(ParseETagHeader.class)
|
||||||
Future<byte[]> putBlob(
|
Future<byte[]> putBlob(
|
||||||
@PathParam("container") String container,
|
@PathParam("container") String container,
|
||||||
@PathParam("key") @ParamParser(BlobKey.class) @EntityParam(MD5EnforcingBlobBinder.class) Blob object);
|
@PathParam("key") @ParamParser(BlobKey.class) @DecoratorParam(GenerateMD5AndAddBlobEntity.class) Blob object);
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
@ResponseParser(ParseBlobFromHeadersAndHttpContent.class)
|
@ResponseParser(ParseBlobFromHeadersAndHttpContent.class)
|
||||||
|
|
|
@ -33,12 +33,12 @@ import org.jclouds.azure.storage.filters.SharedKeyAuthentication;
|
||||||
import org.jclouds.azure.storage.reference.AzureStorageHeaders;
|
import org.jclouds.azure.storage.reference.AzureStorageHeaders;
|
||||||
import org.jclouds.blobstore.functions.ThrowKeyNotFoundOn404;
|
import org.jclouds.blobstore.functions.ThrowKeyNotFoundOn404;
|
||||||
import org.jclouds.http.functions.ParseContentMD5FromHeaders;
|
import org.jclouds.http.functions.ParseContentMD5FromHeaders;
|
||||||
import org.jclouds.rest.Endpoint;
|
import org.jclouds.rest.annotations.Endpoint;
|
||||||
import org.jclouds.rest.ExceptionParser;
|
import org.jclouds.rest.annotations.ExceptionParser;
|
||||||
import org.jclouds.rest.Headers;
|
import org.jclouds.rest.annotations.Headers;
|
||||||
import org.jclouds.rest.RequestFilters;
|
import org.jclouds.rest.annotations.RequestFilters;
|
||||||
import org.jclouds.rest.ResponseParser;
|
import org.jclouds.rest.annotations.ResponseParser;
|
||||||
import org.jclouds.rest.SkipEncoding;
|
import org.jclouds.rest.annotations.SkipEncoding;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper functions needed to to derive BlobStore values
|
* Helper functions needed to to derive BlobStore values
|
||||||
|
|
|
@ -21,27 +21,27 @@
|
||||||
* under the License.
|
* under the License.
|
||||||
* ====================================================================
|
* ====================================================================
|
||||||
*/
|
*/
|
||||||
package org.jclouds.azure.storage.blob.binders;
|
package org.jclouds.azure.storage.blob.decorators;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkArgument;
|
import static com.google.common.base.Preconditions.checkArgument;
|
||||||
import static org.jclouds.blobstore.reference.BlobStoreConstants.PROPERTY_USER_METADATA_PREFIX;
|
import static org.jclouds.blobstore.reference.BlobStoreConstants.PROPERTY_USER_METADATA_PREFIX;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Named;
|
||||||
import javax.ws.rs.core.HttpHeaders;
|
import javax.ws.rs.core.HttpHeaders;
|
||||||
|
|
||||||
import org.jclouds.azure.storage.blob.domain.BlobMetadata;
|
import org.jclouds.azure.storage.blob.domain.BlobMetadata;
|
||||||
import org.jclouds.blobstore.domain.Blob;
|
import org.jclouds.blobstore.domain.Blob;
|
||||||
import org.jclouds.http.HttpRequest;
|
import org.jclouds.http.HttpRequest;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
public class AddBlobEntity extends org.jclouds.blobstore.decorators.AddBlobEntity {
|
||||||
import javax.inject.Named;
|
|
||||||
|
|
||||||
public class BlobBinder extends org.jclouds.blobstore.binders.BlobBinder {
|
|
||||||
@Inject
|
@Inject
|
||||||
public BlobBinder(@Named(PROPERTY_USER_METADATA_PREFIX) String metadataPrefix) {
|
public AddBlobEntity(@Named(PROPERTY_USER_METADATA_PREFIX) String metadataPrefix) {
|
||||||
super(metadataPrefix);
|
super(metadataPrefix);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addEntityToRequest(Object entity, HttpRequest request) {
|
@Override
|
||||||
|
public HttpRequest decorateRequest(HttpRequest request, Object entity) {
|
||||||
Blob<?> object = (Blob<?>) entity;
|
Blob<?> object = (Blob<?>) entity;
|
||||||
checkArgument(object.getMetadata().getSize() >= 0, "size must be set");
|
checkArgument(object.getMetadata().getSize() >= 0, "size must be set");
|
||||||
checkArgument(object.getContentLength() <= 64 * 1024 * 1024,
|
checkArgument(object.getContentLength() <= 64 * 1024 * 1024,
|
||||||
|
@ -57,6 +57,6 @@ public class BlobBinder extends org.jclouds.blobstore.binders.BlobBinder {
|
||||||
request.getHeaders().put(HttpHeaders.CONTENT_ENCODING, md.getContentEncoding());
|
request.getHeaders().put(HttpHeaders.CONTENT_ENCODING, md.getContentEncoding());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
super.addEntityToRequest(entity, request);
|
return super.decorateRequest(request, entity);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -21,7 +21,7 @@
|
||||||
* under the License.
|
* under the License.
|
||||||
* ====================================================================
|
* ====================================================================
|
||||||
*/
|
*/
|
||||||
package org.jclouds.azure.storage.blob.functions;
|
package org.jclouds.azure.storage.blob.decorators;
|
||||||
|
|
||||||
import static org.jclouds.blobstore.reference.BlobStoreConstants.PROPERTY_USER_METADATA_PREFIX;
|
import static org.jclouds.blobstore.reference.BlobStoreConstants.PROPERTY_USER_METADATA_PREFIX;
|
||||||
|
|
||||||
|
@ -30,18 +30,18 @@ import java.io.IOException;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Named;
|
import javax.inject.Named;
|
||||||
|
|
||||||
import org.jclouds.azure.storage.blob.binders.BlobBinder;
|
|
||||||
import org.jclouds.blobstore.domain.Blob;
|
import org.jclouds.blobstore.domain.Blob;
|
||||||
import org.jclouds.http.HttpRequest;
|
import org.jclouds.http.HttpRequest;
|
||||||
|
|
||||||
public class MD5EnforcingBlobBinder extends BlobBinder {
|
public class GenerateMD5AndAddBlobEntity extends AddBlobEntity {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public MD5EnforcingBlobBinder(@Named(PROPERTY_USER_METADATA_PREFIX) String metadataPrefix) {
|
public GenerateMD5AndAddBlobEntity(@Named(PROPERTY_USER_METADATA_PREFIX) String metadataPrefix) {
|
||||||
super(metadataPrefix);
|
super(metadataPrefix);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addEntityToRequest(Object entity, HttpRequest request) {
|
@Override
|
||||||
|
public HttpRequest decorateRequest(HttpRequest request, Object entity) {
|
||||||
Blob<?> object = (Blob<?>) entity;
|
Blob<?> object = (Blob<?>) entity;
|
||||||
if (object.getMetadata().getContentMD5() == null) {
|
if (object.getMetadata().getContentMD5() == null) {
|
||||||
try {
|
try {
|
||||||
|
@ -50,6 +50,6 @@ public class MD5EnforcingBlobBinder extends BlobBinder {
|
||||||
throw new RuntimeException("Could not generate MD5 for " + object.getKey(), e);
|
throw new RuntimeException("Could not generate MD5 for " + object.getKey(), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
super.addEntityToRequest(entity, request);
|
return super.decorateRequest(request, entity);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -36,7 +36,7 @@ import org.jclouds.http.HttpException;
|
||||||
import org.jclouds.http.HttpRequest;
|
import org.jclouds.http.HttpRequest;
|
||||||
import org.jclouds.http.HttpResponse;
|
import org.jclouds.http.HttpResponse;
|
||||||
import org.jclouds.http.HttpUtils;
|
import org.jclouds.http.HttpUtils;
|
||||||
import org.jclouds.rest.RestContext;
|
import org.jclouds.rest.InvocationContext;
|
||||||
import org.jclouds.util.DateService;
|
import org.jclouds.util.DateService;
|
||||||
|
|
||||||
import com.google.common.annotations.VisibleForTesting;
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
|
@ -50,7 +50,7 @@ import com.google.common.base.Function;
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
public class ParseContainerMetadataFromHeaders implements
|
public class ParseContainerMetadataFromHeaders implements
|
||||||
Function<HttpResponse, ContainerMetadata>, RestContext {
|
Function<HttpResponse, ContainerMetadata>, InvocationContext {
|
||||||
|
|
||||||
private final DateService dateParser;
|
private final DateService dateParser;
|
||||||
private final String metadataPrefix;
|
private final String metadataPrefix;
|
||||||
|
|
|
@ -33,6 +33,7 @@ import java.net.URI;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
|
||||||
import javax.ws.rs.HttpMethod;
|
import javax.ws.rs.HttpMethod;
|
||||||
|
import javax.ws.rs.core.HttpHeaders;
|
||||||
|
|
||||||
import org.jclouds.azure.storage.AzureBlob;
|
import org.jclouds.azure.storage.AzureBlob;
|
||||||
import org.jclouds.azure.storage.blob.functions.ParseContainerMetadataFromHeaders;
|
import org.jclouds.azure.storage.blob.functions.ParseContainerMetadataFromHeaders;
|
||||||
|
@ -52,8 +53,8 @@ import org.jclouds.http.functions.ParseSax;
|
||||||
import org.jclouds.http.functions.ReturnTrueIf2xx;
|
import org.jclouds.http.functions.ReturnTrueIf2xx;
|
||||||
import org.jclouds.http.functions.ReturnTrueOn404;
|
import org.jclouds.http.functions.ReturnTrueOn404;
|
||||||
import org.jclouds.http.functions.ReturnVoidIf2xx;
|
import org.jclouds.http.functions.ReturnVoidIf2xx;
|
||||||
import org.jclouds.rest.JaxrsAnnotationProcessor;
|
import org.jclouds.rest.config.RestModule;
|
||||||
import org.jclouds.rest.config.JaxrsModule;
|
import org.jclouds.rest.internal.RestAnnotationProcessor;
|
||||||
import org.jclouds.util.Jsr330;
|
import org.jclouds.util.Jsr330;
|
||||||
import org.testng.annotations.BeforeClass;
|
import org.testng.annotations.BeforeClass;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
@ -300,7 +301,9 @@ public class AzureBlobConnectionTest {
|
||||||
assertEquals(httpMethod.getEndpoint().getPath(), "/container");
|
assertEquals(httpMethod.getEndpoint().getPath(), "/container");
|
||||||
assertEquals(httpMethod.getEndpoint().getQuery(), "restype=container&comp=metadata");
|
assertEquals(httpMethod.getEndpoint().getQuery(), "restype=container&comp=metadata");
|
||||||
assertEquals(httpMethod.getMethod(), HttpMethod.PUT);
|
assertEquals(httpMethod.getMethod(), HttpMethod.PUT);
|
||||||
assertEquals(httpMethod.getHeaders().size(), 2);
|
assertEquals(httpMethod.getHeaders().size(), 3);
|
||||||
|
assertEquals(httpMethod.getHeaders().get(HttpHeaders.CONTENT_LENGTH), Collections
|
||||||
|
.singletonList("0"));
|
||||||
assertEquals(httpMethod.getHeaders().get("x-ms-version"), Collections
|
assertEquals(httpMethod.getHeaders().get("x-ms-version"), Collections
|
||||||
.singletonList("2009-07-17"));
|
.singletonList("2009-07-17"));
|
||||||
assertEquals(httpMethod.getHeaders().get("x-ms-meta-key"), Collections.singletonList("value"));
|
assertEquals(httpMethod.getHeaders().get("x-ms-meta-key"), Collections.singletonList("value"));
|
||||||
|
@ -319,9 +322,11 @@ public class AzureBlobConnectionTest {
|
||||||
assertEquals(httpMethod.getEndpoint().getPath(), "/container/blob");
|
assertEquals(httpMethod.getEndpoint().getPath(), "/container/blob");
|
||||||
assertEquals(httpMethod.getEndpoint().getQuery(), "comp=metadata");
|
assertEquals(httpMethod.getEndpoint().getQuery(), "comp=metadata");
|
||||||
assertEquals(httpMethod.getMethod(), HttpMethod.PUT);
|
assertEquals(httpMethod.getMethod(), HttpMethod.PUT);
|
||||||
assertEquals(httpMethod.getHeaders().size(), 2);
|
assertEquals(httpMethod.getHeaders().size(), 3);
|
||||||
assertEquals(httpMethod.getHeaders().get("x-ms-version"), Collections
|
assertEquals(httpMethod.getHeaders().get("x-ms-version"), Collections
|
||||||
.singletonList("2009-07-17"));
|
.singletonList("2009-07-17"));
|
||||||
|
assertEquals(httpMethod.getHeaders().get(HttpHeaders.CONTENT_LENGTH), Collections
|
||||||
|
.singletonList("0"));
|
||||||
assertEquals(httpMethod.getHeaders().get("x-ms-meta-key"), Collections.singletonList("value"));
|
assertEquals(httpMethod.getHeaders().get("x-ms-meta-key"), Collections.singletonList("value"));
|
||||||
|
|
||||||
assertEquals(processor.createResponseParser(method, httpMethod, null).getClass(),
|
assertEquals(processor.createResponseParser(method, httpMethod, null).getClass(),
|
||||||
|
@ -346,12 +351,12 @@ public class AzureBlobConnectionTest {
|
||||||
Jsr330.named(BlobStoreConstants.PROPERTY_USER_METADATA_PREFIX)).to(
|
Jsr330.named(BlobStoreConstants.PROPERTY_USER_METADATA_PREFIX)).to(
|
||||||
"x-ms-meta-");
|
"x-ms-meta-");
|
||||||
}
|
}
|
||||||
}, new JaxrsModule(), new ExecutorServiceModule(new WithinThreadExecutorService()),
|
}, new RestModule(), new ExecutorServiceModule(new WithinThreadExecutorService()),
|
||||||
new JavaUrlHttpCommandExecutorServiceModule());
|
new JavaUrlHttpCommandExecutorServiceModule());
|
||||||
processor = injector.getInstance(Key
|
processor = injector.getInstance(Key
|
||||||
.get(new TypeLiteral<JaxrsAnnotationProcessor<AzureBlobConnection>>() {
|
.get(new TypeLiteral<RestAnnotationProcessor<AzureBlobConnection>>() {
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
JaxrsAnnotationProcessor<AzureBlobConnection> processor;
|
RestAnnotationProcessor<AzureBlobConnection> processor;
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,8 +49,8 @@ import org.jclouds.http.functions.ParseETagHeader;
|
||||||
import org.jclouds.http.functions.ParseSax;
|
import org.jclouds.http.functions.ParseSax;
|
||||||
import org.jclouds.http.functions.ReturnTrueIf2xx;
|
import org.jclouds.http.functions.ReturnTrueIf2xx;
|
||||||
import org.jclouds.http.functions.ReturnVoidIf2xx;
|
import org.jclouds.http.functions.ReturnVoidIf2xx;
|
||||||
import org.jclouds.rest.JaxrsAnnotationProcessor;
|
import org.jclouds.rest.config.RestModule;
|
||||||
import org.jclouds.rest.config.JaxrsModule;
|
import org.jclouds.rest.internal.RestAnnotationProcessor;
|
||||||
import org.jclouds.util.Jsr330;
|
import org.jclouds.util.Jsr330;
|
||||||
import org.testng.annotations.BeforeClass;
|
import org.testng.annotations.BeforeClass;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
@ -195,12 +195,12 @@ public class AzureBlobStoreTest {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
}, new JaxrsModule(), new ExecutorServiceModule(new WithinThreadExecutorService()),
|
}, new RestModule(), new ExecutorServiceModule(new WithinThreadExecutorService()),
|
||||||
new JavaUrlHttpCommandExecutorServiceModule());
|
new JavaUrlHttpCommandExecutorServiceModule());
|
||||||
processor = injector.getInstance(Key
|
processor = injector.getInstance(Key
|
||||||
.get(new TypeLiteral<JaxrsAnnotationProcessor<AzureBlobStore>>() {
|
.get(new TypeLiteral<RestAnnotationProcessor<AzureBlobStore>>() {
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
JaxrsAnnotationProcessor<AzureBlobStore> processor;
|
RestAnnotationProcessor<AzureBlobStore> processor;
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,7 @@ package org.jclouds.azure.storage.domain;
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public interface BoundedSortedSet<T> extends org.jclouds.rest.BoundedSortedSet<T> {
|
public interface BoundedSortedSet<T> extends org.jclouds.rest.internal.BoundedSortedSet<T> {
|
||||||
|
|
||||||
String getNextMarker();
|
String getNextMarker();
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,7 @@ import java.util.SortedSet;
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class BoundedTreeSet<T> extends org.jclouds.rest.BoundedTreeSet<T> implements
|
public class BoundedTreeSet<T> extends org.jclouds.rest.internal.BoundedTreeSet<T> implements
|
||||||
BoundedSortedSet<T> {
|
BoundedSortedSet<T> {
|
||||||
/** The serialVersionUID */
|
/** The serialVersionUID */
|
||||||
private static final long serialVersionUID = -4475709781001190244L;
|
private static final long serialVersionUID = -4475709781001190244L;
|
||||||
|
|
|
@ -37,11 +37,11 @@ import org.jclouds.concurrent.WithinThreadExecutorService;
|
||||||
import org.jclouds.concurrent.config.ExecutorServiceModule;
|
import org.jclouds.concurrent.config.ExecutorServiceModule;
|
||||||
import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule;
|
import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule;
|
||||||
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
|
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
|
||||||
import org.jclouds.rest.Endpoint;
|
|
||||||
import org.jclouds.rest.QueryParams;
|
|
||||||
import org.jclouds.rest.RequestFilters;
|
|
||||||
import org.jclouds.rest.RestClientFactory;
|
import org.jclouds.rest.RestClientFactory;
|
||||||
import org.jclouds.rest.config.JaxrsModule;
|
import org.jclouds.rest.annotations.Endpoint;
|
||||||
|
import org.jclouds.rest.annotations.QueryParams;
|
||||||
|
import org.jclouds.rest.annotations.RequestFilters;
|
||||||
|
import org.jclouds.rest.config.RestModule;
|
||||||
import org.jclouds.util.Jsr330;
|
import org.jclouds.util.Jsr330;
|
||||||
import org.testng.annotations.BeforeClass;
|
import org.testng.annotations.BeforeClass;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
@ -96,7 +96,7 @@ public class SharedKeyAuthenticationLiveTest {
|
||||||
Jsr330.named(AzureStorageConstants.PROPERTY_AZURESTORAGE_KEY)).to(key);
|
Jsr330.named(AzureStorageConstants.PROPERTY_AZURESTORAGE_KEY)).to(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
}, new JaxrsModule(), new Log4JLoggingModule(), new ExecutorServiceModule(
|
}, new RestModule(), new Log4JLoggingModule(), new ExecutorServiceModule(
|
||||||
new WithinThreadExecutorService()), new JavaUrlHttpCommandExecutorServiceModule());
|
new WithinThreadExecutorService()), new JavaUrlHttpCommandExecutorServiceModule());
|
||||||
RestClientFactory factory = injector.getInstance(RestClientFactory.class);
|
RestClientFactory factory = injector.getInstance(RestClientFactory.class);
|
||||||
client = factory.create(IntegrationTestClient.class);
|
client = factory.create(IntegrationTestClient.class);
|
||||||
|
|
|
@ -40,12 +40,12 @@ import org.jclouds.azure.storage.options.ListOptions;
|
||||||
import org.jclouds.azure.storage.queue.domain.QueueMetadata;
|
import org.jclouds.azure.storage.queue.domain.QueueMetadata;
|
||||||
import org.jclouds.azure.storage.queue.xml.AccountNameEnumerationResultsHandler;
|
import org.jclouds.azure.storage.queue.xml.AccountNameEnumerationResultsHandler;
|
||||||
import org.jclouds.azure.storage.reference.AzureStorageHeaders;
|
import org.jclouds.azure.storage.reference.AzureStorageHeaders;
|
||||||
import org.jclouds.rest.Endpoint;
|
import org.jclouds.rest.annotations.Endpoint;
|
||||||
import org.jclouds.rest.Headers;
|
import org.jclouds.rest.annotations.Headers;
|
||||||
import org.jclouds.rest.QueryParams;
|
import org.jclouds.rest.annotations.QueryParams;
|
||||||
import org.jclouds.rest.RequestFilters;
|
import org.jclouds.rest.annotations.RequestFilters;
|
||||||
import org.jclouds.rest.SkipEncoding;
|
import org.jclouds.rest.annotations.SkipEncoding;
|
||||||
import org.jclouds.rest.XMLResponseParser;
|
import org.jclouds.rest.annotations.XMLResponseParser;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides access to Azure Queue via their REST API.
|
* Provides access to Azure Queue via their REST API.
|
||||||
|
|
|
@ -44,8 +44,8 @@ import org.jclouds.http.HttpUtils;
|
||||||
import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule;
|
import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule;
|
||||||
import org.jclouds.http.functions.ParseSax;
|
import org.jclouds.http.functions.ParseSax;
|
||||||
import org.jclouds.http.functions.ReturnTrueIf2xx;
|
import org.jclouds.http.functions.ReturnTrueIf2xx;
|
||||||
import org.jclouds.rest.JaxrsAnnotationProcessor;
|
import org.jclouds.rest.config.RestModule;
|
||||||
import org.jclouds.rest.config.JaxrsModule;
|
import org.jclouds.rest.internal.RestAnnotationProcessor;
|
||||||
import org.jclouds.util.Jsr330;
|
import org.jclouds.util.Jsr330;
|
||||||
import org.testng.annotations.BeforeClass;
|
import org.testng.annotations.BeforeClass;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
@ -177,12 +177,12 @@ public class AzureQueueConnectionTest {
|
||||||
Jsr330.named(AzureStorageConstants.PROPERTY_AZURESTORAGE_KEY)).to(
|
Jsr330.named(AzureStorageConstants.PROPERTY_AZURESTORAGE_KEY)).to(
|
||||||
HttpUtils.toBase64String("key".getBytes()));
|
HttpUtils.toBase64String("key".getBytes()));
|
||||||
}
|
}
|
||||||
}, new JaxrsModule(), new ExecutorServiceModule(new WithinThreadExecutorService()),
|
}, new RestModule(), new ExecutorServiceModule(new WithinThreadExecutorService()),
|
||||||
new JavaUrlHttpCommandExecutorServiceModule());
|
new JavaUrlHttpCommandExecutorServiceModule());
|
||||||
processor = injector.getInstance(Key
|
processor = injector.getInstance(Key
|
||||||
.get(new TypeLiteral<JaxrsAnnotationProcessor<AzureQueueConnection>>() {
|
.get(new TypeLiteral<RestAnnotationProcessor<AzureQueueConnection>>() {
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
JaxrsAnnotationProcessor<AzureQueueConnection> processor;
|
RestAnnotationProcessor<AzureQueueConnection> processor;
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,9 +21,9 @@
|
||||||
* under the License.
|
* under the License.
|
||||||
* ====================================================================
|
* ====================================================================
|
||||||
*/
|
*/
|
||||||
package org.jclouds.blobstore.binders;
|
package org.jclouds.blobstore.decorators;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.*;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
import static org.jclouds.blobstore.reference.BlobStoreConstants.PROPERTY_USER_METADATA_PREFIX;
|
import static org.jclouds.blobstore.reference.BlobStoreConstants.PROPERTY_USER_METADATA_PREFIX;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
@ -33,17 +33,17 @@ import javax.ws.rs.core.HttpHeaders;
|
||||||
import org.jclouds.blobstore.domain.Blob;
|
import org.jclouds.blobstore.domain.Blob;
|
||||||
import org.jclouds.http.HttpRequest;
|
import org.jclouds.http.HttpRequest;
|
||||||
import org.jclouds.http.HttpUtils;
|
import org.jclouds.http.HttpUtils;
|
||||||
import org.jclouds.rest.binders.EntityBinder;
|
import org.jclouds.rest.decorators.RequestDecorator;
|
||||||
|
|
||||||
public class BlobBinder implements EntityBinder {
|
public class AddBlobEntity implements RequestDecorator {
|
||||||
private final String metadataPrefix;
|
private final String metadataPrefix;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public BlobBinder(@Named(PROPERTY_USER_METADATA_PREFIX) String metadataPrefix) {
|
public AddBlobEntity(@Named(PROPERTY_USER_METADATA_PREFIX) String metadataPrefix) {
|
||||||
this.metadataPrefix = metadataPrefix;
|
this.metadataPrefix = metadataPrefix;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addEntityToRequest(Object entity, HttpRequest request) {
|
public HttpRequest decorateRequest(HttpRequest request, Object entity) {
|
||||||
Blob<?> object = (Blob<?>) entity;
|
Blob<?> object = (Blob<?>) entity;
|
||||||
|
|
||||||
for (String key : object.getMetadata().getUserMetadata().keySet()) {
|
for (String key : object.getMetadata().getUserMetadata().keySet()) {
|
||||||
|
@ -63,6 +63,6 @@ public class BlobBinder implements EntityBinder {
|
||||||
request.getHeaders().put("Content-MD5",
|
request.getHeaders().put("Content-MD5",
|
||||||
HttpUtils.toBase64String(object.getMetadata().getContentMD5()));
|
HttpUtils.toBase64String(object.getMetadata().getContentMD5()));
|
||||||
}
|
}
|
||||||
|
return request;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -21,7 +21,7 @@
|
||||||
* under the License.
|
* under the License.
|
||||||
* ====================================================================
|
* ====================================================================
|
||||||
*/
|
*/
|
||||||
package org.jclouds.mezeo.pcs2.binders;
|
package org.jclouds.blobstore.decorators;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
|
@ -32,12 +32,12 @@ import java.io.InputStream;
|
||||||
import javax.ws.rs.core.HttpHeaders;
|
import javax.ws.rs.core.HttpHeaders;
|
||||||
|
|
||||||
import org.jclouds.blobstore.domain.Blob;
|
import org.jclouds.blobstore.domain.Blob;
|
||||||
|
import org.jclouds.blobstore.domain.Key;
|
||||||
|
import org.jclouds.blobstore.util.BlobStoreUtils;
|
||||||
import org.jclouds.http.HttpRequest;
|
import org.jclouds.http.HttpRequest;
|
||||||
import org.jclouds.http.MultipartForm;
|
import org.jclouds.http.MultipartForm;
|
||||||
import org.jclouds.http.MultipartForm.Part;
|
import org.jclouds.http.MultipartForm.Part;
|
||||||
import org.jclouds.mezeo.pcs2.functions.Key;
|
import org.jclouds.rest.decorators.RequestDecorator;
|
||||||
import org.jclouds.mezeo.pcs2.util.PCSUtils;
|
|
||||||
import org.jclouds.rest.binders.EntityBinder;
|
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableMultimap;
|
import com.google.common.collect.ImmutableMultimap;
|
||||||
import com.google.common.collect.Multimap;
|
import com.google.common.collect.Multimap;
|
||||||
|
@ -46,13 +46,13 @@ import com.google.common.collect.Multimap;
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
public class PCSFileAsMultipartFormBinder implements EntityBinder {
|
public class AddBlobEntityAsMultipartForm implements RequestDecorator {
|
||||||
|
|
||||||
public static final String BOUNDARY = "--PCS--";
|
public static final String BOUNDARY = "--JCLOUDS--";
|
||||||
|
|
||||||
public void addEntityToRequest(Object entity, HttpRequest request) {
|
public HttpRequest decorateRequest(HttpRequest request, Object entity) {
|
||||||
Blob<?> object = (Blob<?>) entity;
|
Blob<?> object = (Blob<?>) entity;
|
||||||
Key key = PCSUtils.parseKey(new Key("junk", object.getKey()));
|
Key key = BlobStoreUtils.parseKey(new Key("junk", object.getKey()));
|
||||||
Multimap<String, String> partHeaders = ImmutableMultimap.of("Content-Disposition", String
|
Multimap<String, String> partHeaders = ImmutableMultimap.of("Content-Disposition", String
|
||||||
.format("form-data; name=\"%s\"; filename=\"%s\"", key.getKey(), key.getKey()),
|
.format("form-data; name=\"%s\"; filename=\"%s\"", key.getKey(), key.getKey()),
|
||||||
HttpHeaders.CONTENT_TYPE, checkNotNull(object.getMetadata().getContentType(),
|
HttpHeaders.CONTENT_TYPE, checkNotNull(object.getMetadata().getContentType(),
|
||||||
|
@ -84,6 +84,6 @@ public class PCSFileAsMultipartFormBinder implements EntityBinder {
|
||||||
"multipart/form-data; boundary=" + BOUNDARY);
|
"multipart/form-data; boundary=" + BOUNDARY);
|
||||||
|
|
||||||
request.getHeaders().put(HttpHeaders.CONTENT_LENGTH, form.getSize() + "");
|
request.getHeaders().put(HttpHeaders.CONTENT_LENGTH, form.getSize() + "");
|
||||||
|
return request;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -21,7 +21,7 @@
|
||||||
* under the License.
|
* under the License.
|
||||||
* ====================================================================
|
* ====================================================================
|
||||||
*/
|
*/
|
||||||
package org.jclouds.blobstore.binders;
|
package org.jclouds.blobstore.decorators;
|
||||||
|
|
||||||
import static org.jclouds.blobstore.reference.BlobStoreConstants.PROPERTY_USER_METADATA_PREFIX;
|
import static org.jclouds.blobstore.reference.BlobStoreConstants.PROPERTY_USER_METADATA_PREFIX;
|
||||||
|
|
||||||
|
@ -31,20 +31,20 @@ import javax.inject.Inject;
|
||||||
import javax.inject.Named;
|
import javax.inject.Named;
|
||||||
|
|
||||||
import org.jclouds.http.HttpRequest;
|
import org.jclouds.http.HttpRequest;
|
||||||
import org.jclouds.rest.binders.EntityBinder;
|
import org.jclouds.rest.decorators.RequestDecorator;
|
||||||
|
|
||||||
import com.google.common.collect.Multimap;
|
import com.google.common.collect.Multimap;
|
||||||
|
|
||||||
public class UserMetadataBinder implements EntityBinder {
|
public class AddHeadersWithPrefix implements RequestDecorator {
|
||||||
private final String metadataPrefix;
|
private final String metadataPrefix;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public UserMetadataBinder(@Named(PROPERTY_USER_METADATA_PREFIX) String metadataPrefix) {
|
public AddHeadersWithPrefix(@Named(PROPERTY_USER_METADATA_PREFIX) String metadataPrefix) {
|
||||||
this.metadataPrefix = metadataPrefix;
|
this.metadataPrefix = metadataPrefix;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public void addEntityToRequest(Object entity, HttpRequest request) {
|
public HttpRequest decorateRequest( HttpRequest request, Object entity) {
|
||||||
Multimap<String, String> userMetadata = (Multimap<String, String>) entity;
|
Multimap<String, String> userMetadata = (Multimap<String, String>) entity;
|
||||||
for (Entry<String, String> entry : userMetadata.entries()) {
|
for (Entry<String, String> entry : userMetadata.entries()) {
|
||||||
if (entry.getKey().startsWith(metadataPrefix)) {
|
if (entry.getKey().startsWith(metadataPrefix)) {
|
||||||
|
@ -54,6 +54,7 @@ public class UserMetadataBinder implements EntityBinder {
|
||||||
entry.getValue());
|
entry.getValue());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return request;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -21,7 +21,7 @@
|
||||||
* under the License.
|
* under the License.
|
||||||
* ====================================================================
|
* ====================================================================
|
||||||
*/
|
*/
|
||||||
package org.jclouds.mezeo.pcs2.functions;
|
package org.jclouds.blobstore.domain;
|
||||||
|
|
||||||
public class Key {
|
public class Key {
|
||||||
private final String container;
|
private final String container;
|
|
@ -38,13 +38,13 @@ import org.jclouds.blobstore.reference.BlobStoreConstants;
|
||||||
import org.jclouds.blobstore.strategy.ClearContainerStrategy;
|
import org.jclouds.blobstore.strategy.ClearContainerStrategy;
|
||||||
import org.jclouds.http.HttpRequest;
|
import org.jclouds.http.HttpRequest;
|
||||||
import org.jclouds.http.HttpResponseException;
|
import org.jclouds.http.HttpResponseException;
|
||||||
import org.jclouds.rest.RestContext;
|
import org.jclouds.rest.InvocationContext;
|
||||||
import org.jclouds.util.Utils;
|
import org.jclouds.util.Utils;
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
|
|
||||||
public class ClearAndDeleteIfNotEmpty<C extends ContainerMetadata, M extends BlobMetadata, B extends Blob<M>>
|
public class ClearAndDeleteIfNotEmpty<C extends ContainerMetadata, M extends BlobMetadata, B extends Blob<M>>
|
||||||
implements Function<Exception, Void>, RestContext {
|
implements Function<Exception, Void>, InvocationContext {
|
||||||
static final Void v;
|
static final Void v;
|
||||||
static {
|
static {
|
||||||
Constructor<Void> cv;
|
Constructor<Void> cv;
|
||||||
|
|
|
@ -32,7 +32,7 @@ import org.jclouds.blobstore.domain.BlobMetadata;
|
||||||
import org.jclouds.http.HttpException;
|
import org.jclouds.http.HttpException;
|
||||||
import org.jclouds.http.HttpRequest;
|
import org.jclouds.http.HttpRequest;
|
||||||
import org.jclouds.http.HttpResponse;
|
import org.jclouds.http.HttpResponse;
|
||||||
import org.jclouds.rest.RestContext;
|
import org.jclouds.rest.InvocationContext;
|
||||||
|
|
||||||
import com.google.common.annotations.VisibleForTesting;
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
|
@ -44,7 +44,7 @@ import com.google.common.base.Function;
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
public class ParseBlobFromHeadersAndHttpContent<M extends BlobMetadata, B extends Blob<M>>
|
public class ParseBlobFromHeadersAndHttpContent<M extends BlobMetadata, B extends Blob<M>>
|
||||||
implements Function<HttpResponse, B>, RestContext {
|
implements Function<HttpResponse, B>, InvocationContext {
|
||||||
private final ParseContentTypeFromHeaders<M> metadataParser;
|
private final ParseContentTypeFromHeaders<M> metadataParser;
|
||||||
private final Provider<B> blobFactory;
|
private final Provider<B> blobFactory;
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,7 @@ import org.jclouds.blobstore.domain.BlobMetadata;
|
||||||
import org.jclouds.http.HttpException;
|
import org.jclouds.http.HttpException;
|
||||||
import org.jclouds.http.HttpRequest;
|
import org.jclouds.http.HttpRequest;
|
||||||
import org.jclouds.http.HttpResponse;
|
import org.jclouds.http.HttpResponse;
|
||||||
import org.jclouds.rest.RestContext;
|
import org.jclouds.rest.InvocationContext;
|
||||||
|
|
||||||
import com.google.common.annotations.VisibleForTesting;
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
|
@ -40,7 +40,7 @@ import com.google.common.base.Function;
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
public class ParseContentTypeFromHeaders<M extends BlobMetadata> implements
|
public class ParseContentTypeFromHeaders<M extends BlobMetadata> implements
|
||||||
Function<HttpResponse, M>, RestContext {
|
Function<HttpResponse, M>, InvocationContext {
|
||||||
private final Provider<M> metadataFactory;
|
private final Provider<M> metadataFactory;
|
||||||
private HttpRequest request;
|
private HttpRequest request;
|
||||||
private Object[] args;
|
private Object[] args;
|
||||||
|
|
|
@ -44,7 +44,7 @@ import org.jclouds.blobstore.strategy.ContainerCountStrategy;
|
||||||
import org.jclouds.blobstore.strategy.ContainsValueStrategy;
|
import org.jclouds.blobstore.strategy.ContainsValueStrategy;
|
||||||
import org.jclouds.blobstore.strategy.GetAllBlobMetadataStrategy;
|
import org.jclouds.blobstore.strategy.GetAllBlobMetadataStrategy;
|
||||||
import org.jclouds.blobstore.strategy.GetAllBlobsStrategy;
|
import org.jclouds.blobstore.strategy.GetAllBlobsStrategy;
|
||||||
import org.jclouds.rest.BoundedSortedSet;
|
import org.jclouds.rest.internal.BoundedSortedSet;
|
||||||
import org.jclouds.util.Utils;
|
import org.jclouds.util.Utils;
|
||||||
|
|
||||||
import com.google.common.collect.Sets;
|
import com.google.common.collect.Sets;
|
||||||
|
|
|
@ -30,6 +30,7 @@ import java.io.InputStream;
|
||||||
|
|
||||||
import org.jclouds.blobstore.domain.Blob;
|
import org.jclouds.blobstore.domain.Blob;
|
||||||
import org.jclouds.blobstore.domain.BlobMetadata;
|
import org.jclouds.blobstore.domain.BlobMetadata;
|
||||||
|
import org.jclouds.blobstore.domain.Key;
|
||||||
import org.jclouds.util.Utils;
|
import org.jclouds.util.Utils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -39,6 +40,17 @@ import org.jclouds.util.Utils;
|
||||||
*/
|
*/
|
||||||
public class BlobStoreUtils {
|
public class BlobStoreUtils {
|
||||||
|
|
||||||
|
public static Key parseKey(Key key) {
|
||||||
|
|
||||||
|
if (key.getKey().indexOf('/') != -1) {
|
||||||
|
String container = key.getContainer() + '/'
|
||||||
|
+ key.getKey().substring(0, key.getKey().lastIndexOf('/'));
|
||||||
|
String newKey = key.getKey().substring(key.getKey().lastIndexOf('/') + 1);
|
||||||
|
key = new Key(container.replaceAll("//", "/"), newKey);
|
||||||
|
}
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
public static String getContentAsStringAndClose(Blob<? extends BlobMetadata> object)
|
public static String getContentAsStringAndClose(Blob<? extends BlobMetadata> object)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
checkNotNull(object, "s3Object");
|
checkNotNull(object, "s3Object");
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
* under the License.
|
* under the License.
|
||||||
* ====================================================================
|
* ====================================================================
|
||||||
*/
|
*/
|
||||||
package org.jclouds.mezeo.pcs2.binders;
|
package org.jclouds.blobstore.decorators;
|
||||||
|
|
||||||
import static org.testng.Assert.assertEquals;
|
import static org.testng.Assert.assertEquals;
|
||||||
|
|
||||||
|
@ -32,8 +32,10 @@ import java.net.URI;
|
||||||
import javax.ws.rs.core.HttpHeaders;
|
import javax.ws.rs.core.HttpHeaders;
|
||||||
import javax.ws.rs.core.MediaType;
|
import javax.ws.rs.core.MediaType;
|
||||||
|
|
||||||
|
import org.jclouds.blobstore.decorators.AddBlobEntityAsMultipartForm;
|
||||||
|
import org.jclouds.blobstore.domain.Blob;
|
||||||
|
import org.jclouds.blobstore.domain.BlobMetadata;
|
||||||
import org.jclouds.http.HttpRequest;
|
import org.jclouds.http.HttpRequest;
|
||||||
import org.jclouds.mezeo.pcs2.domain.PCSFile;
|
|
||||||
import org.jclouds.util.Utils;
|
import org.jclouds.util.Utils;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
@ -42,34 +44,34 @@ import org.testng.annotations.Test;
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
@Test(testName = "pcs2.PCSFileAsMultipartFormBinderTest")
|
@Test(testName = "blobstore.AddBlobEntityAsMultipartFormTest")
|
||||||
public class PCSFileAsMultipartFormBinderTest {
|
public class AddBlobEntityAsMultipartFormTest {
|
||||||
|
|
||||||
public static String BOUNDRY = PCSFileAsMultipartFormBinder.BOUNDARY;
|
public static String BOUNDRY = AddBlobEntityAsMultipartForm.BOUNDARY;
|
||||||
public static final String EXPECTS;
|
public static final String EXPECTS;
|
||||||
public static final PCSFile TEST_BLOB;
|
public static final Blob<BlobMetadata> TEST_BLOB;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
StringBuilder builder = new StringBuilder("--");
|
StringBuilder builder = new StringBuilder("--");
|
||||||
addData(BOUNDRY, "hello", builder);
|
addData(BOUNDRY, "hello", builder);
|
||||||
builder.append("--").append(BOUNDRY).append("--").append("\r\n");
|
builder.append("--").append(BOUNDRY).append("--").append("\r\n");
|
||||||
EXPECTS = builder.toString();
|
EXPECTS = builder.toString();
|
||||||
TEST_BLOB = new PCSFile("hello");
|
TEST_BLOB = new Blob<BlobMetadata>("hello");
|
||||||
TEST_BLOB.setData("hello");
|
TEST_BLOB.setData("hello");
|
||||||
TEST_BLOB.getMetadata().setContentType(MediaType.TEXT_PLAIN);
|
TEST_BLOB.getMetadata().setContentType(MediaType.TEXT_PLAIN);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testSinglePart() throws IOException {
|
public void testSinglePart() throws IOException {
|
||||||
|
|
||||||
assertEquals(EXPECTS.length(), 123);
|
assertEquals(EXPECTS.length(), 131);
|
||||||
|
|
||||||
PCSFileAsMultipartFormBinder binder = new PCSFileAsMultipartFormBinder();
|
AddBlobEntityAsMultipartForm binder = new AddBlobEntityAsMultipartForm();
|
||||||
|
|
||||||
HttpRequest request = new HttpRequest("GET", URI.create("http://localhost:8001"));
|
HttpRequest request = new HttpRequest("GET", URI.create("http://localhost:8001"));
|
||||||
binder.addEntityToRequest(TEST_BLOB, request);
|
binder.decorateRequest(request, TEST_BLOB);
|
||||||
|
|
||||||
assertEquals(Utils.toStringAndClose((InputStream) request.getEntity()), EXPECTS);
|
assertEquals(Utils.toStringAndClose((InputStream) request.getEntity()), EXPECTS);
|
||||||
assertEquals(request.getFirstHeaderOrNull(HttpHeaders.CONTENT_LENGTH), 123 + "");
|
assertEquals(request.getFirstHeaderOrNull(HttpHeaders.CONTENT_LENGTH), 131 + "");
|
||||||
|
|
||||||
assertEquals(request.getFirstHeaderOrNull(HttpHeaders.CONTENT_TYPE),
|
assertEquals(request.getFirstHeaderOrNull(HttpHeaders.CONTENT_TYPE),
|
||||||
"multipart/form-data; boundary=" + BOUNDRY);
|
"multipart/form-data; boundary=" + BOUNDRY);
|
|
@ -0,0 +1,28 @@
|
||||||
|
package org.jclouds.blobstore.util;
|
||||||
|
|
||||||
|
import static org.testng.Assert.assertEquals;
|
||||||
|
|
||||||
|
import org.jclouds.blobstore.domain.Key;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests behavior of {@code BlobStoreUtils}
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@Test(groups = "unit", testName = "blobstore.BlobStoreUtilsTest")
|
||||||
|
public class BlobStoreUtilsTest {
|
||||||
|
|
||||||
|
public void testParseKey() {
|
||||||
|
Key key = BlobStoreUtils.parseKey(new Key("container", "key"));
|
||||||
|
assertEquals(key.getContainer(), "container");
|
||||||
|
assertEquals(key.getKey(), "key");
|
||||||
|
key = BlobStoreUtils.parseKey(new Key("container", "container/key"));
|
||||||
|
assertEquals(key.getContainer(), "container/container");
|
||||||
|
assertEquals(key.getKey(), "key");
|
||||||
|
key = BlobStoreUtils.parseKey(new Key("container", "/container/key"));
|
||||||
|
assertEquals(key.getContainer(), "container/container");
|
||||||
|
assertEquals(key.getKey(), "key");
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -52,7 +52,7 @@ import org.jclouds.http.config.ConfiguresHttpCommandExecutorService;
|
||||||
import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule;
|
import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule;
|
||||||
import org.jclouds.logging.config.LoggingModule;
|
import org.jclouds.logging.config.LoggingModule;
|
||||||
import org.jclouds.logging.jdk.config.JDKLoggingModule;
|
import org.jclouds.logging.jdk.config.JDKLoggingModule;
|
||||||
import org.jclouds.rest.config.JaxrsModule;
|
import org.jclouds.rest.config.RestModule;
|
||||||
import org.jclouds.util.Jsr330;
|
import org.jclouds.util.Jsr330;
|
||||||
|
|
||||||
import com.google.common.annotations.VisibleForTesting;
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
|
@ -218,7 +218,7 @@ public abstract class CloudContextBuilder<C> {
|
||||||
}
|
}
|
||||||
|
|
||||||
})) {
|
})) {
|
||||||
modules.add(new JaxrsModule());
|
modules.add(new RestModule());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,14 +30,14 @@ import org.jclouds.http.HttpRequest;
|
||||||
import org.jclouds.http.HttpResponse;
|
import org.jclouds.http.HttpResponse;
|
||||||
import org.jclouds.http.HttpUtils;
|
import org.jclouds.http.HttpUtils;
|
||||||
import org.jclouds.logging.Logger;
|
import org.jclouds.logging.Logger;
|
||||||
import org.jclouds.rest.RestContext;
|
import org.jclouds.rest.InvocationContext;
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
public class ParseContentMD5FromHeaders implements Function<HttpResponse, byte[]>, RestContext {
|
public class ParseContentMD5FromHeaders implements Function<HttpResponse, byte[]>, InvocationContext {
|
||||||
|
|
||||||
public static class NoContentMD5Exception extends RuntimeException {
|
public static class NoContentMD5Exception extends RuntimeException {
|
||||||
|
|
||||||
|
|
|
@ -75,7 +75,7 @@ public abstract class BaseHttpCommandExecutorService<Q> implements HttpCommandEx
|
||||||
try {
|
try {
|
||||||
logger.trace("%s - filtering request %s", request.getEndpoint(), request);
|
logger.trace("%s - filtering request %s", request.getEndpoint(), request);
|
||||||
for (HttpRequestFilter filter : request.getFilters()) {
|
for (HttpRequestFilter filter : request.getFilters()) {
|
||||||
filter.filter(request);
|
request = filter.filter(request);
|
||||||
}
|
}
|
||||||
logger.trace("%s - request now %s", request.getEndpoint(), request);
|
logger.trace("%s - request now %s", request.getEndpoint(), request);
|
||||||
nativeRequest = convert(request);
|
nativeRequest = convert(request);
|
||||||
|
|
|
@ -34,7 +34,7 @@ import org.jclouds.http.HttpRequest;
|
||||||
* @see PathParam
|
* @see PathParam
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
public interface RestContext {
|
public interface InvocationContext {
|
||||||
void setContext(HttpRequest request, Object[] args);
|
void setContext(HttpRequest request, Object[] args);
|
||||||
|
|
||||||
Object[] getArgs();
|
Object[] getArgs();
|
|
@ -28,6 +28,8 @@ import java.lang.reflect.Proxy;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import org.jclouds.rest.internal.RestClientProxy;
|
||||||
|
|
||||||
import com.google.inject.Injector;
|
import com.google.inject.Injector;
|
||||||
import com.google.inject.Key;
|
import com.google.inject.Key;
|
||||||
import com.google.inject.TypeLiteral;
|
import com.google.inject.TypeLiteral;
|
||||||
|
|
12
core/src/main/java/org/jclouds/rest/EntityParam.java → core/src/main/java/org/jclouds/rest/annotations/DecoratorParam.java
Normal file → Executable file
12
core/src/main/java/org/jclouds/rest/EntityParam.java → core/src/main/java/org/jclouds/rest/annotations/DecoratorParam.java
Normal file → Executable file
|
@ -21,7 +21,7 @@
|
||||||
* under the License.
|
* under the License.
|
||||||
* ====================================================================
|
* ====================================================================
|
||||||
*/
|
*/
|
||||||
package org.jclouds.rest;
|
package org.jclouds.rest.annotations;
|
||||||
|
|
||||||
import static java.lang.annotation.ElementType.PARAMETER;
|
import static java.lang.annotation.ElementType.PARAMETER;
|
||||||
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||||
|
@ -29,20 +29,20 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||||
import java.lang.annotation.Retention;
|
import java.lang.annotation.Retention;
|
||||||
import java.lang.annotation.Target;
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
import org.jclouds.rest.binders.EntityBinder;
|
import org.jclouds.rest.decorators.RequestDecorator;
|
||||||
import org.jclouds.rest.binders.ToStringEntityBinder;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Designates that this parameter will hold the entity for a PUT or POST command.
|
* Designates that this parameter will modify the request, possibly including adding an entity to
|
||||||
|
* it.
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
@Target(PARAMETER)
|
@Target(PARAMETER)
|
||||||
@Retention(RUNTIME)
|
@Retention(RUNTIME)
|
||||||
public @interface EntityParam {
|
public @interface DecoratorParam {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* how to persist this entity.
|
* how to persist this entity.
|
||||||
*/
|
*/
|
||||||
Class<? extends EntityBinder> value() default ToStringEntityBinder.class;
|
Class<? extends RequestDecorator> value();
|
||||||
}
|
}
|
|
@ -21,7 +21,7 @@
|
||||||
* under the License.
|
* under the License.
|
||||||
* ====================================================================
|
* ====================================================================
|
||||||
*/
|
*/
|
||||||
package org.jclouds.rest;
|
package org.jclouds.rest.annotations;
|
||||||
|
|
||||||
import static java.lang.annotation.ElementType.METHOD;
|
import static java.lang.annotation.ElementType.METHOD;
|
||||||
import static java.lang.annotation.ElementType.PARAMETER;
|
import static java.lang.annotation.ElementType.PARAMETER;
|
2
core/src/main/java/org/jclouds/rest/ExceptionParser.java → core/src/main/java/org/jclouds/rest/annotations/ExceptionParser.java
Normal file → Executable file
2
core/src/main/java/org/jclouds/rest/ExceptionParser.java → core/src/main/java/org/jclouds/rest/annotations/ExceptionParser.java
Normal file → Executable file
|
@ -21,7 +21,7 @@
|
||||||
* under the License.
|
* under the License.
|
||||||
* ====================================================================
|
* ====================================================================
|
||||||
*/
|
*/
|
||||||
package org.jclouds.rest;
|
package org.jclouds.rest.annotations;
|
||||||
|
|
||||||
import static java.lang.annotation.ElementType.METHOD;
|
import static java.lang.annotation.ElementType.METHOD;
|
||||||
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
|
@ -21,7 +21,7 @@
|
||||||
* under the License.
|
* under the License.
|
||||||
* ====================================================================
|
* ====================================================================
|
||||||
*/
|
*/
|
||||||
package org.jclouds.rest;
|
package org.jclouds.rest.annotations;
|
||||||
|
|
||||||
import static java.lang.annotation.ElementType.METHOD;
|
import static java.lang.annotation.ElementType.METHOD;
|
||||||
import static java.lang.annotation.ElementType.TYPE;
|
import static java.lang.annotation.ElementType.TYPE;
|
2
core/src/main/java/org/jclouds/rest/HostPrefixParam.java → core/src/main/java/org/jclouds/rest/annotations/HostPrefixParam.java
Normal file → Executable file
2
core/src/main/java/org/jclouds/rest/HostPrefixParam.java → core/src/main/java/org/jclouds/rest/annotations/HostPrefixParam.java
Normal file → Executable file
|
@ -21,7 +21,7 @@
|
||||||
* under the License.
|
* under the License.
|
||||||
* ====================================================================
|
* ====================================================================
|
||||||
*/
|
*/
|
||||||
package org.jclouds.rest;
|
package org.jclouds.rest.annotations;
|
||||||
|
|
||||||
import java.lang.annotation.ElementType;
|
import java.lang.annotation.ElementType;
|
||||||
import java.lang.annotation.Retention;
|
import java.lang.annotation.Retention;
|
|
@ -21,7 +21,7 @@
|
||||||
* under the License.
|
* under the License.
|
||||||
* ====================================================================
|
* ====================================================================
|
||||||
*/
|
*/
|
||||||
package org.jclouds.rest;
|
package org.jclouds.rest.annotations;
|
||||||
|
|
||||||
import static java.lang.annotation.ElementType.METHOD;
|
import static java.lang.annotation.ElementType.METHOD;
|
||||||
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||||
|
@ -29,7 +29,7 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||||
import java.lang.annotation.Retention;
|
import java.lang.annotation.Retention;
|
||||||
import java.lang.annotation.Target;
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
import org.jclouds.rest.binders.MapEntityBinder;
|
import org.jclouds.rest.decorators.MapRequestDecorator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Designates that this parameter will hold the entity for a PUT or POST command.
|
* Designates that this parameter will hold the entity for a PUT or POST command.
|
||||||
|
@ -41,8 +41,8 @@ import org.jclouds.rest.binders.MapEntityBinder;
|
||||||
public @interface MapBinder {
|
public @interface MapBinder {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* How to bind {@link MapEntityParam} values, if there is no {@link MapEntityBinder} in the method
|
* How to bind {@link MapEntityParam} values, if there is no {@link MapRequestDecorator} in the method
|
||||||
* definition
|
* definition
|
||||||
*/
|
*/
|
||||||
Class<? extends MapEntityBinder> value();
|
Class<? extends MapRequestDecorator> value();
|
||||||
}
|
}
|
|
@ -21,7 +21,7 @@
|
||||||
* under the License.
|
* under the License.
|
||||||
* ====================================================================
|
* ====================================================================
|
||||||
*/
|
*/
|
||||||
package org.jclouds.rest;
|
package org.jclouds.rest.annotations;
|
||||||
|
|
||||||
import static java.lang.annotation.ElementType.PARAMETER;
|
import static java.lang.annotation.ElementType.PARAMETER;
|
||||||
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||||
|
@ -39,7 +39,7 @@ import java.lang.annotation.Target;
|
||||||
public @interface MapEntityParam {
|
public @interface MapEntityParam {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The key used in a map passed to the {@link MapEntityBinder} associated with the request.
|
* The key used in a map passed to the {@link MapRequestDecorator} associated with the request.
|
||||||
*/
|
*/
|
||||||
String value();
|
String value();
|
||||||
}
|
}
|
|
@ -0,0 +1,50 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
|
||||||
|
*
|
||||||
|
* ====================================================================
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
* ====================================================================
|
||||||
|
*/
|
||||||
|
package org.jclouds.rest.annotations;
|
||||||
|
|
||||||
|
import static java.lang.annotation.ElementType.METHOD;
|
||||||
|
import static java.lang.annotation.ElementType.TYPE;
|
||||||
|
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||||
|
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
import javax.ws.rs.MatrixParam;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Designates that a matrix param will be added to the request.
|
||||||
|
*
|
||||||
|
* @see MatrixParam
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@Target( { TYPE, METHOD })
|
||||||
|
@Retention(RUNTIME)
|
||||||
|
public @interface MatrixParams {
|
||||||
|
|
||||||
|
public static final String NULL = "MATRIX_NULL";
|
||||||
|
|
||||||
|
String[] keys();
|
||||||
|
|
||||||
|
String[] values() default NULL;
|
||||||
|
}
|
|
@ -21,7 +21,7 @@
|
||||||
* under the License.
|
* under the License.
|
||||||
* ====================================================================
|
* ====================================================================
|
||||||
*/
|
*/
|
||||||
package org.jclouds.rest;
|
package org.jclouds.rest.annotations;
|
||||||
|
|
||||||
import static java.lang.annotation.ElementType.METHOD;
|
import static java.lang.annotation.ElementType.METHOD;
|
||||||
import static java.lang.annotation.ElementType.PARAMETER;
|
import static java.lang.annotation.ElementType.PARAMETER;
|
|
@ -21,7 +21,7 @@
|
||||||
* under the License.
|
* under the License.
|
||||||
* ====================================================================
|
* ====================================================================
|
||||||
*/
|
*/
|
||||||
package org.jclouds.rest;
|
package org.jclouds.rest.annotations;
|
||||||
|
|
||||||
import static java.lang.annotation.ElementType.*;
|
import static java.lang.annotation.ElementType.*;
|
||||||
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
2
core/src/main/java/org/jclouds/rest/RequestFilters.java → core/src/main/java/org/jclouds/rest/annotations/RequestFilters.java
Normal file → Executable file
2
core/src/main/java/org/jclouds/rest/RequestFilters.java → core/src/main/java/org/jclouds/rest/annotations/RequestFilters.java
Normal file → Executable file
|
@ -21,7 +21,7 @@
|
||||||
* under the License.
|
* under the License.
|
||||||
* ====================================================================
|
* ====================================================================
|
||||||
*/
|
*/
|
||||||
package org.jclouds.rest;
|
package org.jclouds.rest.annotations;
|
||||||
|
|
||||||
import static java.lang.annotation.ElementType.METHOD;
|
import static java.lang.annotation.ElementType.METHOD;
|
||||||
import static java.lang.annotation.ElementType.TYPE;
|
import static java.lang.annotation.ElementType.TYPE;
|
2
core/src/main/java/org/jclouds/rest/ResponseParser.java → core/src/main/java/org/jclouds/rest/annotations/ResponseParser.java
Normal file → Executable file
2
core/src/main/java/org/jclouds/rest/ResponseParser.java → core/src/main/java/org/jclouds/rest/annotations/ResponseParser.java
Normal file → Executable file
|
@ -21,7 +21,7 @@
|
||||||
* under the License.
|
* under the License.
|
||||||
* ====================================================================
|
* ====================================================================
|
||||||
*/
|
*/
|
||||||
package org.jclouds.rest;
|
package org.jclouds.rest.annotations;
|
||||||
|
|
||||||
import static java.lang.annotation.ElementType.METHOD;
|
import static java.lang.annotation.ElementType.METHOD;
|
||||||
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
2
core/src/main/java/org/jclouds/rest/SkipEncoding.java → core/src/main/java/org/jclouds/rest/annotations/SkipEncoding.java
Normal file → Executable file
2
core/src/main/java/org/jclouds/rest/SkipEncoding.java → core/src/main/java/org/jclouds/rest/annotations/SkipEncoding.java
Normal file → Executable file
|
@ -21,7 +21,7 @@
|
||||||
* under the License.
|
* under the License.
|
||||||
* ====================================================================
|
* ====================================================================
|
||||||
*/
|
*/
|
||||||
package org.jclouds.rest;
|
package org.jclouds.rest.annotations;
|
||||||
|
|
||||||
import static java.lang.annotation.ElementType.TYPE;
|
import static java.lang.annotation.ElementType.TYPE;
|
||||||
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
2
core/src/main/java/org/jclouds/rest/VirtualHost.java → core/src/main/java/org/jclouds/rest/annotations/VirtualHost.java
Normal file → Executable file
2
core/src/main/java/org/jclouds/rest/VirtualHost.java → core/src/main/java/org/jclouds/rest/annotations/VirtualHost.java
Normal file → Executable file
|
@ -21,7 +21,7 @@
|
||||||
* under the License.
|
* under the License.
|
||||||
* ====================================================================
|
* ====================================================================
|
||||||
*/
|
*/
|
||||||
package org.jclouds.rest;
|
package org.jclouds.rest.annotations;
|
||||||
|
|
||||||
import static java.lang.annotation.ElementType.TYPE;
|
import static java.lang.annotation.ElementType.TYPE;
|
||||||
import static java.lang.annotation.ElementType.METHOD;
|
import static java.lang.annotation.ElementType.METHOD;
|
|
@ -21,7 +21,7 @@
|
||||||
* under the License.
|
* under the License.
|
||||||
* ====================================================================
|
* ====================================================================
|
||||||
*/
|
*/
|
||||||
package org.jclouds.rest;
|
package org.jclouds.rest.annotations;
|
||||||
|
|
||||||
import static java.lang.annotation.ElementType.METHOD;
|
import static java.lang.annotation.ElementType.METHOD;
|
||||||
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
|
@ -1,49 +0,0 @@
|
||||||
/**
|
|
||||||
*
|
|
||||||
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
|
|
||||||
*
|
|
||||||
* ====================================================================
|
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one
|
|
||||||
* or more contributor license agreements. See the NOTICE file
|
|
||||||
* distributed with this work for additional information
|
|
||||||
* regarding copyright ownership. The ASF licenses this file
|
|
||||||
* to you under the Apache License, Version 2.0 (the
|
|
||||||
* "License"); you may not use this file except in compliance
|
|
||||||
* with the License. You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing,
|
|
||||||
* software distributed under the License is distributed on an
|
|
||||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
||||||
* KIND, either express or implied. See the License for the
|
|
||||||
* specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
* ====================================================================
|
|
||||||
*/
|
|
||||||
package org.jclouds.rest.binders;
|
|
||||||
|
|
||||||
import javax.ws.rs.core.HttpHeaders;
|
|
||||||
|
|
||||||
import org.jclouds.http.HttpRequest;
|
|
||||||
import org.jclouds.http.options.HttpRequestOptions;
|
|
||||||
|
|
||||||
import javax.inject.Singleton;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds an entity to a request.
|
|
||||||
*
|
|
||||||
* @author Adrian Cole
|
|
||||||
*/
|
|
||||||
@Singleton
|
|
||||||
public class HttpRequestOptionsBinder implements EntityBinder {
|
|
||||||
public void addEntityToRequest(Object entity, HttpRequest request) {
|
|
||||||
HttpRequestOptions options = (HttpRequestOptions) entity;
|
|
||||||
String stringEntity = options.buildStringEntity();
|
|
||||||
if (stringEntity != null) {
|
|
||||||
request.getHeaders().put(HttpHeaders.CONTENT_TYPE, "application/unknown");
|
|
||||||
request.getHeaders().put(HttpHeaders.CONTENT_LENGTH, stringEntity.getBytes().length + "");
|
|
||||||
request.setEntity(stringEntity);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
4
core/src/main/java/org/jclouds/rest/config/JaxrsModule.java → core/src/main/java/org/jclouds/rest/config/RestModule.java
Normal file → Executable file
4
core/src/main/java/org/jclouds/rest/config/JaxrsModule.java → core/src/main/java/org/jclouds/rest/config/RestModule.java
Normal file → Executable file
|
@ -28,7 +28,7 @@ import javax.ws.rs.ext.RuntimeDelegate;
|
||||||
import org.jclouds.http.TransformingHttpCommand;
|
import org.jclouds.http.TransformingHttpCommand;
|
||||||
import org.jclouds.http.TransformingHttpCommandImpl;
|
import org.jclouds.http.TransformingHttpCommandImpl;
|
||||||
import org.jclouds.http.functions.config.ParserModule;
|
import org.jclouds.http.functions.config.ParserModule;
|
||||||
import org.jclouds.rest.RuntimeDelegateImpl;
|
import org.jclouds.rest.internal.RuntimeDelegateImpl;
|
||||||
|
|
||||||
import com.google.inject.AbstractModule;
|
import com.google.inject.AbstractModule;
|
||||||
import com.google.inject.TypeLiteral;
|
import com.google.inject.TypeLiteral;
|
||||||
|
@ -38,7 +38,7 @@ import com.google.inject.assistedinject.FactoryProvider;
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
public class JaxrsModule extends AbstractModule {
|
public class RestModule extends AbstractModule {
|
||||||
private final static TypeLiteral<TransformingHttpCommand.Factory> httpCommandFactoryLiteral = new TypeLiteral<TransformingHttpCommand.Factory>() {
|
private final static TypeLiteral<TransformingHttpCommand.Factory> httpCommandFactoryLiteral = new TypeLiteral<TransformingHttpCommand.Factory>() {
|
||||||
};
|
};
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
* under the License.
|
* under the License.
|
||||||
* ====================================================================
|
* ====================================================================
|
||||||
*/
|
*/
|
||||||
package org.jclouds.rest.binders;
|
package org.jclouds.rest.decorators;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkState;
|
import static com.google.common.base.Preconditions.checkState;
|
||||||
|
|
||||||
|
@ -42,16 +42,16 @@ import com.google.gson.Gson;
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
* @since 4.0
|
* @since 4.0
|
||||||
*/
|
*/
|
||||||
public class JsonBinder implements MapEntityBinder {
|
public class AddAsJsonEntity implements MapRequestDecorator {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
protected Gson gson;
|
protected Gson gson;
|
||||||
|
|
||||||
public void addEntityToRequest(Map<String, String> postParams, HttpRequest request) {
|
public HttpRequest decorateRequest(HttpRequest request, Map<String, String> postParams) {
|
||||||
addEntityToRequest((Object) postParams, request);
|
return decorateRequest(request, (Object) postParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addEntityToRequest(Object toBind, HttpRequest request) {
|
public HttpRequest decorateRequest(HttpRequest request, Object toBind) {
|
||||||
checkState(gson != null, "Program error: gson should have been injected at this point");
|
checkState(gson != null, "Program error: gson should have been injected at this point");
|
||||||
String json = gson.toJson(toBind);
|
String json = gson.toJson(toBind);
|
||||||
request.setEntity(json);
|
request.setEntity(json);
|
||||||
|
@ -59,6 +59,7 @@ public class JsonBinder implements MapEntityBinder {
|
||||||
Collections.singletonList(json.getBytes().length + ""));
|
Collections.singletonList(json.getBytes().length + ""));
|
||||||
request.getHeaders().replaceValues(HttpHeaders.CONTENT_TYPE,
|
request.getHeaders().replaceValues(HttpHeaders.CONTENT_TYPE,
|
||||||
Collections.singletonList(MediaType.APPLICATION_JSON));
|
Collections.singletonList(MediaType.APPLICATION_JSON));
|
||||||
|
return request;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -21,25 +21,26 @@
|
||||||
* under the License.
|
* under the License.
|
||||||
* ====================================================================
|
* ====================================================================
|
||||||
*/
|
*/
|
||||||
package org.jclouds.rest.binders;
|
package org.jclouds.rest.decorators;
|
||||||
|
|
||||||
|
import javax.inject.Singleton;
|
||||||
import javax.ws.rs.core.HttpHeaders;
|
import javax.ws.rs.core.HttpHeaders;
|
||||||
|
|
||||||
import org.jclouds.http.HttpRequest;
|
import org.jclouds.http.HttpRequest;
|
||||||
|
|
||||||
import javax.inject.Singleton;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds an entity to a request.
|
* Adds an entity to a request.
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
@Singleton
|
@Singleton
|
||||||
public class ToStringEntityBinder implements EntityBinder {
|
public class AddAsStringEntity implements RequestDecorator {
|
||||||
public void addEntityToRequest(Object entity, HttpRequest request) {
|
public HttpRequest decorateRequest(HttpRequest request, Object entity) {
|
||||||
String stringEntity = entity.toString();
|
String stringEntity = entity.toString();
|
||||||
request.getHeaders().put(HttpHeaders.CONTENT_TYPE, "application/unknown");
|
if (request.getFirstHeaderOrNull(HttpHeaders.CONTENT_TYPE) == null)
|
||||||
|
request.getHeaders().put(HttpHeaders.CONTENT_TYPE, "application/unknown");
|
||||||
request.getHeaders().put(HttpHeaders.CONTENT_LENGTH, stringEntity.getBytes().length + "");
|
request.getHeaders().put(HttpHeaders.CONTENT_LENGTH, stringEntity.getBytes().length + "");
|
||||||
request.setEntity(stringEntity);
|
request.setEntity(stringEntity);
|
||||||
|
return request;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -21,7 +21,7 @@
|
||||||
* under the License.
|
* under the License.
|
||||||
* ====================================================================
|
* ====================================================================
|
||||||
*/
|
*/
|
||||||
package org.jclouds.rest.binders;
|
package org.jclouds.rest.decorators;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
@ -33,13 +33,13 @@ import org.jclouds.http.HttpRequest;
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public interface MapEntityBinder extends EntityBinder {
|
public interface MapRequestDecorator extends RequestDecorator {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* creates and binds the POST entity to the request using parameters specified.
|
* creates and binds the POST entity to the request using parameters specified.
|
||||||
*
|
*
|
||||||
* @see MapEntityParam
|
* @see MapEntityParam
|
||||||
*/
|
*/
|
||||||
public void addEntityToRequest(Map<String,String> postParams, HttpRequest request);
|
public HttpRequest decorateRequest(HttpRequest request, Map<String, String> postParams);
|
||||||
|
|
||||||
}
|
}
|
|
@ -21,7 +21,7 @@
|
||||||
* under the License.
|
* under the License.
|
||||||
* ====================================================================
|
* ====================================================================
|
||||||
*/
|
*/
|
||||||
package org.jclouds.rest.binders;
|
package org.jclouds.rest.decorators;
|
||||||
|
|
||||||
import org.jclouds.http.HttpRequest;
|
import org.jclouds.http.HttpRequest;
|
||||||
|
|
||||||
|
@ -30,6 +30,6 @@ import org.jclouds.http.HttpRequest;
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
public interface EntityBinder {
|
public interface RequestDecorator {
|
||||||
public void addEntityToRequest(Object toBind, HttpRequest request);
|
public HttpRequest decorateRequest(HttpRequest request, Object input);
|
||||||
}
|
}
|
|
@ -21,7 +21,7 @@
|
||||||
* under the License.
|
* under the License.
|
||||||
* ====================================================================
|
* ====================================================================
|
||||||
*/
|
*/
|
||||||
package org.jclouds.rest;
|
package org.jclouds.rest.internal;
|
||||||
|
|
||||||
import java.util.SortedSet;
|
import java.util.SortedSet;
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
* under the License.
|
* under the License.
|
||||||
* ====================================================================
|
* ====================================================================
|
||||||
*/
|
*/
|
||||||
package org.jclouds.rest;
|
package org.jclouds.rest.internal;
|
||||||
|
|
||||||
import java.util.SortedSet;
|
import java.util.SortedSet;
|
||||||
import java.util.TreeSet;
|
import java.util.TreeSet;
|
|
@ -21,7 +21,7 @@
|
||||||
* under the License.
|
* under the License.
|
||||||
* ====================================================================
|
* ====================================================================
|
||||||
*/
|
*/
|
||||||
package org.jclouds.rest;
|
package org.jclouds.rest.internal;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkArgument;
|
import static com.google.common.base.Preconditions.checkArgument;
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
@ -33,7 +33,9 @@ import java.lang.annotation.Annotation;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.URLEncoder;
|
import java.net.URLEncoder;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -45,8 +47,11 @@ import javax.annotation.Resource;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Named;
|
import javax.inject.Named;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
import javax.ws.rs.Consumes;
|
||||||
import javax.ws.rs.HeaderParam;
|
import javax.ws.rs.HeaderParam;
|
||||||
|
import javax.ws.rs.MatrixParam;
|
||||||
import javax.ws.rs.PathParam;
|
import javax.ws.rs.PathParam;
|
||||||
|
import javax.ws.rs.Produces;
|
||||||
import javax.ws.rs.QueryParam;
|
import javax.ws.rs.QueryParam;
|
||||||
import javax.ws.rs.core.HttpHeaders;
|
import javax.ws.rs.core.HttpHeaders;
|
||||||
import javax.ws.rs.core.UriBuilder;
|
import javax.ws.rs.core.UriBuilder;
|
||||||
|
@ -65,9 +70,24 @@ import org.jclouds.http.functions.ReturnVoidIf2xx;
|
||||||
import org.jclouds.http.functions.ParseSax.HandlerWithResult;
|
import org.jclouds.http.functions.ParseSax.HandlerWithResult;
|
||||||
import org.jclouds.http.options.HttpRequestOptions;
|
import org.jclouds.http.options.HttpRequestOptions;
|
||||||
import org.jclouds.logging.Logger;
|
import org.jclouds.logging.Logger;
|
||||||
import org.jclouds.rest.binders.EntityBinder;
|
import org.jclouds.rest.InvocationContext;
|
||||||
import org.jclouds.rest.binders.HttpRequestOptionsBinder;
|
import org.jclouds.rest.annotations.DecoratorParam;
|
||||||
import org.jclouds.rest.binders.MapEntityBinder;
|
import org.jclouds.rest.annotations.Endpoint;
|
||||||
|
import org.jclouds.rest.annotations.ExceptionParser;
|
||||||
|
import org.jclouds.rest.annotations.Headers;
|
||||||
|
import org.jclouds.rest.annotations.HostPrefixParam;
|
||||||
|
import org.jclouds.rest.annotations.MapBinder;
|
||||||
|
import org.jclouds.rest.annotations.MapEntityParam;
|
||||||
|
import org.jclouds.rest.annotations.MatrixParams;
|
||||||
|
import org.jclouds.rest.annotations.ParamParser;
|
||||||
|
import org.jclouds.rest.annotations.QueryParams;
|
||||||
|
import org.jclouds.rest.annotations.RequestFilters;
|
||||||
|
import org.jclouds.rest.annotations.ResponseParser;
|
||||||
|
import org.jclouds.rest.annotations.SkipEncoding;
|
||||||
|
import org.jclouds.rest.annotations.VirtualHost;
|
||||||
|
import org.jclouds.rest.annotations.XMLResponseParser;
|
||||||
|
import org.jclouds.rest.decorators.MapRequestDecorator;
|
||||||
|
import org.jclouds.rest.decorators.RequestDecorator;
|
||||||
|
|
||||||
import com.google.common.annotations.VisibleForTesting;
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
|
@ -89,17 +109,18 @@ import com.google.inject.internal.Lists;
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
@Singleton
|
@Singleton
|
||||||
public class JaxrsAnnotationProcessor<T> {
|
public class RestAnnotationProcessor<T> {
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
protected Logger logger = Logger.NULL;
|
protected Logger logger = Logger.NULL;
|
||||||
|
|
||||||
private final Class<T> declaring;
|
private final Class<T> declaring;
|
||||||
|
|
||||||
private final Map<Method, Map<Integer, Set<Annotation>>> methodToIndexOfParamToEntityAnnotation = createMethodToIndexOfParamToAnnotation(EntityParam.class);
|
private final Map<Method, Map<Integer, Set<Annotation>>> methodToIndexOfParamToDecoratorParamAnnotation = createMethodToIndexOfParamToAnnotation(DecoratorParam.class);
|
||||||
private final Map<Method, Map<Integer, Set<Annotation>>> methodToIndexOfParamToHeaderParamAnnotations = createMethodToIndexOfParamToAnnotation(HeaderParam.class);
|
private final Map<Method, Map<Integer, Set<Annotation>>> methodToIndexOfParamToHeaderParamAnnotations = createMethodToIndexOfParamToAnnotation(HeaderParam.class);
|
||||||
private final Map<Method, Map<Integer, Set<Annotation>>> methodToIndexOfParamToHostPrefixParamAnnotations = createMethodToIndexOfParamToAnnotation(HostPrefixParam.class);
|
private final Map<Method, Map<Integer, Set<Annotation>>> methodToIndexOfParamToHostPrefixParamAnnotations = createMethodToIndexOfParamToAnnotation(HostPrefixParam.class);
|
||||||
private final Map<Method, Map<Integer, Set<Annotation>>> methodToindexOfParamToEndpointAnnotations = createMethodToIndexOfParamToAnnotation(Endpoint.class);
|
private final Map<Method, Map<Integer, Set<Annotation>>> methodToindexOfParamToEndpointAnnotations = createMethodToIndexOfParamToAnnotation(Endpoint.class);
|
||||||
|
private final Map<Method, Map<Integer, Set<Annotation>>> methodToindexOfParamToMatrixParamAnnotations = createMethodToIndexOfParamToAnnotation(MatrixParam.class);
|
||||||
private final Map<Method, Map<Integer, Set<Annotation>>> methodToindexOfParamToQueryParamAnnotations = createMethodToIndexOfParamToAnnotation(QueryParam.class);
|
private final Map<Method, Map<Integer, Set<Annotation>>> methodToindexOfParamToQueryParamAnnotations = createMethodToIndexOfParamToAnnotation(QueryParam.class);
|
||||||
private final Map<Method, Map<Integer, Set<Annotation>>> methodToindexOfParamToPathParamAnnotations = createMethodToIndexOfParamToAnnotation(PathParam.class);
|
private final Map<Method, Map<Integer, Set<Annotation>>> methodToindexOfParamToPathParamAnnotations = createMethodToIndexOfParamToAnnotation(PathParam.class);
|
||||||
private final Map<Method, Map<Integer, Set<Annotation>>> methodToindexOfParamToPostParamAnnotations = createMethodToIndexOfParamToAnnotation(MapEntityParam.class);
|
private final Map<Method, Map<Integer, Set<Annotation>>> methodToindexOfParamToPostParamAnnotations = createMethodToIndexOfParamToAnnotation(MapEntityParam.class);
|
||||||
|
@ -172,8 +193,8 @@ public class JaxrsAnnotationProcessor<T> {
|
||||||
} else {
|
} else {
|
||||||
transformer = injector.getInstance(getParserOrThrowException(method));
|
transformer = injector.getInstance(getParserOrThrowException(method));
|
||||||
}
|
}
|
||||||
if (transformer instanceof RestContext) {
|
if (transformer instanceof InvocationContext) {
|
||||||
((RestContext) transformer).setContext(request, args);
|
((InvocationContext) transformer).setContext(request, args);
|
||||||
}
|
}
|
||||||
return transformer;
|
return transformer;
|
||||||
}
|
}
|
||||||
|
@ -189,16 +210,15 @@ public class JaxrsAnnotationProcessor<T> {
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@Inject
|
@Inject
|
||||||
public JaxrsAnnotationProcessor(Injector injector, ParseSax.Factory parserFactory,
|
public RestAnnotationProcessor(Injector injector, ParseSax.Factory parserFactory,
|
||||||
TypeLiteral<T> typeLiteral) {
|
TypeLiteral<T> typeLiteral) {
|
||||||
this.declaring = (Class<T>) typeLiteral.getRawType();
|
this.declaring = (Class<T>) typeLiteral.getRawType();
|
||||||
this.injector = injector;
|
this.injector = injector;
|
||||||
this.parserFactory = parserFactory;
|
this.parserFactory = parserFactory;
|
||||||
this.optionsBinder = injector.getInstance(HttpRequestOptionsBinder.class);
|
|
||||||
seedCache(declaring);
|
seedCache(declaring);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Method getDelegateOrNull(Method in) {
|
public Method getDelegateOrNull(Method in) {
|
||||||
return delegationMap.get(new MethodKey(in));
|
return delegationMap.get(new MethodKey(in));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -208,9 +228,10 @@ public class JaxrsAnnotationProcessor<T> {
|
||||||
for (Method method : methods) {
|
for (Method method : methods) {
|
||||||
if (isHttpMethod(method)) {
|
if (isHttpMethod(method)) {
|
||||||
for (int index = 0; index < method.getParameterTypes().length; index++) {
|
for (int index = 0; index < method.getParameterTypes().length; index++) {
|
||||||
methodToIndexOfParamToEntityAnnotation.get(method).get(index);
|
methodToIndexOfParamToDecoratorParamAnnotation.get(method).get(index);
|
||||||
methodToIndexOfParamToHeaderParamAnnotations.get(method).get(index);
|
methodToIndexOfParamToHeaderParamAnnotations.get(method).get(index);
|
||||||
methodToIndexOfParamToHostPrefixParamAnnotations.get(method).get(index);
|
methodToIndexOfParamToHostPrefixParamAnnotations.get(method).get(index);
|
||||||
|
methodToindexOfParamToMatrixParamAnnotations.get(method).get(index);
|
||||||
methodToindexOfParamToQueryParamAnnotations.get(method).get(index);
|
methodToindexOfParamToQueryParamAnnotations.get(method).get(index);
|
||||||
methodToindexOfParamToEndpointAnnotations.get(method).get(index);
|
methodToindexOfParamToEndpointAnnotations.get(method).get(index);
|
||||||
methodToindexOfParamToPathParamAnnotations.get(method).get(index);
|
methodToindexOfParamToPathParamAnnotations.get(method).get(index);
|
||||||
|
@ -272,8 +293,6 @@ public class JaxrsAnnotationProcessor<T> {
|
||||||
|
|
||||||
final Injector injector;
|
final Injector injector;
|
||||||
|
|
||||||
private HttpRequestOptionsBinder optionsBinder;
|
|
||||||
|
|
||||||
public HttpRequest createRequest(Method method, Object[] args) {
|
public HttpRequest createRequest(Method method, Object[] args) {
|
||||||
URI endpoint = getEndpointFor(method, args);
|
URI endpoint = getEndpointFor(method, args);
|
||||||
|
|
||||||
|
@ -283,68 +302,116 @@ public class JaxrsAnnotationProcessor<T> {
|
||||||
builder.path(declaring);
|
builder.path(declaring);
|
||||||
builder.path(method);
|
builder.path(method);
|
||||||
|
|
||||||
if (declaring.isAnnotationPresent(QueryParams.class)) {
|
Multimap<String, String> tokenValues;
|
||||||
QueryParams query = declaring.getAnnotation(QueryParams.class);
|
if (declaring.isAnnotationPresent(SkipEncoding.class)) {
|
||||||
addQuery(builder, query);
|
tokenValues = encodeValues(getPathParamKeyValues(method, args), declaring.getAnnotation(
|
||||||
|
SkipEncoding.class).value());
|
||||||
|
} else {
|
||||||
|
tokenValues = encodeValues(getPathParamKeyValues(method, args));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (method.isAnnotationPresent(QueryParams.class)) {
|
addQueryParams(method, args, builder, tokenValues.entries());
|
||||||
QueryParams query = method.getAnnotation(QueryParams.class);
|
addMatrixParams(method, args, builder, tokenValues.entries());
|
||||||
addQuery(builder, query);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (Entry<String, String> query : getQueryParamKeyValues(method, args).entrySet()) {
|
Multimap<String, String> headers = buildHeaders(method, args, tokenValues.entries());
|
||||||
builder.queryParam(query.getKey(), query.getValue());
|
|
||||||
}
|
|
||||||
|
|
||||||
Multimap<String, String> headers = buildHeaders(method, args);
|
|
||||||
|
|
||||||
|
String stringEntity = null;
|
||||||
HttpRequestOptions options = findOptionsIn(method, args);
|
HttpRequestOptions options = findOptionsIn(method, args);
|
||||||
if (options != null) {
|
if (options != null) {
|
||||||
injector.injectMembers(options);// TODO test case
|
injector.injectMembers(options);// TODO test case
|
||||||
headers.putAll(options.buildRequestHeaders());
|
for (Entry<String, String> header : options.buildRequestHeaders().entries()) {
|
||||||
|
headers.put(header.getKey(), replaceTokens(header.getValue(), tokenValues.entries()));
|
||||||
|
}
|
||||||
for (Entry<String, String> query : options.buildQueryParameters().entries()) {
|
for (Entry<String, String> query : options.buildQueryParameters().entries()) {
|
||||||
builder.queryParam(query.getKey(), query.getValue());
|
builder.queryParam(query.getKey(), replaceTokens(query.getValue(), tokenValues
|
||||||
|
.entries()));
|
||||||
}
|
}
|
||||||
for (Entry<String, String> matrix : options.buildMatrixParameters().entries()) {
|
for (Entry<String, String> matrix : options.buildMatrixParameters().entries()) {
|
||||||
builder.matrixParam(matrix.getKey(), matrix.getValue());
|
builder.matrixParam(matrix.getKey(), replaceTokens(matrix.getValue(), tokenValues
|
||||||
|
.entries()));
|
||||||
}
|
}
|
||||||
String pathSuffix = options.buildPathSuffix();
|
String pathSuffix = options.buildPathSuffix();
|
||||||
if (pathSuffix != null) {
|
if (pathSuffix != null) {
|
||||||
builder.path(pathSuffix);
|
builder.path(pathSuffix);
|
||||||
}
|
}
|
||||||
|
stringEntity = options.buildStringEntity();
|
||||||
|
if (stringEntity != null) {
|
||||||
|
headers.put(HttpHeaders.CONTENT_LENGTH, stringEntity.getBytes().length + "");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
URI endPoint;
|
URI endPoint;
|
||||||
try {
|
try {
|
||||||
addHeaderIfAnnotationPresentOnMethod(headers, method, args);
|
endPoint = builder.buildFromEncodedMap(convertUnsafe(tokenValues));
|
||||||
if (declaring.isAnnotationPresent(SkipEncoding.class)) {
|
|
||||||
endPoint = builder.buildFromEncodedMap(getEncodedPathParamKeyValues(method, args,
|
|
||||||
declaring.getAnnotation(SkipEncoding.class).value()));
|
|
||||||
} else {
|
|
||||||
endPoint = builder.buildFromEncodedMap(getEncodedPathParamKeyValues(method, args));
|
|
||||||
}
|
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
throw new IllegalStateException(e);
|
throw new IllegalStateException(e);
|
||||||
} catch (UriBuilderException e) {
|
} catch (UriBuilderException e) {
|
||||||
throw new IllegalStateException(e);
|
throw new IllegalStateException(e);
|
||||||
} catch (UnsupportedEncodingException e) {
|
|
||||||
throw new IllegalStateException(e);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
HttpRequest request = new HttpRequest(httpMethod, endPoint, headers);
|
HttpRequest request = new HttpRequest(httpMethod, endPoint, headers);
|
||||||
addHostHeaderIfAnnotatedWithVirtualHost(headers, request.getEndpoint().getHost(), method);
|
addHostHeaderIfAnnotatedWithVirtualHost(headers, request.getEndpoint().getHost(), method);
|
||||||
addFiltersIfAnnotated(method, request);
|
addFiltersIfAnnotated(method, request);
|
||||||
|
if (stringEntity != null) {
|
||||||
buildEntityIfPostOrPutRequest(method, args, request);
|
request.setEntity(stringEntity);
|
||||||
return request;
|
if (headers.get(HttpHeaders.CONTENT_TYPE) != null)
|
||||||
|
headers.put(HttpHeaders.CONTENT_TYPE, "application/unknown");
|
||||||
|
}
|
||||||
|
return decorateRequest(method, args, request);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addQuery(UriBuilder builder, QueryParams query) {
|
private void addMatrixParams(Method method, Object[] args, UriBuilder builder,
|
||||||
|
Collection<Entry<String, String>> tokenValues) {
|
||||||
|
if (declaring.isAnnotationPresent(MatrixParams.class)) {
|
||||||
|
MatrixParams query = declaring.getAnnotation(MatrixParams.class);
|
||||||
|
addMatrix(builder, query, tokenValues);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (method.isAnnotationPresent(MatrixParams.class)) {
|
||||||
|
MatrixParams query = method.getAnnotation(MatrixParams.class);
|
||||||
|
addMatrix(builder, query, tokenValues);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Entry<String, String> query : getMatrixParamKeyValues(method, args).entries()) {
|
||||||
|
builder.queryParam(query.getKey(), replaceTokens(query.getValue(), tokenValues));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addQueryParams(Method method, Object[] args, UriBuilder builder,
|
||||||
|
Collection<Entry<String, String>> tokenValues) {
|
||||||
|
if (declaring.isAnnotationPresent(QueryParams.class)) {
|
||||||
|
QueryParams query = declaring.getAnnotation(QueryParams.class);
|
||||||
|
addQuery(builder, query, tokenValues);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (method.isAnnotationPresent(QueryParams.class)) {
|
||||||
|
QueryParams query = method.getAnnotation(QueryParams.class);
|
||||||
|
addQuery(builder, query, tokenValues);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Entry<String, String> query : getQueryParamKeyValues(method, args).entries()) {
|
||||||
|
builder.queryParam(query.getKey(), replaceTokens(query.getValue(), tokenValues));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addQuery(UriBuilder builder, QueryParams query,
|
||||||
|
Collection<Entry<String, String>> tokenValues) {
|
||||||
for (int i = 0; i < query.keys().length; i++) {
|
for (int i = 0; i < query.keys().length; i++) {
|
||||||
if (query.values()[i].equals(QueryParams.NULL)) {
|
if (query.values()[i].equals(QueryParams.NULL)) {
|
||||||
builder.replaceQuery(query.keys()[i]);
|
builder.replaceQuery(query.keys()[i]);
|
||||||
} else {
|
} else {
|
||||||
builder.queryParam(query.keys()[i], query.values()[i]);
|
builder.queryParam(query.keys()[i], replaceTokens(query.values()[i], tokenValues));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addMatrix(UriBuilder builder, MatrixParams matrix,
|
||||||
|
Collection<Entry<String, String>> tokenValues) {
|
||||||
|
for (int i = 0; i < matrix.keys().length; i++) {
|
||||||
|
if (matrix.values()[i].equals(MatrixParams.NULL)) {
|
||||||
|
builder.replaceMatrix(matrix.keys()[i]);
|
||||||
|
} else {
|
||||||
|
builder.matrixParam(matrix.keys()[i], replaceTokens(matrix.values()[i], tokenValues));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -461,27 +528,27 @@ public class JaxrsAnnotationProcessor<T> {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MapEntityBinder getMapEntityBinderOrNull(Method method, Object[] args) {
|
public MapRequestDecorator getMapEntityBinderOrNull(Method method, Object[] args) {
|
||||||
if (args != null) {
|
if (args != null) {
|
||||||
for (Object arg : args) {
|
for (Object arg : args) {
|
||||||
if (arg instanceof Object[]) {
|
if (arg instanceof Object[]) {
|
||||||
Object[] postBinders = (Object[]) arg;
|
Object[] postBinders = (Object[]) arg;
|
||||||
if (postBinders.length == 0) {
|
if (postBinders.length == 0) {
|
||||||
} else if (postBinders.length == 1) {
|
} else if (postBinders.length == 1) {
|
||||||
if (postBinders[0] instanceof MapEntityBinder) {
|
if (postBinders[0] instanceof MapRequestDecorator) {
|
||||||
MapEntityBinder binder = (MapEntityBinder) postBinders[0];
|
MapRequestDecorator binder = (MapRequestDecorator) postBinders[0];
|
||||||
injector.injectMembers(binder);
|
injector.injectMembers(binder);
|
||||||
return binder;
|
return binder;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (postBinders[0] instanceof MapEntityBinder) {
|
if (postBinders[0] instanceof MapRequestDecorator) {
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
"we currently do not support multiple varargs postBinders in: "
|
"we currently do not support multiple varargs postBinders in: "
|
||||||
+ method.getName());
|
+ method.getName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (arg instanceof MapEntityBinder) {
|
} else if (arg instanceof MapRequestDecorator) {
|
||||||
MapEntityBinder binder = (MapEntityBinder) arg;
|
MapRequestDecorator binder = (MapRequestDecorator) arg;
|
||||||
injector.injectMembers(binder);
|
injector.injectMembers(binder);
|
||||||
return binder;
|
return binder;
|
||||||
}
|
}
|
||||||
|
@ -494,7 +561,7 @@ public class JaxrsAnnotationProcessor<T> {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Map<String, String> constants = Maps.newHashMap();
|
private Multimap<String, String> constants = HashMultimap.create();
|
||||||
|
|
||||||
public boolean isHttpMethod(Method method) {
|
public boolean isHttpMethod(Method method) {
|
||||||
return IsHttpMethod.getHttpMethods(method) != null;
|
return IsHttpMethod.getHttpMethods(method) != null;
|
||||||
|
@ -528,49 +595,41 @@ public class JaxrsAnnotationProcessor<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public HttpRequest buildEntityIfPostOrPutRequest(Method method, Object[] args,
|
public HttpRequest decorateRequest(Method method, Object[] args, HttpRequest request) {
|
||||||
HttpRequest request) {
|
MapRequestDecorator mapBinder = getMapEntityBinderOrNull(method, args);
|
||||||
OUTER: if (request.getMethod().toUpperCase().equals("POST")
|
Map<String, String> mapParams = buildPostParams(method, args);
|
||||||
|| request.getMethod().toUpperCase().equals("PUT")) {
|
// MapEntityBinder is only useful if there are parameters. We guard here in case the
|
||||||
MapEntityBinder mapBinder = getMapEntityBinderOrNull(method, args);
|
// MapEntityBinder is also an EntityBinder. If so, it can be used with or without
|
||||||
Map<String, String> mapParams = buildPostParams(method, args);
|
// parameters.
|
||||||
// MapEntityBinder is only useful if there are parameters. We guard here in case the
|
if (mapBinder != null) {
|
||||||
// MapEntityBinder is also an EntityBinder. If so, it can be used with or without
|
mapBinder.decorateRequest(request, mapParams);
|
||||||
// parameters.
|
return request;
|
||||||
if (mapBinder != null) {
|
}
|
||||||
mapBinder.addEntityToRequest(mapParams, request);
|
|
||||||
break OUTER;
|
|
||||||
}
|
|
||||||
HttpRequestOptions options = findOptionsIn(method, args);
|
|
||||||
if (options != null) {
|
|
||||||
optionsBinder.addEntityToRequest(options, request);
|
|
||||||
}
|
|
||||||
if (request.getEntity() == null) {
|
|
||||||
|
|
||||||
Map<Integer, Set<Annotation>> indexToEntityAnnotation = indexWithOnlyOneAnnotation(
|
for (Entry<Integer, Set<Annotation>> entry : Maps.filterValues(
|
||||||
method, "@Entity", methodToIndexOfParamToEntityAnnotation);
|
methodToIndexOfParamToDecoratorParamAnnotation.get(method),
|
||||||
|
new Predicate<Set<Annotation>>() {
|
||||||
if (indexToEntityAnnotation.size() == 1) {
|
public boolean apply(Set<Annotation> input) {
|
||||||
Entry<Integer, Set<Annotation>> entry = indexToEntityAnnotation.entrySet()
|
return input.size() >= 1;
|
||||||
.iterator().next();
|
}
|
||||||
EntityParam entityAnnotation = (EntityParam) entry.getValue().iterator().next();
|
}).entrySet()) {
|
||||||
|
DecoratorParam entityAnnotation = (DecoratorParam) entry.getValue().iterator().next();
|
||||||
EntityBinder binder = injector.getInstance(entityAnnotation.value());
|
RequestDecorator binder = injector.getInstance(entityAnnotation.value());
|
||||||
Object entity = args[entry.getKey()];
|
Object input = args[entry.getKey()];
|
||||||
if (entity.getClass().isArray()) {
|
if (input.getClass().isArray()) {
|
||||||
Object[] entityArray = (Object[]) entity;
|
Object[] entityArray = (Object[]) input;
|
||||||
entity = entityArray.length > 0 ? entityArray[0] : null;
|
input = entityArray.length > 0 ? entityArray[0] : null;
|
||||||
}
|
|
||||||
if (entity != null)
|
|
||||||
binder.addEntityToRequest(entity, request);
|
|
||||||
} else if (indexToEntityAnnotation.size() > 1) {
|
|
||||||
throw new IllegalStateException("cannot have multiple @Entity annotations on "
|
|
||||||
+ method);
|
|
||||||
} else {
|
|
||||||
request.getHeaders().replaceValues(HttpHeaders.CONTENT_LENGTH,
|
|
||||||
Lists.newArrayList("0"));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Object oldEntity = request.getEntity();
|
||||||
|
request = binder.decorateRequest(request, input);
|
||||||
|
if (oldEntity != null && !oldEntity.equals(request.getEntity())) {
|
||||||
|
throw new IllegalStateException(String.format(
|
||||||
|
"binder %s replaced the previous entity on request: %s", binder, request));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (request.getMethod().equals("PUT") && request.getEntity() == null) {
|
||||||
|
request.getHeaders().replaceValues(HttpHeaders.CONTENT_LENGTH,
|
||||||
|
Collections.singletonList(0 + ""));
|
||||||
}
|
}
|
||||||
return request;
|
return request;
|
||||||
}
|
}
|
||||||
|
@ -619,46 +678,85 @@ public class JaxrsAnnotationProcessor<T> {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Multimap<String, String> buildHeaders(Method method, final Object[] args) {
|
public Multimap<String, String> buildHeaders(Method method, final Object[] args,
|
||||||
|
Collection<Entry<String, String>> tokenValues) {
|
||||||
Multimap<String, String> headers = HashMultimap.create();
|
Multimap<String, String> headers = HashMultimap.create();
|
||||||
|
addHeaderIfAnnotationPresentOnMethod(headers, method, tokenValues);
|
||||||
Map<Integer, Set<Annotation>> indexToHeaderParam = methodToIndexOfParamToHeaderParamAnnotations
|
Map<Integer, Set<Annotation>> indexToHeaderParam = methodToIndexOfParamToHeaderParamAnnotations
|
||||||
.get(method);
|
.get(method);
|
||||||
for (Entry<Integer, Set<Annotation>> entry : indexToHeaderParam.entrySet()) {
|
for (Entry<Integer, Set<Annotation>> entry : indexToHeaderParam.entrySet()) {
|
||||||
for (Annotation key : entry.getValue()) {
|
for (Annotation key : entry.getValue()) {
|
||||||
headers.put(((HeaderParam) key).value(), args[entry.getKey()].toString());
|
String value = args[entry.getKey()].toString();
|
||||||
|
value = replaceTokens(value, tokenValues);
|
||||||
|
headers.put(((HeaderParam) key).value(), value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
addProducesIfPresentOnTypeOrMethod(headers, method);
|
||||||
|
addConsumesIfPresentOnTypeOrMethod(headers, method);
|
||||||
return headers;
|
return headers;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addHeaderIfAnnotationPresentOnMethod(Multimap<String, String> headers,
|
void addConsumesIfPresentOnTypeOrMethod(Multimap<String, String> headers, Method method) {
|
||||||
Method method, Object[] args, char... skipEncode) throws UnsupportedEncodingException {
|
if (declaring.isAnnotationPresent(Consumes.class)) {
|
||||||
if (declaring.isAnnotationPresent(Headers.class)) {
|
Consumes header = declaring.getAnnotation(Consumes.class);
|
||||||
Headers header = declaring.getAnnotation(Headers.class);
|
headers.replaceValues(HttpHeaders.ACCEPT, Arrays.asList(header.value()));
|
||||||
addHeader(headers, method, args, header);
|
|
||||||
}
|
}
|
||||||
if (method.isAnnotationPresent(Headers.class)) {
|
if (method.isAnnotationPresent(Consumes.class)) {
|
||||||
Headers header = method.getAnnotation(Headers.class);
|
Consumes header = method.getAnnotation(Consumes.class);
|
||||||
addHeader(headers, method, args, header);
|
headers.replaceValues(HttpHeaders.ACCEPT, Arrays.asList(header.value()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addHeader(Multimap<String, String> headers, Method method, Object[] args,
|
void addProducesIfPresentOnTypeOrMethod(Multimap<String, String> headers, Method method) {
|
||||||
Headers header) throws UnsupportedEncodingException {
|
if (declaring.isAnnotationPresent(Produces.class)) {
|
||||||
|
Produces header = declaring.getAnnotation(Produces.class);
|
||||||
|
headers.replaceValues(HttpHeaders.CONTENT_TYPE, Arrays.asList(header.value()));
|
||||||
|
}
|
||||||
|
if (method.isAnnotationPresent(Produces.class)) {
|
||||||
|
Produces header = method.getAnnotation(Produces.class);
|
||||||
|
headers.replaceValues(HttpHeaders.CONTENT_TYPE, Arrays.asList(header.value()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addHeaderIfAnnotationPresentOnMethod(Multimap<String, String> headers,
|
||||||
|
Method method, Collection<Entry<String, String>> tokenValues) {
|
||||||
|
if (declaring.isAnnotationPresent(Headers.class)) {
|
||||||
|
Headers header = declaring.getAnnotation(Headers.class);
|
||||||
|
addHeader(headers, header, tokenValues);
|
||||||
|
}
|
||||||
|
if (method.isAnnotationPresent(Headers.class)) {
|
||||||
|
Headers header = method.getAnnotation(Headers.class);
|
||||||
|
addHeader(headers, header, tokenValues);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addHeader(Multimap<String, String> headers, Headers header,
|
||||||
|
Collection<Entry<String, String>> tokenValues) {
|
||||||
for (int i = 0; i < header.keys().length; i++) {
|
for (int i = 0; i < header.keys().length; i++) {
|
||||||
String value = header.values()[i];
|
String value = header.values()[i];
|
||||||
for (Entry<String, String> tokenValue : getEncodedPathParamKeyValues(method, args)
|
value = replaceTokens(value, tokenValues);
|
||||||
.entrySet()) {
|
|
||||||
value = value.replaceAll("\\{" + tokenValue.getKey() + "\\}", tokenValue.getValue());
|
|
||||||
}
|
|
||||||
headers.put(header.keys()[i], value);
|
headers.put(header.keys()[i], value);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Map<String, String> getEncodedPathParamKeyValues(Method method, Object[] args,
|
private String replaceTokens(String value, Collection<Entry<String, String>> tokenValues) {
|
||||||
final char... skipEncode) throws UnsupportedEncodingException {
|
for (Entry<String, String> tokenValue : tokenValues) {
|
||||||
Map<String, String> pathParamValues = Maps.newHashMap();
|
value = value.replaceAll("\\{" + tokenValue.getKey() + "\\}", tokenValue.getValue());
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<String, String> convertUnsafe(Multimap<String, String> in) {
|
||||||
|
Map<String, String> out = Maps.newHashMap();
|
||||||
|
for (Entry<String, String> entry : in.entries()) {
|
||||||
|
out.put(entry.getKey(), entry.getValue());
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Multimap<String, String> getPathParamKeyValues(Method method, Object[] args) {
|
||||||
|
Multimap<String, String> pathParamValues = HashMultimap.create();
|
||||||
pathParamValues.putAll(constants);
|
pathParamValues.putAll(constants);
|
||||||
Map<Integer, Set<Annotation>> indexToPathParam = methodToindexOfParamToPathParamAnnotations
|
Map<Integer, Set<Annotation>> indexToPathParam = methodToindexOfParamToPathParamAnnotations
|
||||||
.get(method);
|
.get(method);
|
||||||
|
@ -686,30 +784,50 @@ public class JaxrsAnnotationProcessor<T> {
|
||||||
String paramValue = injector.getInstance(method.getAnnotation(ParamParser.class).value())
|
String paramValue = injector.getInstance(method.getAnnotation(ParamParser.class).value())
|
||||||
.apply(args);
|
.apply(args);
|
||||||
pathParamValues.put(paramKey, paramValue);
|
pathParamValues.put(paramKey, paramValue);
|
||||||
}
|
|
||||||
|
|
||||||
return Maps.transformValues(pathParamValues, new Function<String, String>() {
|
}
|
||||||
public String apply(String paramValue) {
|
return pathParamValues;
|
||||||
try {
|
|
||||||
paramValue = URLEncoder.encode(paramValue, "UTF-8");
|
|
||||||
// Web browsers do not always handle '+' characters well, use the well-supported
|
|
||||||
// '%20' instead.
|
|
||||||
paramValue = paramValue.replaceAll("\\+", "%20");
|
|
||||||
for (char c : skipEncode) {
|
|
||||||
String value = Character.toString(c);
|
|
||||||
String encoded = URLEncoder.encode(value, "UTF-8");
|
|
||||||
paramValue = paramValue.replaceAll(encoded, value);
|
|
||||||
}
|
|
||||||
} catch (UnsupportedEncodingException e) {
|
|
||||||
throw new RuntimeException("jclouds only supports UTF-8", e);
|
|
||||||
}
|
|
||||||
return paramValue;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Map<String, String> getQueryParamKeyValues(Method method, Object[] args) {
|
private Multimap<String, String> encodeValues(Multimap<String, String> unencoded,
|
||||||
Map<String, String> queryParamValues = Maps.newHashMap();
|
final char... skipEncode) {
|
||||||
|
Multimap<String, String> encoded = HashMultimap.create();
|
||||||
|
for (Entry<String, String> entry : unencoded.entries()) {
|
||||||
|
try {
|
||||||
|
String value = URLEncoder.encode(entry.getValue(), "UTF-8");
|
||||||
|
// Web browsers do not always handle '+' characters well, use the well-supported
|
||||||
|
// '%20' instead.
|
||||||
|
value = value.replaceAll("\\+", "%20");
|
||||||
|
for (char c : skipEncode) {
|
||||||
|
String toSkip = Character.toString(c);
|
||||||
|
String encodedValueToSkip = URLEncoder.encode(toSkip, "UTF-8");
|
||||||
|
value = value.replaceAll(encodedValueToSkip, toSkip);
|
||||||
|
}
|
||||||
|
encoded.put(entry.getKey(), value);
|
||||||
|
} catch (UnsupportedEncodingException e) {
|
||||||
|
throw new RuntimeException("jclouds only supports UTF-8", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return encoded;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Multimap<String, String> getMatrixParamKeyValues(Method method, Object[] args) {
|
||||||
|
Multimap<String, String> queryParamValues = HashMultimap.create();
|
||||||
|
queryParamValues.putAll(constants);
|
||||||
|
Map<Integer, Set<Annotation>> indexToMatrixParam = methodToindexOfParamToMatrixParamAnnotations
|
||||||
|
.get(method);
|
||||||
|
for (Entry<Integer, Set<Annotation>> entry : indexToMatrixParam.entrySet()) {
|
||||||
|
for (Annotation key : entry.getValue()) {
|
||||||
|
String paramKey = ((MatrixParam) key).value();
|
||||||
|
String paramValue = args[entry.getKey()].toString();
|
||||||
|
queryParamValues.put(paramKey, paramValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return queryParamValues;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Multimap<String, String> getQueryParamKeyValues(Method method, Object[] args) {
|
||||||
|
Multimap<String, String> queryParamValues = HashMultimap.create();
|
||||||
queryParamValues.putAll(constants);
|
queryParamValues.putAll(constants);
|
||||||
Map<Integer, Set<Annotation>> indexToQueryParam = methodToindexOfParamToQueryParamAnnotations
|
Map<Integer, Set<Annotation>> indexToQueryParam = methodToindexOfParamToQueryParamAnnotations
|
||||||
.get(method);
|
.get(method);
|
15
core/src/main/java/org/jclouds/rest/RestClientProxy.java → core/src/main/java/org/jclouds/rest/internal/RestClientProxy.java
Normal file → Executable file
15
core/src/main/java/org/jclouds/rest/RestClientProxy.java → core/src/main/java/org/jclouds/rest/internal/RestClientProxy.java
Normal file → Executable file
|
@ -21,7 +21,7 @@
|
||||||
* under the License.
|
* under the License.
|
||||||
* ====================================================================
|
* ====================================================================
|
||||||
*/
|
*/
|
||||||
package org.jclouds.rest;
|
package org.jclouds.rest.internal;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates RESTful clients from appropriately annotated interfaces.
|
* Generates RESTful clients from appropriately annotated interfaces.
|
||||||
|
@ -46,13 +46,14 @@ import org.jclouds.http.HttpRequest;
|
||||||
import org.jclouds.http.HttpResponse;
|
import org.jclouds.http.HttpResponse;
|
||||||
import org.jclouds.http.TransformingHttpCommand;
|
import org.jclouds.http.TransformingHttpCommand;
|
||||||
import org.jclouds.logging.Logger;
|
import org.jclouds.logging.Logger;
|
||||||
|
import org.jclouds.rest.InvocationContext;
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
import com.google.inject.TypeLiteral;
|
import com.google.inject.TypeLiteral;
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
public class RestClientProxy<T> implements InvocationHandler {
|
public class RestClientProxy<T> implements InvocationHandler {
|
||||||
private final JaxrsAnnotationProcessor<T> util;
|
private final RestAnnotationProcessor<T> util;
|
||||||
private final Class<T> declaring;
|
private final Class<T> declaring;
|
||||||
private final TransformingHttpCommand.Factory commandFactory;
|
private final TransformingHttpCommand.Factory commandFactory;
|
||||||
|
|
||||||
|
@ -69,7 +70,7 @@ public class RestClientProxy<T> implements InvocationHandler {
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@Inject
|
@Inject
|
||||||
public RestClientProxy(TransformingHttpCommand.Factory factory,
|
public RestClientProxy(TransformingHttpCommand.Factory factory,
|
||||||
JaxrsAnnotationProcessor<T> util, TypeLiteral<T> typeLiteral) {
|
RestAnnotationProcessor<T> util, TypeLiteral<T> typeLiteral) {
|
||||||
this.util = util;
|
this.util = util;
|
||||||
this.declaring = (Class<T>) typeLiteral.getRawType();
|
this.declaring = (Class<T>) typeLiteral.getRawType();
|
||||||
this.commandFactory = factory;
|
this.commandFactory = factory;
|
||||||
|
@ -87,14 +88,14 @@ public class RestClientProxy<T> implements InvocationHandler {
|
||||||
Function<Exception, ?> exceptionParser = util
|
Function<Exception, ?> exceptionParser = util
|
||||||
.createExceptionParserOrNullIfNotFound(method);
|
.createExceptionParserOrNullIfNotFound(method);
|
||||||
// in case there is an exception creating the request, we should at least pass in args
|
// in case there is an exception creating the request, we should at least pass in args
|
||||||
if (exceptionParser instanceof RestContext) {
|
if (exceptionParser instanceof InvocationContext) {
|
||||||
((RestContext) exceptionParser).setContext(null, args);
|
((InvocationContext) exceptionParser).setContext(null, args);
|
||||||
}
|
}
|
||||||
HttpRequest request;
|
HttpRequest request;
|
||||||
try {
|
try {
|
||||||
request = util.createRequest(method, args);
|
request = util.createRequest(method, args);
|
||||||
if (exceptionParser instanceof RestContext) {
|
if (exceptionParser instanceof InvocationContext) {
|
||||||
((RestContext) exceptionParser).setContext(request, args);
|
((InvocationContext) exceptionParser).setContext(request, args);
|
||||||
}
|
}
|
||||||
} catch (RuntimeException e) {
|
} catch (RuntimeException e) {
|
||||||
if (exceptionParser != null) {
|
if (exceptionParser != null) {
|
|
@ -21,7 +21,7 @@
|
||||||
* under the License.
|
* under the License.
|
||||||
* ====================================================================
|
* ====================================================================
|
||||||
*/
|
*/
|
||||||
package org.jclouds.rest;
|
package org.jclouds.rest.internal;
|
||||||
|
|
||||||
import javax.ws.rs.core.Application;
|
import javax.ws.rs.core.Application;
|
||||||
import javax.ws.rs.core.UriBuilder;
|
import javax.ws.rs.core.UriBuilder;
|
|
@ -41,7 +41,7 @@ import org.jclouds.cloud.ConfiguresCloudConnection;
|
||||||
import org.jclouds.cloud.internal.CloudContextImpl;
|
import org.jclouds.cloud.internal.CloudContextImpl;
|
||||||
import org.jclouds.lifecycle.Closer;
|
import org.jclouds.lifecycle.Closer;
|
||||||
import org.jclouds.rest.RestClientFactory;
|
import org.jclouds.rest.RestClientFactory;
|
||||||
import org.jclouds.rest.JaxrsAnnotationProcessorTest.Localhost;
|
import org.jclouds.rest.RestAnnotationProcessorTest.Localhost;
|
||||||
import org.jclouds.util.Jsr330;
|
import org.jclouds.util.Jsr330;
|
||||||
import org.jclouds.util.Utils;
|
import org.jclouds.util.Utils;
|
||||||
import org.mortbay.jetty.Handler;
|
import org.mortbay.jetty.Handler;
|
||||||
|
|
|
@ -33,17 +33,18 @@ import javax.ws.rs.PUT;
|
||||||
import javax.ws.rs.Path;
|
import javax.ws.rs.Path;
|
||||||
import javax.ws.rs.PathParam;
|
import javax.ws.rs.PathParam;
|
||||||
|
|
||||||
import org.jclouds.rest.binders.JsonBinder;
|
|
||||||
import org.jclouds.http.functions.ParseSax;
|
import org.jclouds.http.functions.ParseSax;
|
||||||
import org.jclouds.http.options.HttpRequestOptions;
|
import org.jclouds.http.options.HttpRequestOptions;
|
||||||
import org.jclouds.rest.Endpoint;
|
import org.jclouds.rest.RestAnnotationProcessorTest.Localhost;
|
||||||
import org.jclouds.rest.EntityParam;
|
import org.jclouds.rest.annotations.DecoratorParam;
|
||||||
import org.jclouds.rest.ExceptionParser;
|
import org.jclouds.rest.annotations.Endpoint;
|
||||||
import org.jclouds.rest.MapBinder;
|
import org.jclouds.rest.annotations.ExceptionParser;
|
||||||
import org.jclouds.rest.MapEntityParam;
|
import org.jclouds.rest.annotations.MapBinder;
|
||||||
import org.jclouds.rest.RequestFilters;
|
import org.jclouds.rest.annotations.MapEntityParam;
|
||||||
import org.jclouds.rest.XMLResponseParser;
|
import org.jclouds.rest.annotations.RequestFilters;
|
||||||
import org.jclouds.rest.JaxrsAnnotationProcessorTest.Localhost;
|
import org.jclouds.rest.annotations.XMLResponseParser;
|
||||||
|
import org.jclouds.rest.decorators.AddAsJsonEntity;
|
||||||
|
import org.jclouds.rest.decorators.AddAsStringEntity;
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
|
|
||||||
|
@ -87,15 +88,15 @@ public interface IntegrationTestClient {
|
||||||
|
|
||||||
@PUT
|
@PUT
|
||||||
@Path("objects/{id}")
|
@Path("objects/{id}")
|
||||||
Future<String> upload(@PathParam("id") String id, @EntityParam String toPut);
|
Future<String> upload(@PathParam("id") String id, @DecoratorParam(AddAsStringEntity.class) String toPut);
|
||||||
|
|
||||||
@POST
|
@POST
|
||||||
@Path("objects/{id}")
|
@Path("objects/{id}")
|
||||||
Future<String> post(@PathParam("id") String id, @EntityParam String toPut);
|
Future<String> post(@PathParam("id") String id, @DecoratorParam(AddAsStringEntity.class) String toPut);
|
||||||
|
|
||||||
@POST
|
@POST
|
||||||
@Path("objects/{id}")
|
@Path("objects/{id}")
|
||||||
@MapBinder(JsonBinder.class)
|
@MapBinder(AddAsJsonEntity.class)
|
||||||
Future<String> postJson(@PathParam("id") String id, @MapEntityParam("key") String toPut);
|
Future<String> postJson(@PathParam("id") String id, @MapEntityParam("key") String toPut);
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
|
|
|
@ -43,6 +43,7 @@ import java.util.concurrent.Future;
|
||||||
|
|
||||||
import javax.inject.Named;
|
import javax.inject.Named;
|
||||||
import javax.inject.Qualifier;
|
import javax.inject.Qualifier;
|
||||||
|
import javax.ws.rs.Consumes;
|
||||||
import javax.ws.rs.GET;
|
import javax.ws.rs.GET;
|
||||||
import javax.ws.rs.HeaderParam;
|
import javax.ws.rs.HeaderParam;
|
||||||
import javax.ws.rs.HttpMethod;
|
import javax.ws.rs.HttpMethod;
|
||||||
|
@ -50,7 +51,9 @@ import javax.ws.rs.POST;
|
||||||
import javax.ws.rs.PUT;
|
import javax.ws.rs.PUT;
|
||||||
import javax.ws.rs.Path;
|
import javax.ws.rs.Path;
|
||||||
import javax.ws.rs.PathParam;
|
import javax.ws.rs.PathParam;
|
||||||
|
import javax.ws.rs.Produces;
|
||||||
import javax.ws.rs.QueryParam;
|
import javax.ws.rs.QueryParam;
|
||||||
|
import javax.ws.rs.core.MediaType;
|
||||||
|
|
||||||
import org.jclouds.concurrent.WithinThreadExecutorService;
|
import org.jclouds.concurrent.WithinThreadExecutorService;
|
||||||
import org.jclouds.concurrent.config.ExecutorServiceModule;
|
import org.jclouds.concurrent.config.ExecutorServiceModule;
|
||||||
|
@ -67,10 +70,25 @@ import org.jclouds.http.functions.ReturnVoidIf2xx;
|
||||||
import org.jclouds.http.options.BaseHttpRequestOptions;
|
import org.jclouds.http.options.BaseHttpRequestOptions;
|
||||||
import org.jclouds.http.options.GetOptions;
|
import org.jclouds.http.options.GetOptions;
|
||||||
import org.jclouds.http.options.HttpRequestOptions;
|
import org.jclouds.http.options.HttpRequestOptions;
|
||||||
import org.jclouds.rest.binders.HttpRequestOptionsBinder;
|
import org.jclouds.rest.InvocationContext;
|
||||||
import org.jclouds.rest.binders.JsonBinder;
|
import org.jclouds.rest.annotations.DecoratorParam;
|
||||||
import org.jclouds.rest.binders.MapEntityBinder;
|
import org.jclouds.rest.annotations.Endpoint;
|
||||||
import org.jclouds.rest.config.JaxrsModule;
|
import org.jclouds.rest.annotations.Headers;
|
||||||
|
import org.jclouds.rest.annotations.HostPrefixParam;
|
||||||
|
import org.jclouds.rest.annotations.MapBinder;
|
||||||
|
import org.jclouds.rest.annotations.MapEntityParam;
|
||||||
|
import org.jclouds.rest.annotations.MatrixParams;
|
||||||
|
import org.jclouds.rest.annotations.ParamParser;
|
||||||
|
import org.jclouds.rest.annotations.QueryParams;
|
||||||
|
import org.jclouds.rest.annotations.RequestFilters;
|
||||||
|
import org.jclouds.rest.annotations.ResponseParser;
|
||||||
|
import org.jclouds.rest.annotations.SkipEncoding;
|
||||||
|
import org.jclouds.rest.annotations.VirtualHost;
|
||||||
|
import org.jclouds.rest.config.RestModule;
|
||||||
|
import org.jclouds.rest.decorators.AddAsJsonEntity;
|
||||||
|
import org.jclouds.rest.decorators.AddAsStringEntity;
|
||||||
|
import org.jclouds.rest.decorators.MapRequestDecorator;
|
||||||
|
import org.jclouds.rest.internal.RestAnnotationProcessor;
|
||||||
import org.jclouds.util.DateService;
|
import org.jclouds.util.DateService;
|
||||||
import org.jclouds.util.Jsr330;
|
import org.jclouds.util.Jsr330;
|
||||||
import org.joda.time.DateTime;
|
import org.joda.time.DateTime;
|
||||||
|
@ -81,6 +99,7 @@ import org.testng.annotations.Test;
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
import com.google.common.collect.HashMultimap;
|
import com.google.common.collect.HashMultimap;
|
||||||
|
import com.google.common.collect.ImmutableMultimap;
|
||||||
import com.google.common.collect.Multimap;
|
import com.google.common.collect.Multimap;
|
||||||
import com.google.inject.AbstractModule;
|
import com.google.inject.AbstractModule;
|
||||||
import com.google.inject.Guice;
|
import com.google.inject.Guice;
|
||||||
|
@ -95,7 +114,7 @@ import com.google.inject.util.Types;
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
@Test(groups = "unit", testName = "jaxrs.JaxrsUtilTest")
|
@Test(groups = "unit", testName = "jaxrs.JaxrsUtilTest")
|
||||||
public class JaxrsAnnotationProcessorTest {
|
public class RestAnnotationProcessorTest {
|
||||||
@Target( { ElementType.METHOD })
|
@Target( { ElementType.METHOD })
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
@javax.ws.rs.HttpMethod("FOO")
|
@javax.ws.rs.HttpMethod("FOO")
|
||||||
|
@ -166,12 +185,11 @@ public class JaxrsAnnotationProcessorTest {
|
||||||
@Endpoint(Localhost.class)
|
@Endpoint(Localhost.class)
|
||||||
public class TestEntityParamVarargs {
|
public class TestEntityParamVarargs {
|
||||||
@POST
|
@POST
|
||||||
public void varargs(
|
public void varargs(HttpRequestOptions... options) {
|
||||||
@EntityParam(HttpRequestOptionsBinder.class) HttpRequestOptions... options) {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@POST
|
@POST
|
||||||
public void post(@EntityParam(HttpRequestOptionsBinder.class) HttpRequestOptions options) {
|
public void post(HttpRequestOptions options) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -293,22 +311,22 @@ public class JaxrsAnnotationProcessorTest {
|
||||||
@Endpoint(Localhost.class)
|
@Endpoint(Localhost.class)
|
||||||
public class TestPost {
|
public class TestPost {
|
||||||
@POST
|
@POST
|
||||||
public void post(@EntityParam String content) {
|
public void post(@DecoratorParam(AddAsStringEntity.class) String content) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@POST
|
@POST
|
||||||
public void postAsJson(@EntityParam(JsonBinder.class) String content) {
|
public void postAsJson(@DecoratorParam(AddAsJsonEntity.class) String content) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@POST
|
@POST
|
||||||
@Path("{foo}")
|
@Path("{foo}")
|
||||||
public void postWithPath(@PathParam("foo") @MapEntityParam("fooble") String path,
|
public void postWithPath(@PathParam("foo") @MapEntityParam("fooble") String path,
|
||||||
MapEntityBinder content) {
|
MapRequestDecorator content) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@POST
|
@POST
|
||||||
@Path("{foo}")
|
@Path("{foo}")
|
||||||
@MapBinder(JsonBinder.class)
|
@MapBinder(AddAsJsonEntity.class)
|
||||||
public void postWithMethodBinder(@PathParam("foo") @MapEntityParam("fooble") String path) {
|
public void postWithMethodBinder(@PathParam("foo") @MapEntityParam("fooble") String path) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -344,14 +362,17 @@ public class JaxrsAnnotationProcessorTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testCreatePostWithPathRequest() throws SecurityException, NoSuchMethodException {
|
public void testCreatePostWithPathRequest() throws SecurityException, NoSuchMethodException {
|
||||||
Method method = TestPost.class.getMethod("postWithPath", String.class, MapEntityBinder.class);
|
Method method = TestPost.class.getMethod("postWithPath", String.class,
|
||||||
|
MapRequestDecorator.class);
|
||||||
HttpRequest httpMethod = factory(TestPost.class).createRequest(method,
|
HttpRequest httpMethod = factory(TestPost.class).createRequest(method,
|
||||||
new Object[] { "data", new MapEntityBinder() {
|
new Object[] { "data", new MapRequestDecorator() {
|
||||||
public void addEntityToRequest(Map<String, String> postParams, HttpRequest request) {
|
public HttpRequest decorateRequest(HttpRequest request,
|
||||||
|
Map<String, String> postParams) {
|
||||||
request.setEntity(postParams.get("fooble"));
|
request.setEntity(postParams.get("fooble"));
|
||||||
|
return request;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addEntityToRequest(Object toBind, HttpRequest request) {
|
public HttpRequest decorateRequest(HttpRequest request, Object toBind) {
|
||||||
throw new RuntimeException("this shouldn't be used in POST");
|
throw new RuntimeException("this shouldn't be used in POST");
|
||||||
}
|
}
|
||||||
} });
|
} });
|
||||||
|
@ -382,9 +403,24 @@ public class JaxrsAnnotationProcessorTest {
|
||||||
public class TestPut {
|
public class TestPut {
|
||||||
@PUT
|
@PUT
|
||||||
@Path("{foo}")
|
@Path("{foo}")
|
||||||
@MapBinder(JsonBinder.class)
|
@MapBinder(AddAsJsonEntity.class)
|
||||||
public void putWithMethodBinder(@PathParam("foo") @MapEntityParam("fooble") String path) {
|
public void putWithMethodBinder(@PathParam("foo") @MapEntityParam("fooble") String path) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PUT
|
||||||
|
@Path("{foo}")
|
||||||
|
@Produces(MediaType.TEXT_PLAIN)
|
||||||
|
public void putWithMethodBinderProduces(
|
||||||
|
@PathParam("foo") @DecoratorParam(AddAsStringEntity.class) String path) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@PUT
|
||||||
|
@Path("{foo}")
|
||||||
|
@MapBinder(AddAsJsonEntity.class)
|
||||||
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
|
public void putWithMethodBinderConsumes(
|
||||||
|
@PathParam("foo") @MapEntityParam("fooble") String path) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testCreatePutWithMethodBinder() throws SecurityException, NoSuchMethodException {
|
public void testCreatePutWithMethodBinder() throws SecurityException, NoSuchMethodException {
|
||||||
|
@ -402,6 +438,40 @@ public class JaxrsAnnotationProcessorTest {
|
||||||
.singletonList(expected.getBytes().length + ""));
|
.singletonList(expected.getBytes().length + ""));
|
||||||
assertEquals(httpMethod.getEntity(), expected);
|
assertEquals(httpMethod.getEntity(), expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testCreatePutWithMethodProduces() throws SecurityException, NoSuchMethodException {
|
||||||
|
Method method = TestPut.class.getMethod("putWithMethodBinderProduces", String.class);
|
||||||
|
HttpRequest httpMethod = factory(TestPut.class).createRequest(method,
|
||||||
|
new Object[] { "data", });
|
||||||
|
assertEquals(httpMethod.getEndpoint().getHost(), "localhost");
|
||||||
|
assertEquals(httpMethod.getEndpoint().getPath(), "/data");
|
||||||
|
assertEquals(httpMethod.getMethod(), HttpMethod.PUT);
|
||||||
|
assertEquals(httpMethod.getHeaders().size(), 2);
|
||||||
|
assertEquals(httpMethod.getHeaders().get(HttpHeaders.CONTENT_TYPE), Collections
|
||||||
|
.singletonList("text/plain"));
|
||||||
|
assertEquals(httpMethod.getHeaders().get(HttpHeaders.CONTENT_LENGTH), Collections
|
||||||
|
.singletonList("data".getBytes().length + ""));
|
||||||
|
assertEquals(httpMethod.getEntity(), "data");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testCreatePutWithMethodConsumes() throws SecurityException, NoSuchMethodException {
|
||||||
|
Method method = TestPut.class.getMethod("putWithMethodBinderConsumes", String.class);
|
||||||
|
HttpRequest httpMethod = factory(TestPut.class).createRequest(method,
|
||||||
|
new Object[] { "data", });
|
||||||
|
assertEquals(httpMethod.getEndpoint().getHost(), "localhost");
|
||||||
|
assertEquals(httpMethod.getEndpoint().getPath(), "/data");
|
||||||
|
assertEquals(httpMethod.getMethod(), HttpMethod.PUT);
|
||||||
|
assertEquals(httpMethod.getHeaders().size(), 3);
|
||||||
|
assertEquals(httpMethod.getHeaders().get(HttpHeaders.CONTENT_TYPE), Collections
|
||||||
|
.singletonList("application/json"));
|
||||||
|
assertEquals(httpMethod.getHeaders().get(HttpHeaders.ACCEPT), Collections
|
||||||
|
.singletonList("application/json"));
|
||||||
|
String expected = "{\"fooble\":\"data\"}";
|
||||||
|
assertEquals(httpMethod.getHeaders().get(HttpHeaders.CONTENT_LENGTH), Collections
|
||||||
|
.singletonList(expected.getBytes().length + ""));
|
||||||
|
assertEquals(httpMethod.getEntity(), expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static class TestRequestFilter1 implements HttpRequestFilter {
|
static class TestRequestFilter1 implements HttpRequestFilter {
|
||||||
public HttpRequest filter(HttpRequest request) throws HttpException {
|
public HttpRequest filter(HttpRequest request) throws HttpException {
|
||||||
|
@ -578,9 +648,8 @@ public class JaxrsAnnotationProcessorTest {
|
||||||
public void testBuildTwoHeader() throws SecurityException, NoSuchMethodException,
|
public void testBuildTwoHeader() throws SecurityException, NoSuchMethodException,
|
||||||
UnsupportedEncodingException {
|
UnsupportedEncodingException {
|
||||||
Method oneHeader = TestHeader.class.getMethod("twoHeader", String.class);
|
Method oneHeader = TestHeader.class.getMethod("twoHeader", String.class);
|
||||||
Multimap<String, String> headers = HashMultimap.create();
|
Multimap<String, String> headers = factory(TestHeader.class).createRequest(oneHeader,
|
||||||
factory(TestHeader.class).addHeaderIfAnnotationPresentOnMethod(headers, oneHeader,
|
new Object[] { "robot" }).getHeaders();
|
||||||
new Object[] { "robot" });
|
|
||||||
assertEquals(headers.size(), 2);
|
assertEquals(headers.size(), 2);
|
||||||
assertEquals(headers.get("slash"), Collections.singletonList("/robot"));
|
assertEquals(headers.get("slash"), Collections.singletonList("/robot"));
|
||||||
assertEquals(headers.get("hyphen"), Collections.singletonList("-robot"));
|
assertEquals(headers.get("hyphen"), Collections.singletonList("-robot"));
|
||||||
|
@ -598,9 +667,8 @@ public class JaxrsAnnotationProcessorTest {
|
||||||
public void testBuildOneClassHeader() throws SecurityException, NoSuchMethodException,
|
public void testBuildOneClassHeader() throws SecurityException, NoSuchMethodException,
|
||||||
UnsupportedEncodingException {
|
UnsupportedEncodingException {
|
||||||
Method oneHeader = TestClassHeader.class.getMethod("oneHeader", String.class);
|
Method oneHeader = TestClassHeader.class.getMethod("oneHeader", String.class);
|
||||||
Multimap<String, String> headers = HashMultimap.create();
|
Multimap<String, String> headers = factory(TestClassHeader.class).createRequest(oneHeader,
|
||||||
factory(TestClassHeader.class).addHeaderIfAnnotationPresentOnMethod(headers, oneHeader,
|
new Object[] { "robot" }).getHeaders();
|
||||||
new Object[] { "robot" });
|
|
||||||
assertEquals(headers.size(), 1);
|
assertEquals(headers.size(), 1);
|
||||||
assertEquals(headers.get("x-amz-copy-source"), Collections.singletonList("/robot"));
|
assertEquals(headers.get("x-amz-copy-source"), Collections.singletonList("/robot"));
|
||||||
}
|
}
|
||||||
|
@ -609,9 +677,8 @@ public class JaxrsAnnotationProcessorTest {
|
||||||
public void testBuildOneHeader() throws SecurityException, NoSuchMethodException,
|
public void testBuildOneHeader() throws SecurityException, NoSuchMethodException,
|
||||||
UnsupportedEncodingException {
|
UnsupportedEncodingException {
|
||||||
Method oneHeader = TestHeader.class.getMethod("oneHeader", String.class);
|
Method oneHeader = TestHeader.class.getMethod("oneHeader", String.class);
|
||||||
Multimap<String, String> headers = HashMultimap.create();
|
Multimap<String, String> headers = factory(TestHeader.class).createRequest(oneHeader,
|
||||||
factory(TestHeader.class).addHeaderIfAnnotationPresentOnMethod(headers, oneHeader,
|
new Object[] { "robot" }).getHeaders();
|
||||||
new Object[] { "robot" });
|
|
||||||
assertEquals(headers.size(), 1);
|
assertEquals(headers.size(), 1);
|
||||||
assertEquals(headers.get("x-amz-copy-source"), Collections.singletonList("/robot"));
|
assertEquals(headers.get("x-amz-copy-source"), Collections.singletonList("/robot"));
|
||||||
}
|
}
|
||||||
|
@ -620,9 +687,8 @@ public class JaxrsAnnotationProcessorTest {
|
||||||
public void testBuildTwoHeaders() throws SecurityException, NoSuchMethodException,
|
public void testBuildTwoHeaders() throws SecurityException, NoSuchMethodException,
|
||||||
UnsupportedEncodingException {
|
UnsupportedEncodingException {
|
||||||
Method twoHeaders = TestHeader.class.getMethod("twoHeaders", String.class, String.class);
|
Method twoHeaders = TestHeader.class.getMethod("twoHeaders", String.class, String.class);
|
||||||
Multimap<String, String> headers = HashMultimap.create();
|
Multimap<String, String> headers = factory(TestHeader.class).createRequest(twoHeaders,
|
||||||
factory(TestHeader.class).addHeaderIfAnnotationPresentOnMethod(headers, twoHeaders,
|
new Object[] { "robot", "eggs" }).getHeaders();
|
||||||
new Object[] { "robot", "eggs" });
|
|
||||||
assertEquals(headers.size(), 1);
|
assertEquals(headers.size(), 1);
|
||||||
assertEquals(headers.get("x-amz-copy-source"), Collections.singletonList("/robot/eggs"));
|
assertEquals(headers.get("x-amz-copy-source"), Collections.singletonList("/robot/eggs"));
|
||||||
}
|
}
|
||||||
|
@ -632,13 +698,213 @@ public class JaxrsAnnotationProcessorTest {
|
||||||
UnsupportedEncodingException {
|
UnsupportedEncodingException {
|
||||||
Method twoHeadersOutOfOrder = TestHeader.class.getMethod("twoHeadersOutOfOrder",
|
Method twoHeadersOutOfOrder = TestHeader.class.getMethod("twoHeadersOutOfOrder",
|
||||||
String.class, String.class);
|
String.class, String.class);
|
||||||
Multimap<String, String> headers = HashMultimap.create();
|
Multimap<String, String> headers = factory(TestHeader.class).createRequest(
|
||||||
factory(TestHeader.class).addHeaderIfAnnotationPresentOnMethod(headers, twoHeadersOutOfOrder,
|
twoHeadersOutOfOrder, new Object[] { "robot", "eggs" }).getHeaders();
|
||||||
new Object[] { "robot", "eggs" });
|
|
||||||
assertEquals(headers.size(), 1);
|
assertEquals(headers.size(), 1);
|
||||||
assertEquals(headers.get("x-amz-copy-source"), Collections.singletonList("/eggs/robot"));
|
assertEquals(headers.get("x-amz-copy-source"), Collections.singletonList("/eggs/robot"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class TestReplaceQueryOptions extends BaseHttpRequestOptions {
|
||||||
|
public TestReplaceQueryOptions() {
|
||||||
|
this.queryParameters.put("x-amz-copy-source", "/{bucket}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testQueryInOptions() throws SecurityException, NoSuchMethodException,
|
||||||
|
UnsupportedEncodingException {
|
||||||
|
Method oneQuery = TestQueryReplace.class.getMethod("queryInOptions", String.class,
|
||||||
|
TestReplaceQueryOptions.class);
|
||||||
|
String query = factory(TestQueryReplace.class).createRequest(oneQuery,
|
||||||
|
new Object[] { "robot", new TestReplaceQueryOptions() }).getEndpoint().getQuery();
|
||||||
|
assertEquals(query, "x-amz-copy-source=/robot");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Endpoint(Localhost.class)
|
||||||
|
public class TestQueryReplace {
|
||||||
|
|
||||||
|
@GET
|
||||||
|
public void queryInOptions(@PathParam("bucket") String path, TestReplaceQueryOptions options) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@QueryParams(keys = "x-amz-copy-source", values = "/{bucket}")
|
||||||
|
public void oneQuery(@PathParam("bucket") String path) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@QueryParams(keys = { "slash", "hyphen" }, values = { "/{bucket}", "-{bucket}" })
|
||||||
|
public void twoQuery(@PathParam("bucket") String path) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@QueryParams(keys = "x-amz-copy-source", values = "/{bucket}/{key}")
|
||||||
|
public void twoQuerys(@PathParam("bucket") String path, @PathParam("key") String path2) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@QueryParams(keys = "x-amz-copy-source", values = "/{bucket}/{key}")
|
||||||
|
public void twoQuerysOutOfOrder(@PathParam("key") String path,
|
||||||
|
@PathParam("bucket") String path2) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testBuildTwoQuery() throws SecurityException, NoSuchMethodException,
|
||||||
|
UnsupportedEncodingException {
|
||||||
|
Method oneQuery = TestQueryReplace.class.getMethod("twoQuery", String.class);
|
||||||
|
String query = factory(TestQueryReplace.class).createRequest(oneQuery,
|
||||||
|
new Object[] { "robot" }).getEndpoint().getQuery();
|
||||||
|
assertEquals(query, "slash=/robot&hyphen=-robot");
|
||||||
|
}
|
||||||
|
|
||||||
|
@QueryParams(keys = "x-amz-copy-source", values = "/{bucket}")
|
||||||
|
@Endpoint(Localhost.class)
|
||||||
|
public class TestClassQuery {
|
||||||
|
@GET
|
||||||
|
public void oneQuery(@PathParam("bucket") String path) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testBuildOneClassQuery() throws SecurityException, NoSuchMethodException,
|
||||||
|
UnsupportedEncodingException {
|
||||||
|
Method oneQuery = TestClassQuery.class.getMethod("oneQuery", String.class);
|
||||||
|
String query = factory(TestClassQuery.class)
|
||||||
|
.createRequest(oneQuery, new Object[] { "robot" }).getEndpoint().getQuery();
|
||||||
|
assertEquals(query, "x-amz-copy-source=/robot");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testBuildOneQuery() throws SecurityException, NoSuchMethodException,
|
||||||
|
UnsupportedEncodingException {
|
||||||
|
Method oneQuery = TestQueryReplace.class.getMethod("oneQuery", String.class);
|
||||||
|
String query = factory(TestQueryReplace.class).createRequest(oneQuery,
|
||||||
|
new Object[] { "robot" }).getEndpoint().getQuery();
|
||||||
|
assertEquals(query, "x-amz-copy-source=/robot");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testBuildTwoQuerys() throws SecurityException, NoSuchMethodException,
|
||||||
|
UnsupportedEncodingException {
|
||||||
|
Method twoQuerys = TestQueryReplace.class.getMethod("twoQuerys", String.class, String.class);
|
||||||
|
String query = factory(TestQueryReplace.class).createRequest(twoQuerys,
|
||||||
|
new Object[] { "robot", "eggs" }).getEndpoint().getQuery();
|
||||||
|
assertEquals(query, "x-amz-copy-source=/robot/eggs");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testBuildTwoQuerysOutOfOrder() throws SecurityException, NoSuchMethodException,
|
||||||
|
UnsupportedEncodingException {
|
||||||
|
Method twoQuerysOutOfOrder = TestQueryReplace.class.getMethod("twoQuerysOutOfOrder",
|
||||||
|
String.class, String.class);
|
||||||
|
String query = factory(TestQueryReplace.class).createRequest(twoQuerysOutOfOrder,
|
||||||
|
new Object[] { "robot", "eggs" }).getEndpoint().getQuery();
|
||||||
|
assertEquals(query, "x-amz-copy-source=/eggs/robot");
|
||||||
|
}
|
||||||
|
|
||||||
|
public class TestReplaceMatrixOptions extends BaseHttpRequestOptions {
|
||||||
|
public TestReplaceMatrixOptions() {
|
||||||
|
this.matrixParameters.put("x-amz-copy-source", "/{bucket}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMatrixInOptions() throws SecurityException, NoSuchMethodException,
|
||||||
|
UnsupportedEncodingException {
|
||||||
|
Method oneMatrix = TestMatrixReplace.class.getMethod("matrixInOptions", String.class,
|
||||||
|
TestReplaceMatrixOptions.class);
|
||||||
|
String path = factory(TestMatrixReplace.class).createRequest(oneMatrix,
|
||||||
|
new Object[] { "robot", new TestReplaceMatrixOptions() }).getEndpoint().getPath();
|
||||||
|
assertEquals(path, "/;x-amz-copy-source=/robot");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Endpoint(Localhost.class)
|
||||||
|
@Path("/")
|
||||||
|
public class TestMatrixReplace {
|
||||||
|
|
||||||
|
@GET
|
||||||
|
public void matrixInOptions(@PathParam("bucket") String path, TestReplaceMatrixOptions options) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@MatrixParams(keys = "x-amz-copy-source", values = "/{bucket}")
|
||||||
|
public void oneMatrix(@PathParam("bucket") String path) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@MatrixParams(keys = { "slash", "hyphen" }, values = { "/{bucket}", "-{bucket}" })
|
||||||
|
public void twoMatrix(@PathParam("bucket") String path) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@MatrixParams(keys = "x-amz-copy-source", values = "/{bucket}/{key}")
|
||||||
|
public void twoMatrixs(@PathParam("bucket") String path, @PathParam("key") String path2) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@MatrixParams(keys = "x-amz-copy-source", values = "/{bucket}/{key}")
|
||||||
|
public void twoMatrixsOutOfOrder(@PathParam("key") String path,
|
||||||
|
@PathParam("bucket") String path2) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testBuildTwoMatrix() throws SecurityException, NoSuchMethodException,
|
||||||
|
UnsupportedEncodingException {
|
||||||
|
Method oneMatrix = TestMatrixReplace.class.getMethod("twoMatrix", String.class);
|
||||||
|
String path = factory(TestMatrixReplace.class).createRequest(oneMatrix,
|
||||||
|
new Object[] { "robot" }).getEndpoint().getPath();
|
||||||
|
assertEquals(path, "/;slash=/robot;hyphen=-robot");
|
||||||
|
}
|
||||||
|
|
||||||
|
@MatrixParams(keys = "x-amz-copy-source", values = "/{bucket}")
|
||||||
|
@Endpoint(Localhost.class)
|
||||||
|
@Path("/")
|
||||||
|
public class TestClassMatrix {
|
||||||
|
@GET
|
||||||
|
public void oneMatrix(@PathParam("bucket") String path) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testBuildOneClassMatrix() throws SecurityException, NoSuchMethodException,
|
||||||
|
UnsupportedEncodingException {
|
||||||
|
Method oneMatrix = TestClassMatrix.class.getMethod("oneMatrix", String.class);
|
||||||
|
String path = factory(TestClassMatrix.class).createRequest(oneMatrix,
|
||||||
|
new Object[] { "robot" }).getEndpoint().getPath();
|
||||||
|
assertEquals(path, "/;x-amz-copy-source=/robot");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testBuildOneMatrix() throws SecurityException, NoSuchMethodException,
|
||||||
|
UnsupportedEncodingException {
|
||||||
|
Method oneMatrix = TestMatrixReplace.class.getMethod("oneMatrix", String.class);
|
||||||
|
String path = factory(TestMatrixReplace.class).createRequest(oneMatrix,
|
||||||
|
new Object[] { "robot" }).getEndpoint().getPath();
|
||||||
|
assertEquals(path, "/;x-amz-copy-source=/robot");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testBuildTwoMatrixs() throws SecurityException, NoSuchMethodException,
|
||||||
|
UnsupportedEncodingException {
|
||||||
|
Method twoMatrixs = TestMatrixReplace.class.getMethod("twoMatrixs", String.class,
|
||||||
|
String.class);
|
||||||
|
String path = factory(TestMatrixReplace.class).createRequest(twoMatrixs,
|
||||||
|
new Object[] { "robot", "eggs" }).getEndpoint().getPath();
|
||||||
|
assertEquals(path, "/;x-amz-copy-source=/robot/eggs");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testBuildTwoMatrixsOutOfOrder() throws SecurityException, NoSuchMethodException,
|
||||||
|
UnsupportedEncodingException {
|
||||||
|
Method twoMatrixsOutOfOrder = TestMatrixReplace.class.getMethod("twoMatrixsOutOfOrder",
|
||||||
|
String.class, String.class);
|
||||||
|
String path = factory(TestMatrixReplace.class).createRequest(twoMatrixsOutOfOrder,
|
||||||
|
new Object[] { "robot", "eggs" }).getEndpoint().getPath();
|
||||||
|
assertEquals(path, "/;x-amz-copy-source=/eggs/robot");
|
||||||
|
}
|
||||||
|
|
||||||
@Endpoint(Localhost.class)
|
@Endpoint(Localhost.class)
|
||||||
public interface TestTransformers {
|
public interface TestTransformers {
|
||||||
@GET
|
@GET
|
||||||
|
@ -697,7 +963,7 @@ public class JaxrsAnnotationProcessorTest {
|
||||||
assertEquals(transformer, ParseURIList.class);
|
assertEquals(transformer, ParseURIList.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class ReturnStringIf200Context extends ReturnStringIf200 implements RestContext {
|
public static class ReturnStringIf200Context extends ReturnStringIf200 implements InvocationContext {
|
||||||
private Object[] args;
|
private Object[] args;
|
||||||
private HttpRequest request;
|
private HttpRequest request;
|
||||||
|
|
||||||
|
@ -783,7 +1049,7 @@ public class JaxrsAnnotationProcessorTest {
|
||||||
@PUT
|
@PUT
|
||||||
@Path("/{id}")
|
@Path("/{id}")
|
||||||
public Future<String> put(@PathParam("id") @ParamParser(FirstCharacter.class) String id,
|
public Future<String> put(@PathParam("id") @ParamParser(FirstCharacter.class) String id,
|
||||||
@EntityParam String payload) {
|
@DecoratorParam(AddAsStringEntity.class) String payload) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -798,7 +1064,8 @@ public class JaxrsAnnotationProcessorTest {
|
||||||
@Path("/{id}")
|
@Path("/{id}")
|
||||||
@Headers(keys = "foo", values = "--{id}--")
|
@Headers(keys = "foo", values = "--{id}--")
|
||||||
@ResponseParser(ReturnTrueIf2xx.class)
|
@ResponseParser(ReturnTrueIf2xx.class)
|
||||||
public Future<String> putHeader(@PathParam("id") String id, @EntityParam String payload) {
|
public Future<String> putHeader(@PathParam("id") String id,
|
||||||
|
@DecoratorParam(AddAsStringEntity.class) String payload) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1080,7 +1347,7 @@ public class JaxrsAnnotationProcessorTest {
|
||||||
public void testOneHeader() throws SecurityException, NoSuchMethodException {
|
public void testOneHeader() throws SecurityException, NoSuchMethodException {
|
||||||
Method method = TestHeaders.class.getMethod("oneHeader", String.class);
|
Method method = TestHeaders.class.getMethod("oneHeader", String.class);
|
||||||
Multimap<String, String> headers = factory(TestHeaders.class).buildHeaders(method,
|
Multimap<String, String> headers = factory(TestHeaders.class).buildHeaders(method,
|
||||||
new Object[] { "robot" });
|
new Object[] { "robot" }, ImmutableMultimap.<String, String> of().entries());
|
||||||
assertEquals(headers.size(), 1);
|
assertEquals(headers.size(), 1);
|
||||||
assertEquals(headers.get("header"), Collections.singletonList("robot"));
|
assertEquals(headers.get("header"), Collections.singletonList("robot"));
|
||||||
}
|
}
|
||||||
|
@ -1089,7 +1356,7 @@ public class JaxrsAnnotationProcessorTest {
|
||||||
public void testOneIntHeader() throws SecurityException, NoSuchMethodException {
|
public void testOneIntHeader() throws SecurityException, NoSuchMethodException {
|
||||||
Method method = TestHeaders.class.getMethod("oneIntHeader", int.class);
|
Method method = TestHeaders.class.getMethod("oneIntHeader", int.class);
|
||||||
Multimap<String, String> headers = factory(TestHeaders.class).buildHeaders(method,
|
Multimap<String, String> headers = factory(TestHeaders.class).buildHeaders(method,
|
||||||
new Object[] { 1 });
|
new Object[] { 1 }, ImmutableMultimap.<String, String> of().entries());
|
||||||
assertEquals(headers.size(), 1);
|
assertEquals(headers.size(), 1);
|
||||||
assertEquals(headers.get("header"), Collections.singletonList("1"));
|
assertEquals(headers.get("header"), Collections.singletonList("1"));
|
||||||
}
|
}
|
||||||
|
@ -1099,7 +1366,7 @@ public class JaxrsAnnotationProcessorTest {
|
||||||
Method method = TestHeaders.class
|
Method method = TestHeaders.class
|
||||||
.getMethod("twoDifferentHeaders", String.class, String.class);
|
.getMethod("twoDifferentHeaders", String.class, String.class);
|
||||||
Multimap<String, String> headers = factory(TestHeaders.class).buildHeaders(method,
|
Multimap<String, String> headers = factory(TestHeaders.class).buildHeaders(method,
|
||||||
new Object[] { "robot", "egg" });
|
new Object[] { "robot", "egg" }, ImmutableMultimap.<String, String> of().entries());
|
||||||
assertEquals(headers.size(), 2);
|
assertEquals(headers.size(), 2);
|
||||||
assertEquals(headers.get("header1"), Collections.singletonList("robot"));
|
assertEquals(headers.get("header1"), Collections.singletonList("robot"));
|
||||||
assertEquals(headers.get("header2"), Collections.singletonList("egg"));
|
assertEquals(headers.get("header2"), Collections.singletonList("egg"));
|
||||||
|
@ -1109,7 +1376,7 @@ public class JaxrsAnnotationProcessorTest {
|
||||||
public void testTwoSameHeaders() throws SecurityException, NoSuchMethodException {
|
public void testTwoSameHeaders() throws SecurityException, NoSuchMethodException {
|
||||||
Method method = TestHeaders.class.getMethod("twoSameHeaders", String.class, String.class);
|
Method method = TestHeaders.class.getMethod("twoSameHeaders", String.class, String.class);
|
||||||
Multimap<String, String> headers = factory(TestHeaders.class).buildHeaders(method,
|
Multimap<String, String> headers = factory(TestHeaders.class).buildHeaders(method,
|
||||||
new Object[] { "robot", "egg" });
|
new Object[] { "robot", "egg" }, ImmutableMultimap.<String, String> of().entries());
|
||||||
assertEquals(headers.size(), 2);
|
assertEquals(headers.size(), 2);
|
||||||
Collection<String> values = headers.get("header");
|
Collection<String> values = headers.get("header");
|
||||||
assert values.contains("robot");
|
assert values.contains("robot");
|
||||||
|
@ -1119,22 +1386,23 @@ public class JaxrsAnnotationProcessorTest {
|
||||||
@Endpoint(Localhost.class)
|
@Endpoint(Localhost.class)
|
||||||
public interface TestEntity {
|
public interface TestEntity {
|
||||||
@PUT
|
@PUT
|
||||||
public void put(@EntityParam String content);
|
public void put(@DecoratorParam(AddAsStringEntity.class) String content);
|
||||||
|
|
||||||
@PUT
|
@PUT
|
||||||
@Path("{foo}")
|
@Path("{foo}")
|
||||||
public Future<Void> putWithPath(@PathParam("foo") String path, @EntityParam String content);
|
public Future<Void> putWithPath(@PathParam("foo") String path,
|
||||||
|
@DecoratorParam(AddAsStringEntity.class) String content);
|
||||||
|
|
||||||
@PUT
|
@PUT
|
||||||
public void twoEntities(@EntityParam String entity1, @EntityParam String entity2);
|
public void twoEntities(@DecoratorParam(AddAsStringEntity.class) String entity1,
|
||||||
|
@DecoratorParam(AddAsStringEntity.class) String entity2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testPut() throws SecurityException, NoSuchMethodException {
|
public void testPut() throws SecurityException, NoSuchMethodException {
|
||||||
Method method = TestEntity.class.getMethod("put", String.class);
|
Method method = TestEntity.class.getMethod("put", String.class);
|
||||||
HttpRequest request = new HttpRequest(HttpMethod.PUT, URI.create("http://localhost:8080"));
|
HttpRequest request = new HttpRequest(HttpMethod.PUT, URI.create("http://localhost:8080"));
|
||||||
factory(TestEntity.class).buildEntityIfPostOrPutRequest(method, new Object[] { "test" },
|
factory(TestEntity.class).decorateRequest(method, new Object[] { "test" }, request);
|
||||||
request);
|
|
||||||
assertEquals(request.getEntity(), "test");
|
assertEquals(request.getEntity(), "test");
|
||||||
assertEquals(request.getHeaders().get(HttpHeaders.CONTENT_TYPE), Collections
|
assertEquals(request.getHeaders().get(HttpHeaders.CONTENT_TYPE), Collections
|
||||||
.singletonList("application/unknown"));
|
.singletonList("application/unknown"));
|
||||||
|
@ -1149,8 +1417,7 @@ public class JaxrsAnnotationProcessorTest {
|
||||||
public void putWithPath() throws SecurityException, NoSuchMethodException {
|
public void putWithPath() throws SecurityException, NoSuchMethodException {
|
||||||
Method method = TestEntity.class.getMethod("putWithPath", String.class, String.class);
|
Method method = TestEntity.class.getMethod("putWithPath", String.class, String.class);
|
||||||
HttpRequest request = new HttpRequest(HttpMethod.PUT, URI.create("http://localhost:8080"));
|
HttpRequest request = new HttpRequest(HttpMethod.PUT, URI.create("http://localhost:8080"));
|
||||||
factory(TestEntity.class).buildEntityIfPostOrPutRequest(method,
|
factory(TestEntity.class).decorateRequest(method, new Object[] { "rabble", "test" }, request);
|
||||||
new Object[] { "rabble", "test" }, request);
|
|
||||||
assertEquals(request.getEntity(), "test");
|
assertEquals(request.getEntity(), "test");
|
||||||
assertEquals(request.getHeaders().get(HttpHeaders.CONTENT_TYPE), Collections
|
assertEquals(request.getHeaders().get(HttpHeaders.CONTENT_TYPE), Collections
|
||||||
.singletonList("application/unknown"));
|
.singletonList("application/unknown"));
|
||||||
|
@ -1162,14 +1429,14 @@ public class JaxrsAnnotationProcessorTest {
|
||||||
public void testPutTwoEntities() throws SecurityException, NoSuchMethodException {
|
public void testPutTwoEntities() throws SecurityException, NoSuchMethodException {
|
||||||
Method method = TestEntity.class.getMethod("twoEntities", String.class, String.class);
|
Method method = TestEntity.class.getMethod("twoEntities", String.class, String.class);
|
||||||
HttpRequest request = new HttpRequest(HttpMethod.PUT, URI.create("http://localhost:8080"));
|
HttpRequest request = new HttpRequest(HttpMethod.PUT, URI.create("http://localhost:8080"));
|
||||||
factory(TestEntity.class).buildEntityIfPostOrPutRequest(method,
|
factory(TestEntity.class)
|
||||||
new Object[] { "test", "ralphie" }, request);
|
.decorateRequest(method, new Object[] { "test", "ralphie" }, request);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
private <T> JaxrsAnnotationProcessor<T> factory(Class<T> clazz) {
|
private <T> RestAnnotationProcessor<T> factory(Class<T> clazz) {
|
||||||
return ((JaxrsAnnotationProcessor<T>) injector.getInstance(Key.get(TypeLiteral.get(Types
|
return ((RestAnnotationProcessor<T>) injector.getInstance(Key.get(TypeLiteral.get(Types
|
||||||
.newParameterizedType(JaxrsAnnotationProcessor.class, clazz)))));
|
.newParameterizedType(RestAnnotationProcessor.class, clazz)))));
|
||||||
}
|
}
|
||||||
|
|
||||||
Injector injector;
|
Injector injector;
|
||||||
|
@ -1186,7 +1453,7 @@ public class JaxrsAnnotationProcessorTest {
|
||||||
bind(URI.class).annotatedWith(Localhost2.class).toInstance(
|
bind(URI.class).annotatedWith(Localhost2.class).toInstance(
|
||||||
URI.create("http://localhost:8081"));
|
URI.create("http://localhost:8081"));
|
||||||
}
|
}
|
||||||
}, new JaxrsModule(), new ExecutorServiceModule(new WithinThreadExecutorService()),
|
}, new RestModule(), new ExecutorServiceModule(new WithinThreadExecutorService()),
|
||||||
new JavaUrlHttpCommandExecutorServiceModule());
|
new JavaUrlHttpCommandExecutorServiceModule());
|
||||||
|
|
||||||
}
|
}
|
|
@ -85,7 +85,7 @@ public class NioHttpCommandExecutionHandler implements NHttpRequestExecutionHand
|
||||||
if (rendezvous != null) {
|
if (rendezvous != null) {
|
||||||
HttpRequest request = rendezvous.getCommand().getRequest();
|
HttpRequest request = rendezvous.getCommand().getRequest();
|
||||||
for (HttpRequestFilter filter : request.getFilters()) {
|
for (HttpRequestFilter filter : request.getFilters()) {
|
||||||
filter.filter(request);
|
request = filter.filter(request);
|
||||||
}
|
}
|
||||||
return NioHttpUtils.convertToApacheRequest(request);
|
return NioHttpUtils.convertToApacheRequest(request);
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,8 +38,8 @@ import org.jclouds.blobstore.functions.ReturnVoidOnNotFoundOr404;
|
||||||
import org.jclouds.blobstore.functions.ThrowKeyNotFoundOn404;
|
import org.jclouds.blobstore.functions.ThrowKeyNotFoundOn404;
|
||||||
import org.jclouds.http.filters.BasicAuthentication;
|
import org.jclouds.http.filters.BasicAuthentication;
|
||||||
import org.jclouds.http.options.GetOptions;
|
import org.jclouds.http.options.GetOptions;
|
||||||
import org.jclouds.mezeo.pcs2.binders.BlockBinder;
|
import org.jclouds.mezeo.pcs2.decorators.AddDataAndLength;
|
||||||
import org.jclouds.mezeo.pcs2.binders.CreateContainerBinder;
|
import org.jclouds.mezeo.pcs2.decorators.AddContainerNameAsXmlEntity;
|
||||||
import org.jclouds.mezeo.pcs2.domain.ContainerMetadata;
|
import org.jclouds.mezeo.pcs2.domain.ContainerMetadata;
|
||||||
import org.jclouds.mezeo.pcs2.domain.FileMetadata;
|
import org.jclouds.mezeo.pcs2.domain.FileMetadata;
|
||||||
import org.jclouds.mezeo.pcs2.domain.PCSFile;
|
import org.jclouds.mezeo.pcs2.domain.PCSFile;
|
||||||
|
@ -57,15 +57,15 @@ import org.jclouds.mezeo.pcs2.functions.ReturnTrueIfContainerAlreadyExists;
|
||||||
import org.jclouds.mezeo.pcs2.xml.CachingFileListToContainerMetadataListHandler;
|
import org.jclouds.mezeo.pcs2.xml.CachingFileListToContainerMetadataListHandler;
|
||||||
import org.jclouds.mezeo.pcs2.xml.FileListToFileMetadataListHandler;
|
import org.jclouds.mezeo.pcs2.xml.FileListToFileMetadataListHandler;
|
||||||
import org.jclouds.mezeo.pcs2.xml.FileMetadataHandler;
|
import org.jclouds.mezeo.pcs2.xml.FileMetadataHandler;
|
||||||
import org.jclouds.rest.Endpoint;
|
import org.jclouds.rest.annotations.DecoratorParam;
|
||||||
import org.jclouds.rest.EntityParam;
|
import org.jclouds.rest.annotations.Endpoint;
|
||||||
import org.jclouds.rest.ExceptionParser;
|
import org.jclouds.rest.annotations.ExceptionParser;
|
||||||
import org.jclouds.rest.Headers;
|
import org.jclouds.rest.annotations.Headers;
|
||||||
import org.jclouds.rest.ParamParser;
|
import org.jclouds.rest.annotations.ParamParser;
|
||||||
import org.jclouds.rest.RequestFilters;
|
import org.jclouds.rest.annotations.RequestFilters;
|
||||||
import org.jclouds.rest.ResponseParser;
|
import org.jclouds.rest.annotations.ResponseParser;
|
||||||
import org.jclouds.rest.SkipEncoding;
|
import org.jclouds.rest.annotations.SkipEncoding;
|
||||||
import org.jclouds.rest.XMLResponseParser;
|
import org.jclouds.rest.annotations.XMLResponseParser;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides access to Mezeo PCS v2 via their REST API.
|
* Provides access to Mezeo PCS v2 via their REST API.
|
||||||
|
@ -98,7 +98,7 @@ public interface PCSBlobStore extends BlobStore<ContainerMetadata, FileMetadata,
|
||||||
@Path("/contents")
|
@Path("/contents")
|
||||||
@Endpoint(RootContainer.class)
|
@Endpoint(RootContainer.class)
|
||||||
@ExceptionParser(ReturnTrueIfContainerAlreadyExists.class)
|
@ExceptionParser(ReturnTrueIfContainerAlreadyExists.class)
|
||||||
Future<Boolean> createContainer(@EntityParam(CreateContainerBinder.class) String container);
|
Future<Boolean> createContainer(@DecoratorParam(AddContainerNameAsXmlEntity.class) String container);
|
||||||
|
|
||||||
@DELETE
|
@DELETE
|
||||||
@ExceptionParser(ReturnVoidOnNotFoundOr404.class)
|
@ExceptionParser(ReturnVoidOnNotFoundOr404.class)
|
||||||
|
@ -124,7 +124,7 @@ public interface PCSBlobStore extends BlobStore<ContainerMetadata, FileMetadata,
|
||||||
@PathParam("fileResourceId")
|
@PathParam("fileResourceId")
|
||||||
@ParamParser(CreateSubFolderIfNotExistsAndNewFileResource.class)
|
@ParamParser(CreateSubFolderIfNotExistsAndNewFileResource.class)
|
||||||
Future<byte[]> putBlob(String containerName,
|
Future<byte[]> putBlob(String containerName,
|
||||||
@EntityParam(BlockBinder.class) PCSFile object);
|
@DecoratorParam(AddDataAndLength.class) PCSFile object);
|
||||||
|
|
||||||
// @POST
|
// @POST
|
||||||
// @Path("/containers/{containerResourceId}/contents")
|
// @Path("/containers/{containerResourceId}/contents")
|
||||||
|
@ -133,7 +133,7 @@ public interface PCSBlobStore extends BlobStore<ContainerMetadata, FileMetadata,
|
||||||
// @PathParam("containerResourceId")
|
// @PathParam("containerResourceId")
|
||||||
// @ParamParser(CreateSubFolderIfNotExistsAndGetResourceId.class)
|
// @ParamParser(CreateSubFolderIfNotExistsAndGetResourceId.class)
|
||||||
// Future<byte[]> putBlob(String containerName,
|
// Future<byte[]> putBlob(String containerName,
|
||||||
// @EntityParam(PCSFileAsMultipartFormBinder.class) PCSFile object);
|
// @EntityParam(BlobAsMultipartFormBinder.class) PCSFile object);
|
||||||
|
|
||||||
@DELETE
|
@DELETE
|
||||||
@ExceptionParser(ReturnVoidOnNotFoundOr404.class)
|
@ExceptionParser(ReturnVoidOnNotFoundOr404.class)
|
||||||
|
|
|
@ -37,9 +37,9 @@ import org.jclouds.mezeo.pcs2.endpoints.RootContainer;
|
||||||
import org.jclouds.mezeo.pcs2.endpoints.Shares;
|
import org.jclouds.mezeo.pcs2.endpoints.Shares;
|
||||||
import org.jclouds.mezeo.pcs2.endpoints.Tags;
|
import org.jclouds.mezeo.pcs2.endpoints.Tags;
|
||||||
import org.jclouds.mezeo.pcs2.xml.CloudXlinkHandler;
|
import org.jclouds.mezeo.pcs2.xml.CloudXlinkHandler;
|
||||||
import org.jclouds.rest.Endpoint;
|
import org.jclouds.rest.annotations.Endpoint;
|
||||||
import org.jclouds.rest.RequestFilters;
|
import org.jclouds.rest.annotations.RequestFilters;
|
||||||
import org.jclouds.rest.XMLResponseParser;
|
import org.jclouds.rest.annotations.XMLResponseParser;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides URIs to PCS services via their REST API.
|
* Provides URIs to PCS services via their REST API.
|
||||||
|
|
|
@ -34,13 +34,13 @@ import javax.ws.rs.POST;
|
||||||
import javax.ws.rs.PUT;
|
import javax.ws.rs.PUT;
|
||||||
import javax.ws.rs.Path;
|
import javax.ws.rs.Path;
|
||||||
|
|
||||||
|
import org.jclouds.blobstore.decorators.AddBlobEntityAsMultipartForm;
|
||||||
import org.jclouds.blobstore.functions.ReturnVoidOnNotFoundOr404;
|
import org.jclouds.blobstore.functions.ReturnVoidOnNotFoundOr404;
|
||||||
import org.jclouds.blobstore.functions.ThrowKeyNotFoundOn404;
|
import org.jclouds.blobstore.functions.ThrowKeyNotFoundOn404;
|
||||||
import org.jclouds.http.filters.BasicAuthentication;
|
import org.jclouds.http.filters.BasicAuthentication;
|
||||||
import org.jclouds.mezeo.pcs2.binders.BlockBinder;
|
import org.jclouds.mezeo.pcs2.decorators.AddDataAndLength;
|
||||||
import org.jclouds.mezeo.pcs2.binders.CreateContainerBinder;
|
import org.jclouds.mezeo.pcs2.decorators.AddContainerNameAsXmlEntity;
|
||||||
import org.jclouds.mezeo.pcs2.binders.CreateFileBinder;
|
import org.jclouds.mezeo.pcs2.decorators.AddFileInfoAsXmlEntity;
|
||||||
import org.jclouds.mezeo.pcs2.binders.PCSFileAsMultipartFormBinder;
|
|
||||||
import org.jclouds.mezeo.pcs2.domain.ContainerMetadata;
|
import org.jclouds.mezeo.pcs2.domain.ContainerMetadata;
|
||||||
import org.jclouds.mezeo.pcs2.domain.FileMetadata;
|
import org.jclouds.mezeo.pcs2.domain.FileMetadata;
|
||||||
import org.jclouds.mezeo.pcs2.domain.PCSFile;
|
import org.jclouds.mezeo.pcs2.domain.PCSFile;
|
||||||
|
@ -48,13 +48,13 @@ import org.jclouds.mezeo.pcs2.endpoints.RootContainer;
|
||||||
import org.jclouds.mezeo.pcs2.options.PutBlockOptions;
|
import org.jclouds.mezeo.pcs2.options.PutBlockOptions;
|
||||||
import org.jclouds.mezeo.pcs2.xml.FileListToContainerMetadataListHandler;
|
import org.jclouds.mezeo.pcs2.xml.FileListToContainerMetadataListHandler;
|
||||||
import org.jclouds.mezeo.pcs2.xml.FileListToFileMetadataListHandler;
|
import org.jclouds.mezeo.pcs2.xml.FileListToFileMetadataListHandler;
|
||||||
import org.jclouds.rest.Endpoint;
|
import org.jclouds.rest.annotations.DecoratorParam;
|
||||||
import org.jclouds.rest.EntityParam;
|
import org.jclouds.rest.annotations.Endpoint;
|
||||||
import org.jclouds.rest.ExceptionParser;
|
import org.jclouds.rest.annotations.ExceptionParser;
|
||||||
import org.jclouds.rest.Headers;
|
import org.jclouds.rest.annotations.Headers;
|
||||||
import org.jclouds.rest.RequestFilters;
|
import org.jclouds.rest.annotations.RequestFilters;
|
||||||
import org.jclouds.rest.SkipEncoding;
|
import org.jclouds.rest.annotations.SkipEncoding;
|
||||||
import org.jclouds.rest.XMLResponseParser;
|
import org.jclouds.rest.annotations.XMLResponseParser;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides access to Mezeo PCS v2 via their REST API.
|
* Provides access to Mezeo PCS v2 via their REST API.
|
||||||
|
@ -79,12 +79,12 @@ public interface PCSConnection {
|
||||||
@POST
|
@POST
|
||||||
@Path("/contents")
|
@Path("/contents")
|
||||||
@Endpoint(RootContainer.class)
|
@Endpoint(RootContainer.class)
|
||||||
Future<URI> createContainer(@EntityParam(CreateContainerBinder.class) String container);
|
Future<URI> createContainer(@DecoratorParam(AddContainerNameAsXmlEntity.class) String container);
|
||||||
|
|
||||||
@POST
|
@POST
|
||||||
@Path("/contents")
|
@Path("/contents")
|
||||||
Future<URI> createContainer(@Endpoint URI parent,
|
Future<URI> createContainer(@Endpoint URI parent,
|
||||||
@EntityParam(CreateContainerBinder.class) String container);
|
@DecoratorParam(AddContainerNameAsXmlEntity.class) String container);
|
||||||
|
|
||||||
@DELETE
|
@DELETE
|
||||||
@ExceptionParser(ReturnVoidOnNotFoundOr404.class)
|
@ExceptionParser(ReturnVoidOnNotFoundOr404.class)
|
||||||
|
@ -105,17 +105,17 @@ public interface PCSConnection {
|
||||||
@POST
|
@POST
|
||||||
@Path("/contents")
|
@Path("/contents")
|
||||||
Future<URI> uploadFile(@Endpoint URI container,
|
Future<URI> uploadFile(@Endpoint URI container,
|
||||||
@EntityParam(PCSFileAsMultipartFormBinder.class) PCSFile object);
|
@DecoratorParam(AddBlobEntityAsMultipartForm.class) PCSFile object);
|
||||||
|
|
||||||
@POST
|
@POST
|
||||||
@Path("/contents")
|
@Path("/contents")
|
||||||
Future<URI> createFile(@Endpoint URI container,
|
Future<URI> createFile(@Endpoint URI container,
|
||||||
@EntityParam(CreateFileBinder.class) PCSFile object);
|
@DecoratorParam(AddFileInfoAsXmlEntity.class) PCSFile object);
|
||||||
|
|
||||||
@PUT
|
@PUT
|
||||||
@Path("/content")
|
@Path("/content")
|
||||||
Future<Void> uploadBlock(@Endpoint URI file,
|
Future<Void> uploadBlock(@Endpoint URI file,
|
||||||
@EntityParam(BlockBinder.class) PCSFile object, PutBlockOptions ... options);
|
@DecoratorParam(AddDataAndLength.class) PCSFile object, PutBlockOptions ... options);
|
||||||
|
|
||||||
@DELETE
|
@DELETE
|
||||||
@ExceptionParser(ReturnVoidOnNotFoundOr404.class)
|
@ExceptionParser(ReturnVoidOnNotFoundOr404.class)
|
||||||
|
|
|
@ -33,11 +33,12 @@ import javax.ws.rs.PathParam;
|
||||||
|
|
||||||
import org.jclouds.http.filters.BasicAuthentication;
|
import org.jclouds.http.filters.BasicAuthentication;
|
||||||
import org.jclouds.mezeo.pcs2.functions.AddEntryIntoMultiMap;
|
import org.jclouds.mezeo.pcs2.functions.AddEntryIntoMultiMap;
|
||||||
import org.jclouds.rest.Endpoint;
|
import org.jclouds.rest.annotations.DecoratorParam;
|
||||||
import org.jclouds.rest.EntityParam;
|
import org.jclouds.rest.annotations.Endpoint;
|
||||||
import org.jclouds.rest.RequestFilters;
|
import org.jclouds.rest.annotations.RequestFilters;
|
||||||
import org.jclouds.rest.ResponseParser;
|
import org.jclouds.rest.annotations.ResponseParser;
|
||||||
import org.jclouds.rest.SkipEncoding;
|
import org.jclouds.rest.annotations.SkipEncoding;
|
||||||
|
import org.jclouds.rest.decorators.AddAsStringEntity;
|
||||||
|
|
||||||
import com.google.common.collect.Multimap;
|
import com.google.common.collect.Multimap;
|
||||||
|
|
||||||
|
@ -58,7 +59,7 @@ public interface PCSUtil {
|
||||||
@Endpoint(PCS.class)
|
@Endpoint(PCS.class)
|
||||||
@Path("/files/{fileResourceId}/metadata/{key}")
|
@Path("/files/{fileResourceId}/metadata/{key}")
|
||||||
Future<Void> putMetadata(@PathParam("fileResourceId") String resourceId,
|
Future<Void> putMetadata(@PathParam("fileResourceId") String resourceId,
|
||||||
@PathParam("key") String key, @EntityParam String value);
|
@PathParam("key") String key, @DecoratorParam(AddAsStringEntity.class) String value);
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
@ResponseParser(AddEntryIntoMultiMap.class)
|
@ResponseParser(AddEntryIntoMultiMap.class)
|
||||||
|
|
|
@ -35,6 +35,7 @@ import javax.inject.Singleton;
|
||||||
import org.jclouds.blobstore.BlobStore;
|
import org.jclouds.blobstore.BlobStore;
|
||||||
import org.jclouds.blobstore.BlobStoreContextImpl;
|
import org.jclouds.blobstore.BlobStoreContextImpl;
|
||||||
import org.jclouds.blobstore.BlobMap.Factory;
|
import org.jclouds.blobstore.BlobMap.Factory;
|
||||||
|
import org.jclouds.blobstore.domain.Key;
|
||||||
import org.jclouds.lifecycle.Closer;
|
import org.jclouds.lifecycle.Closer;
|
||||||
import org.jclouds.mezeo.pcs2.PCS;
|
import org.jclouds.mezeo.pcs2.PCS;
|
||||||
import org.jclouds.mezeo.pcs2.PCSConnection;
|
import org.jclouds.mezeo.pcs2.PCSConnection;
|
||||||
|
@ -44,7 +45,6 @@ import org.jclouds.mezeo.pcs2.domain.FileMetadata;
|
||||||
import org.jclouds.mezeo.pcs2.domain.PCSFile;
|
import org.jclouds.mezeo.pcs2.domain.PCSFile;
|
||||||
import org.jclouds.mezeo.pcs2.functions.FindIdInContainerList;
|
import org.jclouds.mezeo.pcs2.functions.FindIdInContainerList;
|
||||||
import org.jclouds.mezeo.pcs2.functions.FindIdInFileList;
|
import org.jclouds.mezeo.pcs2.functions.FindIdInFileList;
|
||||||
import org.jclouds.mezeo.pcs2.functions.Key;
|
|
||||||
import org.jclouds.mezeo.pcs2.reference.PCSConstants;
|
import org.jclouds.mezeo.pcs2.reference.PCSConstants;
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
|
|
|
@ -21,28 +21,29 @@
|
||||||
* under the License.
|
* under the License.
|
||||||
* ====================================================================
|
* ====================================================================
|
||||||
*/
|
*/
|
||||||
package org.jclouds.mezeo.pcs2.binders;
|
package org.jclouds.mezeo.pcs2.decorators;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
|
||||||
import javax.ws.rs.core.HttpHeaders;
|
import javax.ws.rs.core.HttpHeaders;
|
||||||
|
|
||||||
import org.jclouds.http.HttpRequest;
|
import org.jclouds.http.HttpRequest;
|
||||||
import org.jclouds.rest.binders.EntityBinder;
|
import org.jclouds.rest.decorators.RequestDecorator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class CreateContainerBinder implements EntityBinder {
|
public class AddContainerNameAsXmlEntity implements RequestDecorator {
|
||||||
|
|
||||||
public void addEntityToRequest(Object toBind, HttpRequest request) {
|
public HttpRequest decorateRequest(HttpRequest request, Object toBind) {
|
||||||
String container = String.format("<container><name>%s</name></container>", toBind);
|
String container = String.format("<container><name>%s</name></container>", toBind);
|
||||||
request.setEntity(container);
|
request.setEntity(container);
|
||||||
request.getHeaders().replaceValues(HttpHeaders.CONTENT_LENGTH,
|
request.getHeaders().replaceValues(HttpHeaders.CONTENT_LENGTH,
|
||||||
Collections.singletonList(container.getBytes().length + ""));
|
Collections.singletonList(container.getBytes().length + ""));
|
||||||
request.getHeaders().replaceValues(HttpHeaders.CONTENT_TYPE,
|
request.getHeaders().replaceValues(HttpHeaders.CONTENT_TYPE,
|
||||||
Collections.singletonList("application/vnd.csp.container-info+xml"));
|
Collections.singletonList("application/vnd.csp.container-info+xml"));
|
||||||
|
return request;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package org.jclouds.mezeo.pcs2.binders;
|
package org.jclouds.mezeo.pcs2.decorators;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
|
@ -6,13 +6,14 @@ import javax.ws.rs.core.HttpHeaders;
|
||||||
|
|
||||||
import org.jclouds.blobstore.domain.Blob;
|
import org.jclouds.blobstore.domain.Blob;
|
||||||
import org.jclouds.http.HttpRequest;
|
import org.jclouds.http.HttpRequest;
|
||||||
import org.jclouds.rest.binders.EntityBinder;
|
import org.jclouds.rest.decorators.RequestDecorator;
|
||||||
|
|
||||||
public class BlockBinder implements EntityBinder {
|
public class AddDataAndLength implements RequestDecorator {
|
||||||
|
|
||||||
public void addEntityToRequest(Object entity, HttpRequest request) {
|
public HttpRequest decorateRequest(HttpRequest request, Object entity) {
|
||||||
Blob<?> object = (Blob<?>) entity;
|
Blob<?> object = (Blob<?>) entity;
|
||||||
request.setEntity(checkNotNull(object.getData(), "object.getContent()"));
|
request.setEntity(checkNotNull(object.getData(), "object.getContent()"));
|
||||||
request.getHeaders().put(HttpHeaders.CONTENT_LENGTH, object.getMetadata().getSize() + "");
|
request.getHeaders().put(HttpHeaders.CONTENT_LENGTH, object.getMetadata().getSize() + "");
|
||||||
|
return request;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -21,28 +21,28 @@
|
||||||
* under the License.
|
* under the License.
|
||||||
* ====================================================================
|
* ====================================================================
|
||||||
*/
|
*/
|
||||||
package org.jclouds.mezeo.pcs2.binders;
|
package org.jclouds.mezeo.pcs2.decorators;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
|
||||||
import javax.ws.rs.core.HttpHeaders;
|
import javax.ws.rs.core.HttpHeaders;
|
||||||
|
|
||||||
import org.jclouds.blobstore.domain.Blob;
|
import org.jclouds.blobstore.domain.Blob;
|
||||||
|
import org.jclouds.blobstore.domain.Key;
|
||||||
|
import org.jclouds.blobstore.util.BlobStoreUtils;
|
||||||
import org.jclouds.http.HttpRequest;
|
import org.jclouds.http.HttpRequest;
|
||||||
import org.jclouds.mezeo.pcs2.functions.Key;
|
import org.jclouds.rest.decorators.RequestDecorator;
|
||||||
import org.jclouds.mezeo.pcs2.util.PCSUtils;
|
|
||||||
import org.jclouds.rest.binders.EntityBinder;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class CreateFileBinder implements EntityBinder {
|
public class AddFileInfoAsXmlEntity implements RequestDecorator {
|
||||||
|
|
||||||
public void addEntityToRequest(Object toBind, HttpRequest request) {
|
public HttpRequest decorateRequest(HttpRequest request, Object toBind) {
|
||||||
Blob<?> blob = (Blob<?>) toBind;
|
Blob<?> blob = (Blob<?>) toBind;
|
||||||
String bareKey = PCSUtils.parseKey(new Key("trash", blob.getKey())).getKey();
|
String bareKey = BlobStoreUtils.parseKey(new Key("trash", blob.getKey())).getKey();
|
||||||
String file = String.format(
|
String file = String.format(
|
||||||
"<file><name>%s</name><mime_type>%s</mime_type><public>false</public></file>",
|
"<file><name>%s</name><mime_type>%s</mime_type><public>false</public></file>",
|
||||||
bareKey, blob.getMetadata().getContentType());
|
bareKey, blob.getMetadata().getContentType());
|
||||||
|
@ -51,5 +51,6 @@ public class CreateFileBinder implements EntityBinder {
|
||||||
Collections.singletonList(file.getBytes().length + ""));
|
Collections.singletonList(file.getBytes().length + ""));
|
||||||
request.getHeaders().replaceValues(HttpHeaders.CONTENT_TYPE,
|
request.getHeaders().replaceValues(HttpHeaders.CONTENT_TYPE,
|
||||||
Collections.singletonList("application/vnd.csp.file-info+xml"));
|
Collections.singletonList("application/vnd.csp.file-info+xml"));
|
||||||
|
return request;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -9,7 +9,7 @@ import javax.inject.Inject;
|
||||||
import org.jclouds.http.HttpRequest;
|
import org.jclouds.http.HttpRequest;
|
||||||
import org.jclouds.http.HttpResponse;
|
import org.jclouds.http.HttpResponse;
|
||||||
import org.jclouds.http.functions.ReturnStringIf200;
|
import org.jclouds.http.functions.ReturnStringIf200;
|
||||||
import org.jclouds.rest.RestContext;
|
import org.jclouds.rest.InvocationContext;
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
import com.google.common.collect.Multimap;
|
import com.google.common.collect.Multimap;
|
||||||
|
@ -18,7 +18,7 @@ import com.google.common.collect.Multimap;
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
public class AddEntryIntoMultiMap implements Function<HttpResponse, Void>, RestContext {
|
public class AddEntryIntoMultiMap implements Function<HttpResponse, Void>, InvocationContext {
|
||||||
ReturnStringIf200 returnIf200;
|
ReturnStringIf200 returnIf200;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
|
|
|
@ -38,6 +38,7 @@ import javax.inject.Inject;
|
||||||
import javax.inject.Named;
|
import javax.inject.Named;
|
||||||
|
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
|
import org.jclouds.blobstore.domain.Key;
|
||||||
import org.jclouds.blobstore.internal.BlobRuntimeException;
|
import org.jclouds.blobstore.internal.BlobRuntimeException;
|
||||||
import org.jclouds.blobstore.reference.BlobStoreConstants;
|
import org.jclouds.blobstore.reference.BlobStoreConstants;
|
||||||
import org.jclouds.http.HttpRequest;
|
import org.jclouds.http.HttpRequest;
|
||||||
|
@ -46,7 +47,7 @@ import org.jclouds.logging.Logger;
|
||||||
import org.jclouds.mezeo.pcs2.PCSUtil;
|
import org.jclouds.mezeo.pcs2.PCSUtil;
|
||||||
import org.jclouds.mezeo.pcs2.domain.PCSFile;
|
import org.jclouds.mezeo.pcs2.domain.PCSFile;
|
||||||
import org.jclouds.mezeo.pcs2.util.PCSUtils;
|
import org.jclouds.mezeo.pcs2.util.PCSUtils;
|
||||||
import org.jclouds.rest.RestContext;
|
import org.jclouds.rest.InvocationContext;
|
||||||
import org.jclouds.util.Utils;
|
import org.jclouds.util.Utils;
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
|
@ -58,7 +59,7 @@ import com.google.common.collect.Sets;
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
public class AddMetadataAndParseResourceIdIntoBytes implements Function<HttpResponse, byte[]>,
|
public class AddMetadataAndParseResourceIdIntoBytes implements Function<HttpResponse, byte[]>,
|
||||||
RestContext {
|
InvocationContext {
|
||||||
private final PCSUtil util;
|
private final PCSUtil util;
|
||||||
private final ConcurrentMap<Key, String> fileCache;
|
private final ConcurrentMap<Key, String> fileCache;
|
||||||
|
|
||||||
|
|
|
@ -27,12 +27,13 @@ import java.util.concurrent.ConcurrentMap;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import org.jclouds.blobstore.domain.Key;
|
||||||
import org.jclouds.blobstore.functions.ParseContentTypeFromHeaders;
|
import org.jclouds.blobstore.functions.ParseContentTypeFromHeaders;
|
||||||
import org.jclouds.http.HttpRequest;
|
import org.jclouds.http.HttpRequest;
|
||||||
import org.jclouds.http.HttpResponse;
|
import org.jclouds.http.HttpResponse;
|
||||||
import org.jclouds.mezeo.pcs2.domain.FileMetadata;
|
import org.jclouds.mezeo.pcs2.domain.FileMetadata;
|
||||||
import org.jclouds.mezeo.pcs2.domain.PCSFile;
|
import org.jclouds.mezeo.pcs2.domain.PCSFile;
|
||||||
import org.jclouds.rest.RestContext;
|
import org.jclouds.rest.InvocationContext;
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
|
|
||||||
|
@ -43,7 +44,7 @@ import com.google.common.base.Function;
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
public class AssembleBlobFromContentAndMetadataCache implements Function<HttpResponse, PCSFile>,
|
public class AssembleBlobFromContentAndMetadataCache implements Function<HttpResponse, PCSFile>,
|
||||||
RestContext {
|
InvocationContext {
|
||||||
|
|
||||||
private final ConcurrentMap<Key, FileMetadata> cache;
|
private final ConcurrentMap<Key, FileMetadata> cache;
|
||||||
private HttpRequest request;
|
private HttpRequest request;
|
||||||
|
|
|
@ -34,6 +34,7 @@ import javax.inject.Singleton;
|
||||||
|
|
||||||
import org.jclouds.blobstore.ContainerNotFoundException;
|
import org.jclouds.blobstore.ContainerNotFoundException;
|
||||||
import org.jclouds.blobstore.KeyNotFoundException;
|
import org.jclouds.blobstore.KeyNotFoundException;
|
||||||
|
import org.jclouds.blobstore.domain.Key;
|
||||||
import org.jclouds.util.Utils;
|
import org.jclouds.util.Utils;
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
|
|
|
@ -40,8 +40,10 @@ import javax.inject.Singleton;
|
||||||
|
|
||||||
import org.jclouds.blobstore.ContainerNotFoundException;
|
import org.jclouds.blobstore.ContainerNotFoundException;
|
||||||
import org.jclouds.blobstore.domain.Blob;
|
import org.jclouds.blobstore.domain.Blob;
|
||||||
|
import org.jclouds.blobstore.domain.Key;
|
||||||
import org.jclouds.blobstore.internal.BlobRuntimeException;
|
import org.jclouds.blobstore.internal.BlobRuntimeException;
|
||||||
import org.jclouds.blobstore.reference.BlobStoreConstants;
|
import org.jclouds.blobstore.reference.BlobStoreConstants;
|
||||||
|
import org.jclouds.blobstore.util.BlobStoreUtils;
|
||||||
import org.jclouds.mezeo.pcs2.PCSConnection;
|
import org.jclouds.mezeo.pcs2.PCSConnection;
|
||||||
import org.jclouds.mezeo.pcs2.domain.ContainerMetadata;
|
import org.jclouds.mezeo.pcs2.domain.ContainerMetadata;
|
||||||
import org.jclouds.mezeo.pcs2.endpoints.RootContainer;
|
import org.jclouds.mezeo.pcs2.endpoints.RootContainer;
|
||||||
|
@ -85,7 +87,7 @@ public class CreateSubFolderIfNotExistsAndGetResourceId implements Function<Obje
|
||||||
Object[] args = (Object[]) from;
|
Object[] args = (Object[]) from;
|
||||||
checkArgument(args[0] instanceof String, "arg[0] must be a container name");
|
checkArgument(args[0] instanceof String, "arg[0] must be a container name");
|
||||||
checkArgument(args[1] instanceof Blob, "arg[1] must be a pcsfile");
|
checkArgument(args[1] instanceof Blob, "arg[1] must be a pcsfile");
|
||||||
Key key = PCSUtils.parseKey(new Key(args[0].toString(), ((Blob) args[1]).getKey()));
|
Key key = BlobStoreUtils.parseKey(new Key(args[0].toString(), ((Blob) args[1]).getKey()));
|
||||||
try {
|
try {
|
||||||
return finder.get(key.getContainer());
|
return finder.get(key.getContainer());
|
||||||
} catch (ComputationException e) {
|
} catch (ComputationException e) {
|
||||||
|
@ -95,12 +97,12 @@ public class CreateSubFolderIfNotExistsAndGetResourceId implements Function<Obje
|
||||||
SortedSet<ContainerMetadata> response = blobStore.listContainers();
|
SortedSet<ContainerMetadata> response = blobStore.listContainers();
|
||||||
URI containerUri;
|
URI containerUri;
|
||||||
try {
|
try {
|
||||||
containerUri = urlForNameInListOrCreate(rootContainer, containerTree[0],
|
containerUri = urlForNameInListOrCreate(rootContainer, containerTree[0], response);
|
||||||
response);
|
|
||||||
} catch (Exception e1) {
|
} catch (Exception e1) {
|
||||||
|
|
||||||
Utils.<ContainerNotFoundException> rethrowIfRuntimeOrSameType(e1);
|
Utils.<ContainerNotFoundException> rethrowIfRuntimeOrSameType(e1);
|
||||||
throw new BlobRuntimeException("error creating container at: " + containerTree[0], e1);
|
throw new BlobRuntimeException("error creating container at: " + containerTree[0],
|
||||||
|
e1);
|
||||||
}
|
}
|
||||||
if (containerTree.length != 1) {
|
if (containerTree.length != 1) {
|
||||||
for (int i = 1; i < containerTree.length; i++) {
|
for (int i = 1; i < containerTree.length; i++) {
|
||||||
|
|
|
@ -38,6 +38,7 @@ import javax.ws.rs.core.UriBuilder;
|
||||||
|
|
||||||
import org.jclouds.blobstore.ContainerNotFoundException;
|
import org.jclouds.blobstore.ContainerNotFoundException;
|
||||||
import org.jclouds.blobstore.KeyNotFoundException;
|
import org.jclouds.blobstore.KeyNotFoundException;
|
||||||
|
import org.jclouds.blobstore.domain.Key;
|
||||||
import org.jclouds.blobstore.internal.BlobRuntimeException;
|
import org.jclouds.blobstore.internal.BlobRuntimeException;
|
||||||
import org.jclouds.blobstore.reference.BlobStoreConstants;
|
import org.jclouds.blobstore.reference.BlobStoreConstants;
|
||||||
import org.jclouds.mezeo.pcs2.PCS;
|
import org.jclouds.mezeo.pcs2.PCS;
|
||||||
|
|
|
@ -32,11 +32,12 @@ import javax.inject.Inject;
|
||||||
import org.jclouds.blobstore.BlobStore;
|
import org.jclouds.blobstore.BlobStore;
|
||||||
import org.jclouds.blobstore.ContainerNotFoundException;
|
import org.jclouds.blobstore.ContainerNotFoundException;
|
||||||
import org.jclouds.blobstore.KeyNotFoundException;
|
import org.jclouds.blobstore.KeyNotFoundException;
|
||||||
|
import org.jclouds.blobstore.domain.Key;
|
||||||
|
import org.jclouds.blobstore.util.BlobStoreUtils;
|
||||||
import org.jclouds.http.HttpException;
|
import org.jclouds.http.HttpException;
|
||||||
import org.jclouds.mezeo.pcs2.domain.ContainerMetadata;
|
import org.jclouds.mezeo.pcs2.domain.ContainerMetadata;
|
||||||
import org.jclouds.mezeo.pcs2.domain.FileMetadata;
|
import org.jclouds.mezeo.pcs2.domain.FileMetadata;
|
||||||
import org.jclouds.mezeo.pcs2.domain.PCSFile;
|
import org.jclouds.mezeo.pcs2.domain.PCSFile;
|
||||||
import org.jclouds.mezeo.pcs2.util.PCSUtils;
|
|
||||||
import org.jclouds.util.Utils;
|
import org.jclouds.util.Utils;
|
||||||
|
|
||||||
import com.google.common.annotations.VisibleForTesting;
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
|
@ -51,7 +52,7 @@ public class FindIdInFileList implements Function<Key, String> {
|
||||||
}
|
}
|
||||||
|
|
||||||
public String apply(Key key) {
|
public String apply(Key key) {
|
||||||
key = PCSUtils.parseKey(key);
|
key = BlobStoreUtils.parseKey(key);
|
||||||
SortedSet<FileMetadata> response;
|
SortedSet<FileMetadata> response;
|
||||||
try {
|
try {
|
||||||
response = connection.listBlobs(key.getContainer()).get(10, TimeUnit.SECONDS);
|
response = connection.listBlobs(key.getContainer()).get(10, TimeUnit.SECONDS);
|
||||||
|
|
|
@ -30,7 +30,7 @@ import javax.inject.Inject;
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
import org.jclouds.http.HttpRequest;
|
import org.jclouds.http.HttpRequest;
|
||||||
import org.jclouds.http.HttpResponse;
|
import org.jclouds.http.HttpResponse;
|
||||||
import org.jclouds.rest.RestContext;
|
import org.jclouds.rest.InvocationContext;
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
|
|
||||||
|
@ -40,7 +40,7 @@ import com.google.common.base.Function;
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
public class InvalidateContainerNameCacheAndReturnTrueIf2xx implements Function<HttpResponse, Boolean>,
|
public class InvalidateContainerNameCacheAndReturnTrueIf2xx implements Function<HttpResponse, Boolean>,
|
||||||
RestContext {
|
InvocationContext {
|
||||||
private final ConcurrentMap<String, String> cache;
|
private final ConcurrentMap<String, String> cache;
|
||||||
private HttpRequest request;
|
private HttpRequest request;
|
||||||
private Object[] args;
|
private Object[] args;
|
||||||
|
|
|
@ -28,10 +28,11 @@ import java.util.concurrent.ConcurrentMap;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
|
import org.jclouds.blobstore.domain.Key;
|
||||||
import org.jclouds.http.HttpRequest;
|
import org.jclouds.http.HttpRequest;
|
||||||
import org.jclouds.http.HttpResponse;
|
import org.jclouds.http.HttpResponse;
|
||||||
import org.jclouds.mezeo.pcs2.domain.FileMetadata;
|
import org.jclouds.mezeo.pcs2.domain.FileMetadata;
|
||||||
import org.jclouds.rest.RestContext;
|
import org.jclouds.rest.InvocationContext;
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
|
|
||||||
|
@ -41,7 +42,7 @@ import com.google.common.base.Function;
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
public class InvalidatePCSKeyCacheAndReturnVoidIf2xx implements Function<HttpResponse, Void>,
|
public class InvalidatePCSKeyCacheAndReturnVoidIf2xx implements Function<HttpResponse, Void>,
|
||||||
RestContext {
|
InvocationContext {
|
||||||
private final ConcurrentMap<Key, String> cache;
|
private final ConcurrentMap<Key, String> cache;
|
||||||
private final ConcurrentMap<Key, FileMetadata> mdCache;
|
private final ConcurrentMap<Key, FileMetadata> mdCache;
|
||||||
private HttpRequest request;
|
private HttpRequest request;
|
||||||
|
|
|
@ -26,7 +26,6 @@ package org.jclouds.mezeo.pcs2.util;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
|
||||||
import org.jclouds.http.HttpUtils;
|
import org.jclouds.http.HttpUtils;
|
||||||
import org.jclouds.mezeo.pcs2.functions.Key;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utilities for PCS connections.
|
* Utilities for PCS connections.
|
||||||
|
@ -49,17 +48,6 @@ public class PCSUtils {
|
||||||
return eTag;
|
return eTag;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Key parseKey(Key key) {
|
|
||||||
|
|
||||||
if (key.getKey().indexOf('/') != -1) {
|
|
||||||
String container = key.getContainer() + '/'
|
|
||||||
+ key.getKey().substring(0, key.getKey().lastIndexOf('/'));
|
|
||||||
String newKey = key.getKey().substring(key.getKey().lastIndexOf('/') + 1);
|
|
||||||
key = new Key(container.replaceAll("//", "/"), newKey);
|
|
||||||
}
|
|
||||||
return key;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getContainerId(URI url) {
|
public static String getContainerId(URI url) {
|
||||||
String path = url.getPath();
|
String path = url.getPath();
|
||||||
int indexAfterContainersSlash = path.indexOf("containers/") + "containers/".length();
|
int indexAfterContainersSlash = path.indexOf("containers/") + "containers/".length();
|
||||||
|
|
|
@ -54,7 +54,6 @@ import org.jclouds.http.functions.ParseSax;
|
||||||
import org.jclouds.http.functions.ReturnTrueIf2xx;
|
import org.jclouds.http.functions.ReturnTrueIf2xx;
|
||||||
import org.jclouds.http.functions.ReturnVoidIf2xx;
|
import org.jclouds.http.functions.ReturnVoidIf2xx;
|
||||||
import org.jclouds.http.options.GetOptions;
|
import org.jclouds.http.options.GetOptions;
|
||||||
import org.jclouds.mezeo.pcs2.binders.PCSFileAsMultipartFormBinderTest;
|
|
||||||
import org.jclouds.mezeo.pcs2.domain.ContainerMetadata;
|
import org.jclouds.mezeo.pcs2.domain.ContainerMetadata;
|
||||||
import org.jclouds.mezeo.pcs2.domain.FileMetadata;
|
import org.jclouds.mezeo.pcs2.domain.FileMetadata;
|
||||||
import org.jclouds.mezeo.pcs2.domain.PCSFile;
|
import org.jclouds.mezeo.pcs2.domain.PCSFile;
|
||||||
|
@ -67,8 +66,8 @@ import org.jclouds.mezeo.pcs2.functions.InvalidateContainerNameCacheAndReturnTru
|
||||||
import org.jclouds.mezeo.pcs2.functions.InvalidatePCSKeyCacheAndReturnVoidIf2xx;
|
import org.jclouds.mezeo.pcs2.functions.InvalidatePCSKeyCacheAndReturnVoidIf2xx;
|
||||||
import org.jclouds.mezeo.pcs2.functions.ReturnFalseIfContainerNotFound;
|
import org.jclouds.mezeo.pcs2.functions.ReturnFalseIfContainerNotFound;
|
||||||
import org.jclouds.mezeo.pcs2.options.PutBlockOptions;
|
import org.jclouds.mezeo.pcs2.options.PutBlockOptions;
|
||||||
import org.jclouds.rest.JaxrsAnnotationProcessor;
|
import org.jclouds.rest.config.RestModule;
|
||||||
import org.jclouds.rest.config.JaxrsModule;
|
import org.jclouds.rest.internal.RestAnnotationProcessor;
|
||||||
import org.jclouds.util.DateService;
|
import org.jclouds.util.DateService;
|
||||||
import org.testng.annotations.BeforeClass;
|
import org.testng.annotations.BeforeClass;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
@ -298,19 +297,18 @@ public class PCSBlobStoreTest {
|
||||||
|
|
||||||
public void testPutBlob() throws SecurityException, NoSuchMethodException, IOException {
|
public void testPutBlob() throws SecurityException, NoSuchMethodException, IOException {
|
||||||
Method method = PCSBlobStore.class.getMethod("putBlob", String.class, PCSFile.class);
|
Method method = PCSBlobStore.class.getMethod("putBlob", String.class, PCSFile.class);
|
||||||
|
PCSFile file = new PCSFile("hello");
|
||||||
HttpRequest httpMethod = processor.createRequest(method, new Object[] { "mycontainer",
|
file.setData("wonkers");
|
||||||
PCSFileAsMultipartFormBinderTest.TEST_BLOB });
|
HttpRequest httpMethod = processor
|
||||||
|
.createRequest(method, new Object[] { "mycontainer", file });
|
||||||
assertEquals(httpMethod.getEndpoint().getHost(), "localhost");
|
assertEquals(httpMethod.getEndpoint().getHost(), "localhost");
|
||||||
assertEquals(httpMethod.getEndpoint().getPath(), "/files/o/content");
|
assertEquals(httpMethod.getEndpoint().getPath(), "/files/o/content");
|
||||||
assertEquals(httpMethod.getEndpoint().getQuery(), null);
|
assertEquals(httpMethod.getEndpoint().getQuery(), null);
|
||||||
assertEquals(httpMethod.getMethod(), HttpMethod.PUT);
|
assertEquals(httpMethod.getMethod(), HttpMethod.PUT);
|
||||||
assertEquals(httpMethod.getHeaders().size(), 1);
|
assertEquals(httpMethod.getHeaders().size(), 1);
|
||||||
assertEquals(httpMethod.getHeaders().get(HttpHeaders.CONTENT_LENGTH), Collections
|
assertEquals(httpMethod.getHeaders().get(HttpHeaders.CONTENT_LENGTH), Collections
|
||||||
.singletonList(PCSFileAsMultipartFormBinderTest.TEST_BLOB.getData().toString()
|
.singletonList(file.getData().toString().getBytes().length + ""));
|
||||||
.getBytes().length
|
assertEquals(httpMethod.getEntity(), file.getData());
|
||||||
+ ""));
|
|
||||||
assertEquals(httpMethod.getEntity(), PCSFileAsMultipartFormBinderTest.TEST_BLOB.getData());
|
|
||||||
assertEquals(processor.createResponseParser(method, httpMethod, null).getClass(),
|
assertEquals(processor.createResponseParser(method, httpMethod, null).getClass(),
|
||||||
AddMetadataAndParseResourceIdIntoBytes.class);
|
AddMetadataAndParseResourceIdIntoBytes.class);
|
||||||
}
|
}
|
||||||
|
@ -419,8 +417,8 @@ public class PCSBlobStoreTest {
|
||||||
AddEntryIntoMultiMap.class);
|
AddEntryIntoMultiMap.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
JaxrsAnnotationProcessor<PCSBlobStore> processor;
|
RestAnnotationProcessor<PCSBlobStore> processor;
|
||||||
private JaxrsAnnotationProcessor<PCSUtil> utilProcessor;
|
private RestAnnotationProcessor<PCSUtil> utilProcessor;
|
||||||
|
|
||||||
@BeforeClass
|
@BeforeClass
|
||||||
void setupFactory() {
|
void setupFactory() {
|
||||||
|
@ -459,22 +457,20 @@ public class PCSBlobStoreTest {
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
ConcurrentMap<org.jclouds.mezeo.pcs2.functions.Key, String> giveMap() {
|
ConcurrentMap<org.jclouds.blobstore.domain.Key, String> giveMap() {
|
||||||
ConcurrentHashMap<org.jclouds.mezeo.pcs2.functions.Key, String> map = new ConcurrentHashMap<org.jclouds.mezeo.pcs2.functions.Key, String>();
|
ConcurrentHashMap<org.jclouds.blobstore.domain.Key, String> map = new ConcurrentHashMap<org.jclouds.blobstore.domain.Key, String>();
|
||||||
map.put(
|
map.put(new org.jclouds.blobstore.domain.Key("mycontainer", "testfile.txt"),
|
||||||
new org.jclouds.mezeo.pcs2.functions.Key("mycontainer",
|
"9E4C5AFA-A98B-11DE-8B4C-C3884B4A2DA3");
|
||||||
"testfile.txt"), "9E4C5AFA-A98B-11DE-8B4C-C3884B4A2DA3");
|
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
ConcurrentMap<org.jclouds.mezeo.pcs2.functions.Key, FileMetadata> giveMap2() {
|
ConcurrentMap<org.jclouds.blobstore.domain.Key, FileMetadata> giveMap2() {
|
||||||
ConcurrentHashMap<org.jclouds.mezeo.pcs2.functions.Key, FileMetadata> map = new ConcurrentHashMap<org.jclouds.mezeo.pcs2.functions.Key, FileMetadata>();
|
ConcurrentHashMap<org.jclouds.blobstore.domain.Key, FileMetadata> map = new ConcurrentHashMap<org.jclouds.blobstore.domain.Key, FileMetadata>();
|
||||||
map.put(
|
map.put(new org.jclouds.blobstore.domain.Key("mycontainer", "testfile.txt"),
|
||||||
new org.jclouds.mezeo.pcs2.functions.Key("mycontainer",
|
new FileMetadata("testfile.txt"));
|
||||||
"testfile.txt"), new FileMetadata("testfile.txt"));
|
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -494,14 +490,14 @@ public class PCSBlobStoreTest {
|
||||||
throws UnsupportedEncodingException {
|
throws UnsupportedEncodingException {
|
||||||
return new BasicAuthentication("foo", "bar");
|
return new BasicAuthentication("foo", "bar");
|
||||||
}
|
}
|
||||||
}, new JaxrsModule(), new ExecutorServiceModule(new WithinThreadExecutorService()),
|
}, new RestModule(), new ExecutorServiceModule(new WithinThreadExecutorService()),
|
||||||
new JavaUrlHttpCommandExecutorServiceModule());
|
new JavaUrlHttpCommandExecutorServiceModule());
|
||||||
|
|
||||||
processor = injector.getInstance(Key
|
processor = injector.getInstance(Key
|
||||||
.get(new TypeLiteral<JaxrsAnnotationProcessor<PCSBlobStore>>() {
|
.get(new TypeLiteral<RestAnnotationProcessor<PCSBlobStore>>() {
|
||||||
}));
|
}));
|
||||||
utilProcessor = injector.getInstance(Key
|
utilProcessor = injector.getInstance(Key
|
||||||
.get(new TypeLiteral<JaxrsAnnotationProcessor<PCSUtil>>() {
|
.get(new TypeLiteral<RestAnnotationProcessor<PCSUtil>>() {
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,7 +37,7 @@ import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule;
|
||||||
import org.jclouds.http.filters.BasicAuthentication;
|
import org.jclouds.http.filters.BasicAuthentication;
|
||||||
import org.jclouds.mezeo.pcs2.PCSCloud.Response;
|
import org.jclouds.mezeo.pcs2.PCSCloud.Response;
|
||||||
import org.jclouds.rest.RestClientFactory;
|
import org.jclouds.rest.RestClientFactory;
|
||||||
import org.jclouds.rest.config.JaxrsModule;
|
import org.jclouds.rest.config.RestModule;
|
||||||
import org.testng.annotations.BeforeClass;
|
import org.testng.annotations.BeforeClass;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
@ -97,7 +97,7 @@ public class PCSCloudLiveTest {
|
||||||
protected PCSCloud provideCloud(RestClientFactory factory) {
|
protected PCSCloud provideCloud(RestClientFactory factory) {
|
||||||
return factory.create(PCSCloud.class);
|
return factory.create(PCSCloud.class);
|
||||||
}
|
}
|
||||||
}, new JaxrsModule(), new ExecutorServiceModule(new WithinThreadExecutorService()),
|
}, new RestModule(), new ExecutorServiceModule(new WithinThreadExecutorService()),
|
||||||
new JavaUrlHttpCommandExecutorServiceModule());
|
new JavaUrlHttpCommandExecutorServiceModule());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,6 +39,7 @@ import javax.inject.Singleton;
|
||||||
import javax.ws.rs.HttpMethod;
|
import javax.ws.rs.HttpMethod;
|
||||||
import javax.ws.rs.core.HttpHeaders;
|
import javax.ws.rs.core.HttpHeaders;
|
||||||
|
|
||||||
|
import org.jclouds.blobstore.decorators.AddBlobEntityAsMultipartFormTest;
|
||||||
import org.jclouds.blobstore.functions.ReturnVoidOnNotFoundOr404;
|
import org.jclouds.blobstore.functions.ReturnVoidOnNotFoundOr404;
|
||||||
import org.jclouds.concurrent.WithinThreadExecutorService;
|
import org.jclouds.concurrent.WithinThreadExecutorService;
|
||||||
import org.jclouds.concurrent.config.ExecutorServiceModule;
|
import org.jclouds.concurrent.config.ExecutorServiceModule;
|
||||||
|
@ -49,12 +50,11 @@ import org.jclouds.http.functions.ParseSax;
|
||||||
import org.jclouds.http.functions.ParseURIList;
|
import org.jclouds.http.functions.ParseURIList;
|
||||||
import org.jclouds.http.functions.ReturnInputStream;
|
import org.jclouds.http.functions.ReturnInputStream;
|
||||||
import org.jclouds.http.functions.ReturnVoidIf2xx;
|
import org.jclouds.http.functions.ReturnVoidIf2xx;
|
||||||
import org.jclouds.mezeo.pcs2.binders.PCSFileAsMultipartFormBinderTest;
|
|
||||||
import org.jclouds.mezeo.pcs2.domain.FileMetadata;
|
import org.jclouds.mezeo.pcs2.domain.FileMetadata;
|
||||||
import org.jclouds.mezeo.pcs2.domain.PCSFile;
|
import org.jclouds.mezeo.pcs2.domain.PCSFile;
|
||||||
import org.jclouds.mezeo.pcs2.endpoints.RootContainer;
|
import org.jclouds.mezeo.pcs2.endpoints.RootContainer;
|
||||||
import org.jclouds.rest.JaxrsAnnotationProcessor;
|
import org.jclouds.rest.config.RestModule;
|
||||||
import org.jclouds.rest.config.JaxrsModule;
|
import org.jclouds.rest.internal.RestAnnotationProcessor;
|
||||||
import org.jclouds.util.Utils;
|
import org.jclouds.util.Utils;
|
||||||
import org.testng.annotations.BeforeClass;
|
import org.testng.annotations.BeforeClass;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
@ -165,19 +165,19 @@ public class PCSConnectionTest {
|
||||||
|
|
||||||
HttpRequest httpMethod = processor.createRequest(method, new Object[] {
|
HttpRequest httpMethod = processor.createRequest(method, new Object[] {
|
||||||
URI.create("http://localhost/mycontainer"),
|
URI.create("http://localhost/mycontainer"),
|
||||||
PCSFileAsMultipartFormBinderTest.TEST_BLOB });
|
AddBlobEntityAsMultipartFormTest.TEST_BLOB });
|
||||||
assertEquals(httpMethod.getEndpoint().getHost(), "localhost");
|
assertEquals(httpMethod.getEndpoint().getHost(), "localhost");
|
||||||
assertEquals(httpMethod.getEndpoint().getPath(), "/mycontainer/contents");
|
assertEquals(httpMethod.getEndpoint().getPath(), "/mycontainer/contents");
|
||||||
assertEquals(httpMethod.getEndpoint().getQuery(), null);
|
assertEquals(httpMethod.getEndpoint().getQuery(), null);
|
||||||
assertEquals(httpMethod.getMethod(), HttpMethod.POST);
|
assertEquals(httpMethod.getMethod(), HttpMethod.POST);
|
||||||
assertEquals(httpMethod.getHeaders().size(), 2);
|
assertEquals(httpMethod.getHeaders().size(), 2);
|
||||||
assertEquals(httpMethod.getHeaders().get(HttpHeaders.CONTENT_LENGTH), Collections
|
assertEquals(httpMethod.getHeaders().get(HttpHeaders.CONTENT_LENGTH), Collections
|
||||||
.singletonList(PCSFileAsMultipartFormBinderTest.EXPECTS.length() + ""));
|
.singletonList(AddBlobEntityAsMultipartFormTest.EXPECTS.length() + ""));
|
||||||
assertEquals(httpMethod.getHeaders().get(HttpHeaders.CONTENT_TYPE), Collections
|
assertEquals(httpMethod.getHeaders().get(HttpHeaders.CONTENT_TYPE), Collections
|
||||||
.singletonList("multipart/form-data; boundary="
|
.singletonList("multipart/form-data; boundary="
|
||||||
+ PCSFileAsMultipartFormBinderTest.BOUNDRY));
|
+ AddBlobEntityAsMultipartFormTest.BOUNDRY));
|
||||||
assertEquals(Utils.toStringAndClose((InputStream) httpMethod.getEntity()),
|
assertEquals(Utils.toStringAndClose((InputStream) httpMethod.getEntity()),
|
||||||
PCSFileAsMultipartFormBinderTest.EXPECTS);
|
AddBlobEntityAsMultipartFormTest.EXPECTS);
|
||||||
assertEquals(processor.createResponseParser(method, httpMethod, null).getClass(),
|
assertEquals(processor.createResponseParser(method, httpMethod, null).getClass(),
|
||||||
ParseURIList.class);
|
ParseURIList.class);
|
||||||
}
|
}
|
||||||
|
@ -212,7 +212,7 @@ public class PCSConnectionTest {
|
||||||
ReturnVoidOnNotFoundOr404.class);
|
ReturnVoidOnNotFoundOr404.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
JaxrsAnnotationProcessor<PCSConnection> processor;
|
RestAnnotationProcessor<PCSConnection> processor;
|
||||||
|
|
||||||
@BeforeClass
|
@BeforeClass
|
||||||
void setupFactory() {
|
void setupFactory() {
|
||||||
|
@ -248,22 +248,20 @@ public class PCSConnectionTest {
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
ConcurrentMap<org.jclouds.mezeo.pcs2.functions.Key, String> giveMap() {
|
ConcurrentMap<org.jclouds.blobstore.domain.Key, String> giveMap() {
|
||||||
ConcurrentHashMap<org.jclouds.mezeo.pcs2.functions.Key, String> map = new ConcurrentHashMap<org.jclouds.mezeo.pcs2.functions.Key, String>();
|
ConcurrentHashMap<org.jclouds.blobstore.domain.Key, String> map = new ConcurrentHashMap<org.jclouds.blobstore.domain.Key, String>();
|
||||||
map.put(
|
map.put(new org.jclouds.blobstore.domain.Key("mycontainer", "testfile.txt"),
|
||||||
new org.jclouds.mezeo.pcs2.functions.Key("mycontainer",
|
"9E4C5AFA-A98B-11DE-8B4C-C3884B4A2DA3");
|
||||||
"testfile.txt"), "9E4C5AFA-A98B-11DE-8B4C-C3884B4A2DA3");
|
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
ConcurrentMap<org.jclouds.mezeo.pcs2.functions.Key, FileMetadata> giveMap2() {
|
ConcurrentMap<org.jclouds.blobstore.domain.Key, FileMetadata> giveMap2() {
|
||||||
ConcurrentHashMap<org.jclouds.mezeo.pcs2.functions.Key, FileMetadata> map = new ConcurrentHashMap<org.jclouds.mezeo.pcs2.functions.Key, FileMetadata>();
|
ConcurrentHashMap<org.jclouds.blobstore.domain.Key, FileMetadata> map = new ConcurrentHashMap<org.jclouds.blobstore.domain.Key, FileMetadata>();
|
||||||
map.put(
|
map.put(new org.jclouds.blobstore.domain.Key("mycontainer", "testfile.txt"),
|
||||||
new org.jclouds.mezeo.pcs2.functions.Key("mycontainer",
|
new FileMetadata("testfile.txt"));
|
||||||
"testfile.txt"), new FileMetadata("testfile.txt"));
|
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -283,11 +281,11 @@ public class PCSConnectionTest {
|
||||||
throws UnsupportedEncodingException {
|
throws UnsupportedEncodingException {
|
||||||
return new BasicAuthentication("foo", "bar");
|
return new BasicAuthentication("foo", "bar");
|
||||||
}
|
}
|
||||||
}, new JaxrsModule(), new ExecutorServiceModule(new WithinThreadExecutorService()),
|
}, new RestModule(), new ExecutorServiceModule(new WithinThreadExecutorService()),
|
||||||
new JavaUrlHttpCommandExecutorServiceModule());
|
new JavaUrlHttpCommandExecutorServiceModule());
|
||||||
|
|
||||||
processor = injector.getInstance(Key
|
processor = injector.getInstance(Key
|
||||||
.get(new TypeLiteral<JaxrsAnnotationProcessor<PCSConnection>>() {
|
.get(new TypeLiteral<RestAnnotationProcessor<PCSConnection>>() {
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
* under the License.
|
* under the License.
|
||||||
* ====================================================================
|
* ====================================================================
|
||||||
*/
|
*/
|
||||||
package org.jclouds.mezeo.pcs2.binders;
|
package org.jclouds.mezeo.pcs2.decorators;
|
||||||
|
|
||||||
import static org.testng.Assert.assertEquals;
|
import static org.testng.Assert.assertEquals;
|
||||||
|
|
||||||
|
@ -33,17 +33,17 @@ import org.jclouds.http.HttpRequest;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests behavior of {@code ParseFlavorListFromGsonResponseTest}
|
* Tests behavior of {@code AddContainerNameAsXmlEntity}
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
@Test(groups = "unit", testName = "pcs2.CreateContainerBinderTest")
|
@Test(groups = "unit", testName = "pcs2.AddContainerNameAsXmlEntityTest")
|
||||||
public class CreateContainerBinderTest {
|
public class AddContainerNameAsXmlEntityTest {
|
||||||
|
|
||||||
public void test() {
|
public void test() {
|
||||||
CreateContainerBinder binder = new CreateContainerBinder();
|
AddContainerNameAsXmlEntity binder = new AddContainerNameAsXmlEntity();
|
||||||
HttpRequest request = new HttpRequest("GET", URI.create("http://localhost"));
|
HttpRequest request = new HttpRequest("GET", URI.create("http://localhost"));
|
||||||
binder.addEntityToRequest("foo", request);
|
binder.decorateRequest(request, "foo");
|
||||||
assertEquals(request.getEntity(), "<container><name>foo</name></container>");
|
assertEquals(request.getEntity(), "<container><name>foo</name></container>");
|
||||||
assertEquals(request.getFirstHeaderOrNull(HttpHeaders.CONTENT_LENGTH),
|
assertEquals(request.getFirstHeaderOrNull(HttpHeaders.CONTENT_LENGTH),
|
||||||
"<container><name>foo</name></container>".getBytes().length + "");
|
"<container><name>foo</name></container>".getBytes().length + "");
|
|
@ -21,7 +21,7 @@
|
||||||
* under the License.
|
* under the License.
|
||||||
* ====================================================================
|
* ====================================================================
|
||||||
*/
|
*/
|
||||||
package org.jclouds.mezeo.pcs2.binders;
|
package org.jclouds.mezeo.pcs2.decorators;
|
||||||
|
|
||||||
import static org.testng.Assert.assertEquals;
|
import static org.testng.Assert.assertEquals;
|
||||||
|
|
||||||
|
@ -34,18 +34,18 @@ import org.jclouds.mezeo.pcs2.domain.PCSFile;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests behavior of {@code CreateFileBinder}
|
* Tests behavior of {@code AddFileInfoAsXmlEntity}
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
@Test(groups = "unit", testName = "pcs2.CreateFileBinderTest")
|
@Test(groups = "unit", testName = "pcs2.AddFileInfoAsXmlEntityTest")
|
||||||
public class CreateFileBinderTest {
|
public class AddFileInfoAsXmlEntityTest {
|
||||||
|
|
||||||
public void test() {
|
public void test() {
|
||||||
CreateFileBinder binder = new CreateFileBinder();
|
AddFileInfoAsXmlEntity binder = new AddFileInfoAsXmlEntity();
|
||||||
HttpRequest request = new HttpRequest("GET", URI.create("http://localhost"));
|
HttpRequest request = new HttpRequest("GET", URI.create("http://localhost"));
|
||||||
PCSFile file = new PCSFile("foo");
|
PCSFile file = new PCSFile("foo");
|
||||||
binder.addEntityToRequest(file, request);
|
binder.decorateRequest(request, file);
|
||||||
assertEquals(
|
assertEquals(
|
||||||
request.getEntity(),
|
request.getEntity(),
|
||||||
"<file><name>foo</name><mime_type>application/octet-stream</mime_type><public>false</public></file>");
|
"<file><name>foo</name><mime_type>application/octet-stream</mime_type><public>false</public></file>");
|
||||||
|
@ -58,13 +58,12 @@ public class CreateFileBinderTest {
|
||||||
"application/vnd.csp.file-info+xml");
|
"application/vnd.csp.file-info+xml");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void testCompound() {
|
public void testCompound() {
|
||||||
CreateFileBinder binder = new CreateFileBinder();
|
AddFileInfoAsXmlEntity binder = new AddFileInfoAsXmlEntity();
|
||||||
HttpRequest request = new HttpRequest("GET", URI.create("http://localhost"));
|
HttpRequest request = new HttpRequest("GET", URI.create("http://localhost"));
|
||||||
PCSFile file = new PCSFile("subdir/foo");
|
PCSFile file = new PCSFile("subdir/foo");
|
||||||
binder.addEntityToRequest(file, request);
|
binder.decorateRequest(request, file);
|
||||||
assertEquals(
|
assertEquals(
|
||||||
request.getEntity(),
|
request.getEntity(),
|
||||||
"<file><name>foo</name><mime_type>application/octet-stream</mime_type><public>false</public></file>");
|
"<file><name>foo</name><mime_type>application/octet-stream</mime_type><public>false</public></file>");
|
|
@ -38,12 +38,13 @@ import java.util.concurrent.Future;
|
||||||
import javax.ws.rs.ext.RuntimeDelegate;
|
import javax.ws.rs.ext.RuntimeDelegate;
|
||||||
|
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
|
import org.jclouds.blobstore.domain.Key;
|
||||||
import org.jclouds.http.HttpRequest;
|
import org.jclouds.http.HttpRequest;
|
||||||
import org.jclouds.http.HttpResponse;
|
import org.jclouds.http.HttpResponse;
|
||||||
import org.jclouds.http.HttpUtils;
|
import org.jclouds.http.HttpUtils;
|
||||||
import org.jclouds.mezeo.pcs2.PCSUtil;
|
import org.jclouds.mezeo.pcs2.PCSUtil;
|
||||||
import org.jclouds.mezeo.pcs2.domain.PCSFile;
|
import org.jclouds.mezeo.pcs2.domain.PCSFile;
|
||||||
import org.jclouds.rest.RuntimeDelegateImpl;
|
import org.jclouds.rest.internal.RuntimeDelegateImpl;
|
||||||
import org.testng.annotations.BeforeClass;
|
import org.testng.annotations.BeforeClass;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,7 @@ import static org.testng.Assert.assertEquals;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.concurrent.ConcurrentMap;
|
import java.util.concurrent.ConcurrentMap;
|
||||||
|
|
||||||
|
import org.jclouds.blobstore.domain.Key;
|
||||||
import org.jclouds.http.HttpException;
|
import org.jclouds.http.HttpException;
|
||||||
import org.jclouds.http.HttpResponse;
|
import org.jclouds.http.HttpResponse;
|
||||||
import org.jclouds.mezeo.pcs2.domain.FileMetadata;
|
import org.jclouds.mezeo.pcs2.domain.FileMetadata;
|
||||||
|
|
|
@ -28,7 +28,6 @@ import static org.testng.Assert.assertEquals;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
|
||||||
import org.jclouds.http.HttpUtils;
|
import org.jclouds.http.HttpUtils;
|
||||||
import org.jclouds.mezeo.pcs2.functions.Key;
|
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -45,17 +44,4 @@ public class PCSUtilsTest {
|
||||||
.create("http://localhost/contents/7F143552-AAF5-11DE-BBB0-0BC388ED913B"));
|
.create("http://localhost/contents/7F143552-AAF5-11DE-BBB0-0BC388ED913B"));
|
||||||
assertEquals(eTag, expected);
|
assertEquals(eTag, expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testParseKey() {
|
|
||||||
Key key = PCSUtils.parseKey(new Key("container", "key"));
|
|
||||||
assertEquals(key.getContainer(), "container");
|
|
||||||
assertEquals(key.getKey(), "key");
|
|
||||||
key = PCSUtils.parseKey(new Key("container", "container/key"));
|
|
||||||
assertEquals(key.getContainer(), "container/container");
|
|
||||||
assertEquals(key.getKey(), "key");
|
|
||||||
key = PCSUtils.parseKey(new Key("container", "/container/key"));
|
|
||||||
assertEquals(key.getContainer(), "container/container");
|
|
||||||
assertEquals(key.getKey(), "key");
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,7 @@ import javax.ws.rs.Path;
|
||||||
import javax.ws.rs.PathParam;
|
import javax.ws.rs.PathParam;
|
||||||
|
|
||||||
import org.jclouds.blobstore.BlobStore;
|
import org.jclouds.blobstore.BlobStore;
|
||||||
import org.jclouds.blobstore.binders.BlobBinder;
|
import org.jclouds.blobstore.decorators.AddBlobEntity;
|
||||||
import org.jclouds.blobstore.domain.Blob;
|
import org.jclouds.blobstore.domain.Blob;
|
||||||
import org.jclouds.blobstore.domain.BlobMetadata;
|
import org.jclouds.blobstore.domain.BlobMetadata;
|
||||||
import org.jclouds.blobstore.functions.BlobKey;
|
import org.jclouds.blobstore.functions.BlobKey;
|
||||||
|
@ -53,14 +53,14 @@ import org.jclouds.rackspace.cloudfiles.functions.ParseObjectFromHeadersAndHttpC
|
||||||
import org.jclouds.rackspace.cloudfiles.functions.ParseObjectMetadataFromHeaders;
|
import org.jclouds.rackspace.cloudfiles.functions.ParseObjectMetadataFromHeaders;
|
||||||
import org.jclouds.rackspace.cloudfiles.options.ListContainerOptions;
|
import org.jclouds.rackspace.cloudfiles.options.ListContainerOptions;
|
||||||
import org.jclouds.rackspace.filters.AuthenticateRequest;
|
import org.jclouds.rackspace.filters.AuthenticateRequest;
|
||||||
import org.jclouds.rest.Endpoint;
|
import org.jclouds.rest.annotations.DecoratorParam;
|
||||||
import org.jclouds.rest.EntityParam;
|
import org.jclouds.rest.annotations.Endpoint;
|
||||||
import org.jclouds.rest.ExceptionParser;
|
import org.jclouds.rest.annotations.ExceptionParser;
|
||||||
import org.jclouds.rest.ParamParser;
|
import org.jclouds.rest.annotations.ParamParser;
|
||||||
import org.jclouds.rest.QueryParams;
|
import org.jclouds.rest.annotations.QueryParams;
|
||||||
import org.jclouds.rest.RequestFilters;
|
import org.jclouds.rest.annotations.RequestFilters;
|
||||||
import org.jclouds.rest.ResponseParser;
|
import org.jclouds.rest.annotations.ResponseParser;
|
||||||
import org.jclouds.rest.SkipEncoding;
|
import org.jclouds.rest.annotations.SkipEncoding;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides access to Cloud Files via their REST API.
|
* Provides access to Cloud Files via their REST API.
|
||||||
|
@ -113,7 +113,7 @@ public interface CloudFilesBlobStore extends
|
||||||
@ResponseParser(ParseETagHeader.class)
|
@ResponseParser(ParseETagHeader.class)
|
||||||
Future<byte[]> putBlob(
|
Future<byte[]> putBlob(
|
||||||
@PathParam("container") String container,
|
@PathParam("container") String container,
|
||||||
@PathParam("key") @ParamParser(BlobKey.class) @EntityParam(BlobBinder.class) Blob<BlobMetadata> object);
|
@PathParam("key") @ParamParser(BlobKey.class) @DecoratorParam(AddBlobEntity.class) Blob<BlobMetadata> object);
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
@ResponseParser(ParseObjectFromHeadersAndHttpContent.class)
|
@ResponseParser(ParseObjectFromHeadersAndHttpContent.class)
|
||||||
|
|
|
@ -36,8 +36,8 @@ import javax.ws.rs.PUT;
|
||||||
import javax.ws.rs.Path;
|
import javax.ws.rs.Path;
|
||||||
import javax.ws.rs.PathParam;
|
import javax.ws.rs.PathParam;
|
||||||
|
|
||||||
import org.jclouds.blobstore.binders.BlobBinder;
|
import org.jclouds.blobstore.decorators.AddBlobEntity;
|
||||||
import org.jclouds.blobstore.binders.UserMetadataBinder;
|
import org.jclouds.blobstore.decorators.AddHeadersWithPrefix;
|
||||||
import org.jclouds.blobstore.domain.Blob;
|
import org.jclouds.blobstore.domain.Blob;
|
||||||
import org.jclouds.blobstore.domain.BlobMetadata;
|
import org.jclouds.blobstore.domain.BlobMetadata;
|
||||||
import org.jclouds.blobstore.functions.BlobKey;
|
import org.jclouds.blobstore.functions.BlobKey;
|
||||||
|
@ -64,15 +64,15 @@ import org.jclouds.rackspace.cloudfiles.options.ListCdnContainerOptions;
|
||||||
import org.jclouds.rackspace.cloudfiles.options.ListContainerOptions;
|
import org.jclouds.rackspace.cloudfiles.options.ListContainerOptions;
|
||||||
import org.jclouds.rackspace.cloudfiles.reference.CloudFilesHeaders;
|
import org.jclouds.rackspace.cloudfiles.reference.CloudFilesHeaders;
|
||||||
import org.jclouds.rackspace.filters.AuthenticateRequest;
|
import org.jclouds.rackspace.filters.AuthenticateRequest;
|
||||||
import org.jclouds.rest.Endpoint;
|
import org.jclouds.rest.annotations.DecoratorParam;
|
||||||
import org.jclouds.rest.EntityParam;
|
import org.jclouds.rest.annotations.Endpoint;
|
||||||
import org.jclouds.rest.ExceptionParser;
|
import org.jclouds.rest.annotations.ExceptionParser;
|
||||||
import org.jclouds.rest.Headers;
|
import org.jclouds.rest.annotations.Headers;
|
||||||
import org.jclouds.rest.ParamParser;
|
import org.jclouds.rest.annotations.ParamParser;
|
||||||
import org.jclouds.rest.QueryParams;
|
import org.jclouds.rest.annotations.QueryParams;
|
||||||
import org.jclouds.rest.RequestFilters;
|
import org.jclouds.rest.annotations.RequestFilters;
|
||||||
import org.jclouds.rest.ResponseParser;
|
import org.jclouds.rest.annotations.ResponseParser;
|
||||||
import org.jclouds.rest.SkipEncoding;
|
import org.jclouds.rest.annotations.SkipEncoding;
|
||||||
|
|
||||||
import com.google.common.collect.Multimap;
|
import com.google.common.collect.Multimap;
|
||||||
|
|
||||||
|
@ -141,7 +141,7 @@ public interface CloudFilesConnection {
|
||||||
@Path("{container}/{key}")
|
@Path("{container}/{key}")
|
||||||
boolean setObjectMetadata(@PathParam("container") String container,
|
boolean setObjectMetadata(@PathParam("container") String container,
|
||||||
@PathParam("key") String key,
|
@PathParam("key") String key,
|
||||||
@EntityParam(UserMetadataBinder.class) Multimap<String, String> userMetadata);
|
@DecoratorParam(AddHeadersWithPrefix.class) Multimap<String, String> userMetadata);
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
@ResponseParser(ParseContainerCDNMetadataListFromGsonResponse.class)
|
@ResponseParser(ParseContainerCDNMetadataListFromGsonResponse.class)
|
||||||
|
@ -205,7 +205,7 @@ public interface CloudFilesConnection {
|
||||||
@ResponseParser(ParseETagHeader.class)
|
@ResponseParser(ParseETagHeader.class)
|
||||||
Future<byte[]> putObject(
|
Future<byte[]> putObject(
|
||||||
@PathParam("container") String container,
|
@PathParam("container") String container,
|
||||||
@PathParam("key") @ParamParser(BlobKey.class) @EntityParam(BlobBinder.class) Blob<BlobMetadata> object);
|
@PathParam("key") @ParamParser(BlobKey.class) @DecoratorParam(AddBlobEntity.class) Blob<BlobMetadata> object);
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
@ResponseParser(ParseObjectFromHeadersAndHttpContent.class)
|
@ResponseParser(ParseObjectFromHeadersAndHttpContent.class)
|
||||||
|
|
|
@ -21,28 +21,27 @@
|
||||||
* under the License.
|
* under the License.
|
||||||
* ====================================================================
|
* ====================================================================
|
||||||
*/
|
*/
|
||||||
package org.jclouds.rackspace.cloudfiles.binders;
|
package org.jclouds.rackspace.cloudfiles.decorators;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkArgument;
|
import static com.google.common.base.Preconditions.checkArgument;
|
||||||
import static org.jclouds.blobstore.reference.BlobStoreConstants.PROPERTY_USER_METADATA_PREFIX;
|
import static org.jclouds.blobstore.reference.BlobStoreConstants.PROPERTY_USER_METADATA_PREFIX;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Named;
|
||||||
import javax.ws.rs.core.HttpHeaders;
|
import javax.ws.rs.core.HttpHeaders;
|
||||||
|
|
||||||
import org.jclouds.blobstore.binders.BlobBinder;
|
import org.jclouds.blobstore.decorators.AddBlobEntity;
|
||||||
import org.jclouds.blobstore.domain.Blob;
|
import org.jclouds.blobstore.domain.Blob;
|
||||||
import org.jclouds.http.HttpRequest;
|
import org.jclouds.http.HttpRequest;
|
||||||
import org.jclouds.http.HttpUtils;
|
import org.jclouds.http.HttpUtils;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
public class AddCFObjectEntity extends AddBlobEntity {
|
||||||
import javax.inject.Named;
|
|
||||||
|
|
||||||
public class CFObjectBinder extends BlobBinder {
|
|
||||||
@Inject
|
@Inject
|
||||||
public CFObjectBinder(@Named(PROPERTY_USER_METADATA_PREFIX) String metadataPrefix) {
|
public AddCFObjectEntity(@Named(PROPERTY_USER_METADATA_PREFIX) String metadataPrefix) {
|
||||||
super(metadataPrefix);
|
super(metadataPrefix);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addEntityToRequest(Object entity, HttpRequest request) {
|
public HttpRequest decorateRequest(HttpRequest request, Object entity) {
|
||||||
Blob<?> object = (Blob<?>) entity;
|
Blob<?> object = (Blob<?>) entity;
|
||||||
if (object.getMetadata().getSize() >= 0) {
|
if (object.getMetadata().getSize() >= 0) {
|
||||||
checkArgument(object.getContentLength() <= 5 * 1024 * 1024 * 1024,
|
checkArgument(object.getContentLength() <= 5 * 1024 * 1024 * 1024,
|
||||||
|
@ -59,6 +58,6 @@ public class CFObjectBinder extends BlobBinder {
|
||||||
request.getHeaders().put(HttpHeaders.ETAG,
|
request.getHeaders().put(HttpHeaders.ETAG,
|
||||||
HttpUtils.toBase64String(object.getMetadata().getContentMD5()));
|
HttpUtils.toBase64String(object.getMetadata().getContentMD5()));
|
||||||
}
|
}
|
||||||
super.addEntityToRequest(entity, request);
|
return super.decorateRequest(request, entity);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -37,15 +37,15 @@ import javax.ws.rs.PathParam;
|
||||||
|
|
||||||
import org.jclouds.http.functions.ReturnFalseOn404;
|
import org.jclouds.http.functions.ReturnFalseOn404;
|
||||||
import org.jclouds.rackspace.CloudServers;
|
import org.jclouds.rackspace.CloudServers;
|
||||||
import org.jclouds.rackspace.cloudservers.binders.BackupScheduleBinder;
|
import org.jclouds.rackspace.cloudservers.decorators.AddBackupScheduleAsJsonEntity;
|
||||||
import org.jclouds.rackspace.cloudservers.binders.ChangeAdminPassBinder;
|
import org.jclouds.rackspace.cloudservers.decorators.AddAdminPassAsJsonEntity;
|
||||||
import org.jclouds.rackspace.cloudservers.binders.ChangeServerNameBinder;
|
import org.jclouds.rackspace.cloudservers.decorators.AddServerNameAsJsonEntity;
|
||||||
import org.jclouds.rackspace.cloudservers.binders.ConfirmResizeBinder;
|
import org.jclouds.rackspace.cloudservers.decorators.AddConfirmResizeAsJsonEntity;
|
||||||
import org.jclouds.rackspace.cloudservers.binders.CreateImageBinder;
|
import org.jclouds.rackspace.cloudservers.decorators.AddCreateImageAsJsonEntity;
|
||||||
import org.jclouds.rackspace.cloudservers.binders.RebootTypeBinder;
|
import org.jclouds.rackspace.cloudservers.decorators.AddRebootTypeAsJsonEntity;
|
||||||
import org.jclouds.rackspace.cloudservers.binders.ResizeBinder;
|
import org.jclouds.rackspace.cloudservers.decorators.AddResizeFlavorAsJsonEntity;
|
||||||
import org.jclouds.rackspace.cloudservers.binders.RevertResizeBinder;
|
import org.jclouds.rackspace.cloudservers.decorators.AddRevertResizeAsJsonEntity;
|
||||||
import org.jclouds.rackspace.cloudservers.binders.ShareIpBinder;
|
import org.jclouds.rackspace.cloudservers.decorators.AddSharedIpGroupAsJsonEntity;
|
||||||
import org.jclouds.rackspace.cloudservers.domain.Addresses;
|
import org.jclouds.rackspace.cloudservers.domain.Addresses;
|
||||||
import org.jclouds.rackspace.cloudservers.domain.BackupSchedule;
|
import org.jclouds.rackspace.cloudservers.domain.BackupSchedule;
|
||||||
import org.jclouds.rackspace.cloudservers.domain.Flavor;
|
import org.jclouds.rackspace.cloudservers.domain.Flavor;
|
||||||
|
@ -74,16 +74,16 @@ import org.jclouds.rackspace.cloudservers.options.CreateSharedIpGroupOptions;
|
||||||
import org.jclouds.rackspace.cloudservers.options.ListOptions;
|
import org.jclouds.rackspace.cloudservers.options.ListOptions;
|
||||||
import org.jclouds.rackspace.cloudservers.options.RebuildServerOptions;
|
import org.jclouds.rackspace.cloudservers.options.RebuildServerOptions;
|
||||||
import org.jclouds.rackspace.filters.AuthenticateRequest;
|
import org.jclouds.rackspace.filters.AuthenticateRequest;
|
||||||
import org.jclouds.rest.Endpoint;
|
import org.jclouds.rest.annotations.DecoratorParam;
|
||||||
import org.jclouds.rest.EntityParam;
|
import org.jclouds.rest.annotations.Endpoint;
|
||||||
import org.jclouds.rest.ExceptionParser;
|
import org.jclouds.rest.annotations.ExceptionParser;
|
||||||
import org.jclouds.rest.MapBinder;
|
import org.jclouds.rest.annotations.MapBinder;
|
||||||
import org.jclouds.rest.MapEntityParam;
|
import org.jclouds.rest.annotations.MapEntityParam;
|
||||||
import org.jclouds.rest.ParamParser;
|
import org.jclouds.rest.annotations.ParamParser;
|
||||||
import org.jclouds.rest.QueryParams;
|
import org.jclouds.rest.annotations.QueryParams;
|
||||||
import org.jclouds.rest.RequestFilters;
|
import org.jclouds.rest.annotations.RequestFilters;
|
||||||
import org.jclouds.rest.ResponseParser;
|
import org.jclouds.rest.annotations.ResponseParser;
|
||||||
import org.jclouds.rest.SkipEncoding;
|
import org.jclouds.rest.annotations.SkipEncoding;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides access to Cloud Servers via their REST API.
|
* Provides access to Cloud Servers via their REST API.
|
||||||
|
@ -170,7 +170,7 @@ public interface CloudServersConnection {
|
||||||
// TODO:cloudServersFault (400, 500), serviceUnavailable (503), unauthorized (401), badRequest
|
// TODO:cloudServersFault (400, 500), serviceUnavailable (503), unauthorized (401), badRequest
|
||||||
// (400), badMediaType(415),buildInProgress (409), overLimit (403)
|
// (400), badMediaType(415),buildInProgress (409), overLimit (403)
|
||||||
boolean rebootServer(@PathParam("id") int id,
|
boolean rebootServer(@PathParam("id") int id,
|
||||||
@EntityParam(RebootTypeBinder.class) RebootType rebootType);
|
@DecoratorParam(AddRebootTypeAsJsonEntity.class) RebootType rebootType);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The resize function converts an existing server to a different flavor, in essence, scaling the
|
* The resize function converts an existing server to a different flavor, in essence, scaling the
|
||||||
|
@ -192,7 +192,7 @@ public interface CloudServersConnection {
|
||||||
// TODO:cloudServersFault (400, 500), serviceUnavailable (503), unauthorized (401), badRequest
|
// TODO:cloudServersFault (400, 500), serviceUnavailable (503), unauthorized (401), badRequest
|
||||||
// (400), badMediaType(415), itemNotFound (404), buildInProgress (409), serverCapacityUnavailable
|
// (400), badMediaType(415), itemNotFound (404), buildInProgress (409), serverCapacityUnavailable
|
||||||
// (503), overLimit (413), resizeNotAllowed (403)
|
// (503), overLimit (413), resizeNotAllowed (403)
|
||||||
boolean resizeServer(@PathParam("id") int id, @EntityParam(ResizeBinder.class) int flavorId);
|
boolean resizeServer(@PathParam("id") int id, @DecoratorParam(AddResizeFlavorAsJsonEntity.class) int flavorId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The resize function converts an existing server to a different flavor, in essence, scaling the
|
* The resize function converts an existing server to a different flavor, in essence, scaling the
|
||||||
|
@ -212,7 +212,7 @@ public interface CloudServersConnection {
|
||||||
// TODO:cloudServersFault (400, 500), serviceUnavailable (503), unauthorized (401), badRequest
|
// TODO:cloudServersFault (400, 500), serviceUnavailable (503), unauthorized (401), badRequest
|
||||||
// (400), badMediaType(415), itemNotFound (404), buildInProgress (409), serverCapacityUnavailable
|
// (400), badMediaType(415), itemNotFound (404), buildInProgress (409), serverCapacityUnavailable
|
||||||
// (503), overLimit (413), resizeNotAllowed (403)
|
// (503), overLimit (413), resizeNotAllowed (403)
|
||||||
boolean confirmResizeServer(@PathParam("id") @EntityParam(ConfirmResizeBinder.class) int id);
|
boolean confirmResizeServer(@PathParam("id") @DecoratorParam(AddConfirmResizeAsJsonEntity.class) int id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The resize function converts an existing server to a different flavor, in essence, scaling the
|
* The resize function converts an existing server to a different flavor, in essence, scaling the
|
||||||
|
@ -232,7 +232,7 @@ public interface CloudServersConnection {
|
||||||
// TODO:cloudServersFault (400, 500), serviceUnavailable (503), unauthorized (401), badRequest
|
// TODO:cloudServersFault (400, 500), serviceUnavailable (503), unauthorized (401), badRequest
|
||||||
// (400), badMediaType(415), itemNotFound (404), buildInProgress (409), serverCapacityUnavailable
|
// (400), badMediaType(415), itemNotFound (404), buildInProgress (409), serverCapacityUnavailable
|
||||||
// (503), overLimit (413), resizeNotAllowed (403)
|
// (503), overLimit (413), resizeNotAllowed (403)
|
||||||
boolean revertResizeServer(@PathParam("id") @EntityParam(RevertResizeBinder.class) int id);
|
boolean revertResizeServer(@PathParam("id") @DecoratorParam(AddRevertResizeAsJsonEntity.class) int id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This operation asynchronously provisions a new server. The progress of this operation depends
|
* This operation asynchronously provisions a new server. The progress of this operation depends
|
||||||
|
@ -304,7 +304,7 @@ public interface CloudServersConnection {
|
||||||
@PUT
|
@PUT
|
||||||
@ExceptionParser(ReturnFalseOn404.class)
|
@ExceptionParser(ReturnFalseOn404.class)
|
||||||
@Path("/servers/{id}/ips/public/{address}")
|
@Path("/servers/{id}/ips/public/{address}")
|
||||||
@MapBinder(ShareIpBinder.class)
|
@MapBinder(AddSharedIpGroupAsJsonEntity.class)
|
||||||
// TODO: cloudServersFault (400, 500), serviceUnavailable (503), unauthorized (401), badRequest
|
// TODO: cloudServersFault (400, 500), serviceUnavailable (503), unauthorized (401), badRequest
|
||||||
// (400), badMediaType(415), buildInProgress (409), overLimit (413)
|
// (400), badMediaType(415), buildInProgress (409), overLimit (413)
|
||||||
boolean shareIp(@PathParam("address") @ParamParser(IpAddress.class) InetAddress addressToShare,
|
boolean shareIp(@PathParam("address") @ParamParser(IpAddress.class) InetAddress addressToShare,
|
||||||
|
@ -344,7 +344,7 @@ public interface CloudServersConnection {
|
||||||
// TODO: cloudServersFault (400, 500), serviceUnavailable (503), unauthorized (401), badRequest
|
// TODO: cloudServersFault (400, 500), serviceUnavailable (503), unauthorized (401), badRequest
|
||||||
// (400), badMediaType(415), buildInProgress (409), overLimit (413)
|
// (400), badMediaType(415), buildInProgress (409), overLimit (413)
|
||||||
boolean changeAdminPass(@PathParam("id") int id,
|
boolean changeAdminPass(@PathParam("id") int id,
|
||||||
@EntityParam(ChangeAdminPassBinder.class) String adminPass);
|
@DecoratorParam(AddAdminPassAsJsonEntity.class) String adminPass);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This operation allows you to update the name of the server. This operation changes the name of
|
* This operation allows you to update the name of the server. This operation changes the name of
|
||||||
|
@ -360,7 +360,7 @@ public interface CloudServersConnection {
|
||||||
// TODO: cloudServersFault (400, 500), serviceUnavailable (503), unauthorized (401), badRequest
|
// TODO: cloudServersFault (400, 500), serviceUnavailable (503), unauthorized (401), badRequest
|
||||||
// (400), badMediaType(415), buildInProgress (409), overLimit (413)
|
// (400), badMediaType(415), buildInProgress (409), overLimit (413)
|
||||||
boolean renameServer(@PathParam("id") int id,
|
boolean renameServer(@PathParam("id") int id,
|
||||||
@EntityParam(ChangeServerNameBinder.class) String newName);
|
@DecoratorParam(AddServerNameAsJsonEntity.class) String newName);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -447,7 +447,7 @@ public interface CloudServersConnection {
|
||||||
@ResponseParser(ParseImageFromJsonResponse.class)
|
@ResponseParser(ParseImageFromJsonResponse.class)
|
||||||
@QueryParams(keys = "format", values = "json")
|
@QueryParams(keys = "format", values = "json")
|
||||||
@ExceptionParser(ReturnImageNotFoundOn404.class)
|
@ExceptionParser(ReturnImageNotFoundOn404.class)
|
||||||
@MapBinder(CreateImageBinder.class)
|
@MapBinder(AddCreateImageAsJsonEntity.class)
|
||||||
@Path("/images")
|
@Path("/images")
|
||||||
// TODO: cloudServersFault (400, 500), serviceUnavailable (503), unauthorized (401), badRequest
|
// TODO: cloudServersFault (400, 500), serviceUnavailable (503), unauthorized (401), badRequest
|
||||||
// (400), badMediaType(415), buildInProgress (409), serverCapacityUnavailable (503), overLimit
|
// (400), badMediaType(415), buildInProgress (409), serverCapacityUnavailable (503), overLimit
|
||||||
|
@ -554,7 +554,7 @@ public interface CloudServersConnection {
|
||||||
// (400), badMediaType(415), buildInProgress (409), serverCapacityUnavailable (503),
|
// (400), badMediaType(415), buildInProgress (409), serverCapacityUnavailable (503),
|
||||||
// backupOrResizeInProgress(409), resizeNotAllowed (403). overLimit (413)
|
// backupOrResizeInProgress(409), resizeNotAllowed (403). overLimit (413)
|
||||||
boolean replaceBackupSchedule(@PathParam("id") int id,
|
boolean replaceBackupSchedule(@PathParam("id") int id,
|
||||||
@EntityParam(BackupScheduleBinder.class) BackupSchedule backupSchedule);
|
@DecoratorParam(AddBackupScheduleAsJsonEntity.class) BackupSchedule backupSchedule);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* List all server addresses
|
* List all server addresses
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
* under the License.
|
* under the License.
|
||||||
* ====================================================================
|
* ====================================================================
|
||||||
*/
|
*/
|
||||||
package org.jclouds.rackspace.cloudservers.binders;
|
package org.jclouds.rackspace.cloudservers.decorators;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkArgument;
|
import static com.google.common.base.Preconditions.checkArgument;
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
@ -29,7 +29,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.jclouds.http.HttpRequest;
|
import org.jclouds.http.HttpRequest;
|
||||||
import org.jclouds.rest.binders.JsonBinder;
|
import org.jclouds.rest.decorators.AddAsJsonEntity;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
|
||||||
|
@ -38,17 +38,17 @@ import com.google.common.collect.ImmutableMap;
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class ChangeAdminPassBinder extends JsonBinder {
|
public class AddAdminPassAsJsonEntity extends AddAsJsonEntity {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addEntityToRequest(Map<String, String> postParams, HttpRequest request) {
|
public HttpRequest decorateRequest(HttpRequest request, Map<String, String> postParams) {
|
||||||
throw new IllegalStateException("Change Admin Pass is a PUT operation");
|
throw new IllegalStateException("Change Admin Pass is a PUT operation");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addEntityToRequest(Object toBind, HttpRequest request) {
|
public HttpRequest decorateRequest(HttpRequest request, Object toBind) {
|
||||||
checkArgument(toBind instanceof String, "this binder is only valid for Strings!");
|
checkArgument(toBind instanceof String, "this binder is only valid for Strings!");
|
||||||
super.addEntityToRequest(ImmutableMap.of("server", ImmutableMap.of("adminPass", checkNotNull(
|
return super.decorateRequest(request, ImmutableMap.of("server", ImmutableMap.of("adminPass",
|
||||||
toBind, "adminPass"))), request);
|
checkNotNull(toBind, "adminPass"))));
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -21,15 +21,15 @@
|
||||||
* under the License.
|
* under the License.
|
||||||
* ====================================================================
|
* ====================================================================
|
||||||
*/
|
*/
|
||||||
package org.jclouds.rackspace.cloudservers.binders;
|
package org.jclouds.rackspace.cloudservers.decorators;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkArgument;
|
import static com.google.common.base.Preconditions.checkArgument;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.jclouds.http.HttpRequest;
|
import org.jclouds.http.HttpRequest;
|
||||||
import org.jclouds.rest.binders.JsonBinder;
|
|
||||||
import org.jclouds.rackspace.cloudservers.domain.BackupSchedule;
|
import org.jclouds.rackspace.cloudservers.domain.BackupSchedule;
|
||||||
|
import org.jclouds.rest.decorators.AddAsJsonEntity;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
|
||||||
|
@ -38,18 +38,18 @@ import com.google.common.collect.ImmutableMap;
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class BackupScheduleBinder extends JsonBinder {
|
public class AddBackupScheduleAsJsonEntity extends AddAsJsonEntity {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addEntityToRequest(Map<String, String> postParams, HttpRequest request) {
|
public HttpRequest decorateRequest(HttpRequest request, Map<String, String> postParams) {
|
||||||
throw new IllegalStateException(
|
throw new IllegalStateException(
|
||||||
"Replace Backup Schedule needs an BackupSchedule object, not a Map");
|
"Replace Backup Schedule needs an BackupSchedule object, not a Map");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addEntityToRequest(Object toBind, HttpRequest request) {
|
public HttpRequest decorateRequest(HttpRequest request, Object toBind) {
|
||||||
checkArgument(toBind instanceof BackupSchedule,
|
checkArgument(toBind instanceof BackupSchedule,
|
||||||
"this binder is only valid for BackupSchedules!");
|
"this binder is only valid for BackupSchedules!");
|
||||||
super.addEntityToRequest(ImmutableMap.of("backupSchedule", toBind), request);
|
return super.decorateRequest(request, ImmutableMap.of("backupSchedule", toBind));
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -21,7 +21,7 @@
|
||||||
* under the License.
|
* under the License.
|
||||||
* ====================================================================
|
* ====================================================================
|
||||||
*/
|
*/
|
||||||
package org.jclouds.rackspace.cloudservers.binders;
|
package org.jclouds.rackspace.cloudservers.decorators;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
|
||||||
|
@ -29,20 +29,21 @@ import javax.ws.rs.core.HttpHeaders;
|
||||||
import javax.ws.rs.core.MediaType;
|
import javax.ws.rs.core.MediaType;
|
||||||
|
|
||||||
import org.jclouds.http.HttpRequest;
|
import org.jclouds.http.HttpRequest;
|
||||||
import org.jclouds.rest.binders.EntityBinder;
|
import org.jclouds.rest.decorators.RequestDecorator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class ConfirmResizeBinder implements EntityBinder {
|
public class AddConfirmResizeAsJsonEntity implements RequestDecorator {
|
||||||
|
|
||||||
public void addEntityToRequest(Object toBind, HttpRequest request) {
|
public HttpRequest decorateRequest(HttpRequest request, Object toBind) {
|
||||||
request.setEntity("{\"confirmResize\":null}");
|
request.setEntity("{\"confirmResize\":null}");
|
||||||
request.getHeaders().replaceValues(HttpHeaders.CONTENT_LENGTH,
|
request.getHeaders().replaceValues(HttpHeaders.CONTENT_LENGTH,
|
||||||
Collections.singletonList("{\"confirmResize\":null}".getBytes().length + ""));
|
Collections.singletonList("{\"confirmResize\":null}".getBytes().length + ""));
|
||||||
request.getHeaders().replaceValues(HttpHeaders.CONTENT_TYPE,
|
request.getHeaders().replaceValues(HttpHeaders.CONTENT_TYPE,
|
||||||
Collections.singletonList(MediaType.APPLICATION_JSON));
|
Collections.singletonList(MediaType.APPLICATION_JSON));
|
||||||
|
return request;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -21,14 +21,14 @@
|
||||||
* under the License.
|
* under the License.
|
||||||
* ====================================================================
|
* ====================================================================
|
||||||
*/
|
*/
|
||||||
package org.jclouds.rackspace.cloudservers.binders;
|
package org.jclouds.rackspace.cloudservers.decorators;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.jclouds.http.HttpRequest;
|
import org.jclouds.http.HttpRequest;
|
||||||
import org.jclouds.rest.binders.JsonBinder;
|
import org.jclouds.rest.decorators.AddAsJsonEntity;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ import com.google.common.collect.ImmutableMap;
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class CreateImageBinder extends JsonBinder {
|
public class AddCreateImageAsJsonEntity extends AddAsJsonEntity {
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
private class CreateImageRequest {
|
private class CreateImageRequest {
|
||||||
|
@ -52,15 +52,15 @@ public class CreateImageBinder extends JsonBinder {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addEntityToRequest(Map<String, String> postParams, HttpRequest request) {
|
public HttpRequest decorateRequest(HttpRequest request, Map<String, String> postParams) {
|
||||||
CreateImageRequest createRequest = new CreateImageRequest(Integer
|
CreateImageRequest createRequest = new CreateImageRequest(Integer
|
||||||
.parseInt(checkNotNull(postParams.get("serverId"))), checkNotNull(postParams
|
.parseInt(checkNotNull(postParams.get("serverId"))), checkNotNull(postParams
|
||||||
.get("imageName")));
|
.get("imageName")));
|
||||||
super.addEntityToRequest(ImmutableMap.of("image", createRequest), request);
|
return super.decorateRequest(request, ImmutableMap.of("image", createRequest));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addEntityToRequest(Object toBind, HttpRequest request) {
|
public HttpRequest decorateRequest(HttpRequest request, Object toBind) {
|
||||||
throw new IllegalArgumentException("image is needs parameters");
|
throw new IllegalArgumentException("image is needs parameters");
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -21,7 +21,7 @@
|
||||||
* under the License.
|
* under the License.
|
||||||
* ====================================================================
|
* ====================================================================
|
||||||
*/
|
*/
|
||||||
package org.jclouds.rackspace.cloudservers.binders;
|
package org.jclouds.rackspace.cloudservers.decorators;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkArgument;
|
import static com.google.common.base.Preconditions.checkArgument;
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
@ -29,8 +29,8 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.jclouds.http.HttpRequest;
|
import org.jclouds.http.HttpRequest;
|
||||||
import org.jclouds.rest.binders.JsonBinder;
|
|
||||||
import org.jclouds.rackspace.cloudservers.domain.RebootType;
|
import org.jclouds.rackspace.cloudservers.domain.RebootType;
|
||||||
|
import org.jclouds.rest.decorators.AddAsJsonEntity;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
|
||||||
|
@ -39,17 +39,17 @@ import com.google.common.collect.ImmutableMap;
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class RebootTypeBinder extends JsonBinder {
|
public class AddRebootTypeAsJsonEntity extends AddAsJsonEntity {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addEntityToRequest(Map<String, String> postParams, HttpRequest request) {
|
public HttpRequest decorateRequest(HttpRequest request, Map<String, String> postParams) {
|
||||||
throw new IllegalStateException("Reboot doesn't take map parameters");
|
throw new IllegalStateException("Reboot doesn't take map parameters");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addEntityToRequest(Object toBind, HttpRequest request) {
|
public HttpRequest decorateRequest(HttpRequest request, Object toBind) {
|
||||||
checkArgument(toBind instanceof RebootType, "this binder is only valid for RebootTypes!");
|
checkArgument(toBind instanceof RebootType, "this binder is only valid for RebootTypes!");
|
||||||
super.addEntityToRequest(ImmutableMap.of("reboot", ImmutableMap.of("type", checkNotNull(
|
return super.decorateRequest(request, ImmutableMap.of("reboot", ImmutableMap.of("type",
|
||||||
toBind, "type"))), request);
|
checkNotNull(toBind, "type"))));
|
||||||
}
|
}
|
||||||
}
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue