JCLOUDS-150 add SubmissionAsyncBlobStore; unasync s3 and aws-s3
Project: http://git-wip-us.apache.org/repos/asf/jclouds/repo Commit: http://git-wip-us.apache.org/repos/asf/jclouds/commit/b6497556 Tree: http://git-wip-us.apache.org/repos/asf/jclouds/tree/b6497556 Diff: http://git-wip-us.apache.org/repos/asf/jclouds/diff/b6497556 Branch: refs/heads/use-agentproxy-008 Commit: b6497556f69d07d87280bd8c38b79da384f79e04 Parents: 80d51f4 Author: Adrian Cole <[email protected]> Authored: Fri Oct 3 13:14:00 2014 -0700 Committer: Adrian Cole <[email protected]> Committed: Fri Oct 3 13:18:29 2014 -0700 ---------------------------------------------------------------------- .../main/java/org/jclouds/s3/S3ApiMetadata.java | 40 +- .../main/java/org/jclouds/s3/S3AsyncClient.java | 363 -------------- .../src/main/java/org/jclouds/s3/S3Client.java | 356 +++++++++----- .../jclouds/s3/blobstore/S3AsyncBlobStore.java | 273 ----------- .../s3/blobstore/S3BlobRequestSigner.java | 4 +- .../s3/blobstore/S3BlobStoreContext.java | 3 - .../config/S3BlobStoreContextModule.java | 11 +- .../internal/S3BlobStoreContextImpl.java | 7 - .../org/jclouds/s3/config/S3HttpApiModule.java | 211 ++++++++ .../jclouds/s3/config/S3RestClientModule.java | 214 -------- .../jclouds/s3/domain/AccessControlList.java | 3 - .../org/jclouds/s3/domain/BucketLogging.java | 2 - .../jclouds/s3/domain/CannedAccessPolicy.java | 3 - .../org/jclouds/s3/domain/CanonicalUser.java | 5 +- .../jclouds/s3/domain/ListBucketResponse.java | 2 - .../s3/domain/MutableObjectMetadata.java | 14 +- .../org/jclouds/s3/domain/ObjectMetadata.java | 4 - .../main/java/org/jclouds/s3/domain/Payer.java | 3 - .../java/org/jclouds/s3/domain/S3Object.java | 5 +- .../org/jclouds/s3/domain/package-info.java | 1 - .../s3/filters/RequestAuthorizeSignature.java | 4 - .../org/jclouds/s3/filters/package-info.java | 1 - .../ParseObjectMetadataFromHeaders.java | 12 +- .../jclouds/s3/options/CopyObjectOptions.java | 6 - .../jclouds/s3/options/ListBucketOptions.java | 6 +- .../jclouds/s3/options/PutBucketOptions.java | 6 +- .../jclouds/s3/options/PutObjectOptions.java | 6 +- .../org/jclouds/s3/options/package-info.java | 2 - .../main/java/org/jclouds/s3/package-info.java | 2 - .../org/jclouds/s3/reference/S3Headers.java | 8 +- .../s3/xml/AccessControlListHandler.java | 2 - .../jclouds/s3/xml/BucketLoggingHandler.java | 2 - .../org/jclouds/s3/xml/CopyObjectHandler.java | 2 - .../jclouds/s3/xml/ListAllMyBucketsHandler.java | 4 - .../org/jclouds/s3/xml/ListBucketHandler.java | 4 - .../s3/xml/LocationConstraintHandler.java | 4 - .../java/org/jclouds/s3/xml/PayerHandler.java | 2 - .../java/org/jclouds/s3/S3AsyncClientTest.java | 490 ------------------- .../java/org/jclouds/s3/S3ClientLiveTest.java | 8 +- .../test/java/org/jclouds/s3/S3ClientTest.java | 490 +++++++++++++++++++ .../BindAsHostPrefixIfConfiguredNoPathTest.java | 8 +- .../BindAsHostPrefixIfConfiguredTest.java | 8 +- .../BindNoBucketLoggingToXmlPayloadTest.java | 6 +- .../BindS3ObjectMetadataToRequestTest.java | 6 +- .../s3/blobstore/S3BlobSignerExpectTest.java | 11 +- .../filters/RequestAuthorizeSignatureTest.java | 16 +- ...rizeSignatureWithSessionCredentialsTest.java | 13 +- .../s3/internal/BaseS3AsyncClientTest.java | 62 --- .../s3/internal/BaseS3ClientExpectTest.java | 11 +- .../jclouds/s3/internal/BaseS3ClientTest.java | 62 +++ .../jclouds/s3/internal/StubS3AsyncClient.java | 343 ------------- .../jclouds/s3/services/BucketsLiveTest.java | 63 +-- .../internal/SubmissionAsyncBlobStore.java | 293 +++++++++++ .../org/jclouds/aws/s3/AWSS3ApiMetadata.java | 22 +- .../org/jclouds/aws/s3/AWSS3AsyncClient.java | 135 ----- .../java/org/jclouds/aws/s3/AWSS3Client.java | 88 +++- .../aws/s3/blobstore/AWSS3AsyncBlobStore.java | 139 ------ .../s3/blobstore/AWSS3BlobRequestSigner.java | 6 +- .../aws/s3/blobstore/AWSS3BlobStore.java | 4 +- .../aws/s3/blobstore/AWSS3BlobStoreContext.java | 3 - .../config/AWSS3BlobStoreContextModule.java | 3 - .../internal/AWSS3BlobStoreContextImpl.java | 7 - .../strategy/AsyncMultipartUploadStrategy.java | 3 - .../s3/blobstore/strategy/MultipartUpload.java | 3 - .../strategy/MultipartUploadStrategy.java | 3 - .../ParallelMultipartUploadStrategy.java | 31 +- .../aws/s3/config/AWSS3HttpApiModule.java | 69 +++ .../aws/s3/config/AWSS3RestClientModule.java | 78 --- .../org/jclouds/aws/s3/domain/DeleteResult.java | 12 +- .../filters/AWSRequestAuthorizeSignature.java | 8 +- .../jclouds/aws/s3/filters/package-info.java | 5 +- .../functions/ETagFromHttpResponseViaRegex.java | 3 - .../UploadIdFromHttpResponseViaRegex.java | 5 - .../jclouds/aws/s3/xml/DeleteResultHandler.java | 7 +- .../jclouds/aws/s3/xml/ErrorEntryHandler.java | 9 +- .../jclouds/aws/s3/AWSS3AsyncClientTest.java | 308 ------------ .../org/jclouds/aws/s3/AWSS3ClientLiveTest.java | 4 +- .../org/jclouds/aws/s3/AWSS3ClientTest.java | 307 ++++++++++++ ...indIterableAsPayloadToDeleteRequestTest.java | 11 +- .../BindObjectMetadataToRequestTest.java | 6 +- .../s3/blobstore/AWSS3BlobSignerExpectTest.java | 10 +- .../s3/internal/BaseAWSS3ClientExpectTest.java | 10 +- .../aws/s3/xml/DeleteResultHandlerTest.java | 8 +- 83 files changed, 1930 insertions(+), 2864 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/jclouds/blob/b6497556/apis/s3/src/main/java/org/jclouds/s3/S3ApiMetadata.java ---------------------------------------------------------------------- diff --git a/apis/s3/src/main/java/org/jclouds/s3/S3ApiMetadata.java b/apis/s3/src/main/java/org/jclouds/s3/S3ApiMetadata.java index 5e6fd0b..2923c15 100644 --- a/apis/s3/src/main/java/org/jclouds/s3/S3ApiMetadata.java +++ b/apis/s3/src/main/java/org/jclouds/s3/S3ApiMetadata.java @@ -29,14 +29,14 @@ import java.net.URI; import java.util.Properties; import org.jclouds.apis.ApiMetadata; +import org.jclouds.rest.internal.BaseHttpApiMetadata; import org.jclouds.rest.internal.BaseRestApiMetadata; import org.jclouds.s3.blobstore.S3BlobStoreContext; import org.jclouds.s3.blobstore.config.S3BlobStoreContextModule; -import org.jclouds.s3.config.S3RestClientModule; +import org.jclouds.s3.config.S3HttpApiModule; import org.jclouds.s3.reference.S3Headers; import com.google.common.collect.ImmutableSet; -import com.google.common.reflect.TypeToken; import com.google.inject.Module; /** @@ -44,9 +44,8 @@ import com.google.inject.Module; * * <h3>note</h3> * <p/> - * This class allows overriding of types {@code S}(client) and {@code A} - * (asyncClient), so that children can add additional methods not declared here, - * such as new features from AWS. + * This class allows overriding of types {@code A}(api), so that children can + * add additional methods not declared here, such as new features from AWS. * <p/> * * As this is a popular api, we also allow overrides for type {@code C} @@ -54,19 +53,10 @@ import com.google.inject.Module; * not present in the base api. For example, you could make a subtype for * context, that exposes admin operations. */ -public class S3ApiMetadata extends BaseRestApiMetadata { - - /** - * @deprecated please use {@code org.jclouds.ContextBuilder#buildClient(S3Client.class)} as - * {@link S3AsyncClient} interface will be removed in jclouds 1.7. - */ - @Deprecated - public static final TypeToken<org.jclouds.rest.RestContext<? extends S3Client, ? extends S3AsyncClient>> CONTEXT_TOKEN = new TypeToken<org.jclouds.rest.RestContext<? extends S3Client, ? extends S3AsyncClient>>() { - private static final long serialVersionUID = 1L; - }; +public class S3ApiMetadata extends BaseHttpApiMetadata { @Override - public Builder<?> toBuilder() { + public Builder<?, ?> toBuilder() { return new ConcreteBuilder().fromApiMetadata(this); } @@ -74,7 +64,7 @@ public class S3ApiMetadata extends BaseRestApiMetadata { this(new ConcreteBuilder()); } - protected S3ApiMetadata(Builder<?> builder) { + protected S3ApiMetadata(Builder<?, ?> builder) { super(builder); } @@ -90,14 +80,15 @@ public class S3ApiMetadata extends BaseRestApiMetadata { return properties; } - public abstract static class Builder<T extends Builder<T>> extends BaseRestApiMetadata.Builder<T> { - @SuppressWarnings("deprecation") + public abstract static class Builder<A extends S3Client, T extends Builder<A, T>> extends + BaseHttpApiMetadata.Builder<A, T> { + protected Builder() { - this(S3Client.class, S3AsyncClient.class); + this(Class.class.cast(S3Client.class)); } - protected Builder(Class<?> syncClient, Class<?> asyncClient) { - super(syncClient, asyncClient); + protected Builder(Class<A> syncClient) { + super(syncClient); id("s3") .name("Amazon Simple Storage Service (S3) API") .identityName("Access Key ID") @@ -106,9 +97,8 @@ public class S3ApiMetadata extends BaseRestApiMetadata { .documentation(URI.create("http://docs.amazonwebservices.com/AmazonS3/latest/API")) .version("2006-03-01") .defaultProperties(S3ApiMetadata.defaultProperties()) - .context(CONTEXT_TOKEN) .view(typeToken(S3BlobStoreContext.class)) - .defaultModules(ImmutableSet.<Class<? extends Module>>of(S3RestClientModule.class, S3BlobStoreContextModule.class)); + .defaultModules(ImmutableSet.<Class<? extends Module>>of(S3HttpApiModule.class, S3BlobStoreContextModule.class)); } @Override @@ -117,7 +107,7 @@ public class S3ApiMetadata extends BaseRestApiMetadata { } } - private static class ConcreteBuilder extends Builder<ConcreteBuilder> { + private static class ConcreteBuilder extends Builder<S3Client, ConcreteBuilder> { @Override protected ConcreteBuilder self() { return this; http://git-wip-us.apache.org/repos/asf/jclouds/blob/b6497556/apis/s3/src/main/java/org/jclouds/s3/S3AsyncClient.java ---------------------------------------------------------------------- diff --git a/apis/s3/src/main/java/org/jclouds/s3/S3AsyncClient.java b/apis/s3/src/main/java/org/jclouds/s3/S3AsyncClient.java deleted file mode 100644 index f119461..0000000 --- a/apis/s3/src/main/java/org/jclouds/s3/S3AsyncClient.java +++ /dev/null @@ -1,363 +0,0 @@ -/* - * 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.s3; - -import static com.google.common.net.HttpHeaders.EXPECT; -import static org.jclouds.blobstore.attr.BlobScopes.CONTAINER; - -import java.io.Closeable; -import java.util.Set; - -import javax.inject.Named; -import javax.ws.rs.DELETE; -import javax.ws.rs.GET; -import javax.ws.rs.HEAD; -import javax.ws.rs.PUT; -import javax.ws.rs.Path; -import javax.ws.rs.PathParam; -import javax.ws.rs.Produces; -import javax.ws.rs.core.MediaType; - -import org.jclouds.Fallbacks.VoidOnNotFoundOr404; -import org.jclouds.blobstore.BlobStoreFallbacks.FalseOnContainerNotFound; -import org.jclouds.blobstore.BlobStoreFallbacks.FalseOnKeyNotFound; -import org.jclouds.blobstore.BlobStoreFallbacks.NullOnKeyNotFound; -import org.jclouds.blobstore.BlobStoreFallbacks.ThrowContainerNotFoundOn404; -import org.jclouds.blobstore.BlobStoreFallbacks.ThrowKeyNotFoundOn404; -import org.jclouds.blobstore.attr.BlobScope; -import org.jclouds.http.functions.ParseETagHeader; -import org.jclouds.http.options.GetOptions; -import org.jclouds.javax.annotation.Nullable; -import org.jclouds.rest.annotations.BinderParam; -import org.jclouds.rest.annotations.Endpoint; -import org.jclouds.rest.annotations.EndpointParam; -import org.jclouds.rest.annotations.Fallback; -import org.jclouds.rest.annotations.Headers; -import org.jclouds.rest.annotations.ParamParser; -import org.jclouds.rest.annotations.ParamValidators; -import org.jclouds.rest.annotations.QueryParams; -import org.jclouds.rest.annotations.RequestFilters; -import org.jclouds.rest.annotations.ResponseParser; -import org.jclouds.rest.annotations.VirtualHost; -import org.jclouds.rest.annotations.XMLResponseParser; -import org.jclouds.s3.S3Fallbacks.TrueOn404OrNotFoundFalseOnIllegalState; -import org.jclouds.s3.binders.BindACLToXMLPayload; -import org.jclouds.s3.binders.BindAsHostPrefixIfConfigured; -import org.jclouds.s3.binders.BindBucketLoggingToXmlPayload; -import org.jclouds.s3.binders.BindNoBucketLoggingToXmlPayload; -import org.jclouds.s3.binders.BindPayerToXmlPayload; -import org.jclouds.s3.binders.BindS3ObjectMetadataToRequest; -import org.jclouds.s3.domain.AccessControlList; -import org.jclouds.s3.domain.BucketLogging; -import org.jclouds.s3.domain.BucketMetadata; -import org.jclouds.s3.domain.ListBucketResponse; -import org.jclouds.s3.domain.ObjectMetadata; -import org.jclouds.s3.domain.Payer; -import org.jclouds.s3.domain.S3Object; -import org.jclouds.s3.fallbacks.FalseIfBucketAlreadyOwnedByYouOrOperationAbortedWhenBucketExists; -import org.jclouds.s3.filters.RequestAuthorizeSignature; -import org.jclouds.s3.functions.AssignCorrectHostnameForBucket; -import org.jclouds.s3.functions.BindRegionToXmlPayload; -import org.jclouds.s3.functions.DefaultEndpointThenInvalidateRegion; -import org.jclouds.s3.functions.ObjectKey; -import org.jclouds.s3.functions.ParseObjectFromHeadersAndHttpContent; -import org.jclouds.s3.functions.ParseObjectMetadataFromHeaders; -import org.jclouds.s3.options.CopyObjectOptions; -import org.jclouds.s3.options.ListBucketOptions; -import org.jclouds.s3.options.PutBucketOptions; -import org.jclouds.s3.options.PutObjectOptions; -import org.jclouds.s3.predicates.validators.BucketNameValidator; -import org.jclouds.s3.xml.AccessControlListHandler; -import org.jclouds.s3.xml.BucketLoggingHandler; -import org.jclouds.s3.xml.CopyObjectHandler; -import org.jclouds.s3.xml.ListAllMyBucketsHandler; -import org.jclouds.s3.xml.ListBucketHandler; -import org.jclouds.s3.xml.LocationConstraintHandler; -import org.jclouds.s3.xml.PayerHandler; - -import com.google.common.util.concurrent.ListenableFuture; -import com.google.inject.Provides; - -/** - * Provides asynchronous access to S3 via their REST API. - * <p/> - * All commands return a ListenableFuture of the result from S3. Any exceptions incurred during - * processing will be backend in an {@link ExecutionException} as documented in - * {@link ListenableFuture#get()}. - * - * @see AWSS3Client - * @see <a href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/RESTAPI.html" /> - * @deprecated please use - * {@code org.jclouds.ContextBuilder#buildApi(S3Client.class)} - * as {@link S3AsyncClient} interface will be removed in jclouds 1.7. - */ -@Deprecated -@RequestFilters(RequestAuthorizeSignature.class) -@BlobScope(CONTAINER) -public interface S3AsyncClient extends Closeable { - String VERSION = "2006-03-01"; - - /** - * Creates a default implementation of S3Object - */ - @Provides - S3Object newS3Object(); - - /** - * @see S3Client#getObject - */ - @Named("GetObject") - @GET - @Path("/{key}") - @Fallback(NullOnKeyNotFound.class) - @ResponseParser(ParseObjectFromHeadersAndHttpContent.class) - ListenableFuture<S3Object> getObject( - @Bucket @EndpointParam(parser = AssignCorrectHostnameForBucket.class) @BinderParam(BindAsHostPrefixIfConfigured.class) @ParamValidators(BucketNameValidator.class) String bucketName, - @PathParam("key") String key, GetOptions... options); - - /** - * @see S3Client#headObject - */ - @Named("GetObject") - @HEAD - @Path("/{key}") - @Fallback(NullOnKeyNotFound.class) - @ResponseParser(ParseObjectMetadataFromHeaders.class) - ListenableFuture<ObjectMetadata> headObject( - @Bucket @EndpointParam(parser = AssignCorrectHostnameForBucket.class) @BinderParam(BindAsHostPrefixIfConfigured.class) @ParamValidators(BucketNameValidator.class) String bucketName, - @PathParam("key") String key); - - /** - * @see S3Client#objectExists - */ - @Named("GetObject") - @HEAD - @Path("/{key}") - @Fallback(FalseOnKeyNotFound.class) - ListenableFuture<Boolean> objectExists( - @Bucket @EndpointParam(parser = AssignCorrectHostnameForBucket.class) @BinderParam(BindAsHostPrefixIfConfigured.class) @ParamValidators(BucketNameValidator.class) String bucketName, - @PathParam("key") String key); - - /** - * @see S3Client#deleteObject - */ - @Named("DeleteObject") - @DELETE - @Path("/{key}") - @Fallback(VoidOnNotFoundOr404.class) - ListenableFuture<Void> deleteObject( - @Bucket @EndpointParam(parser = AssignCorrectHostnameForBucket.class) @BinderParam(BindAsHostPrefixIfConfigured.class) @ParamValidators(BucketNameValidator.class) String bucketName, - @PathParam("key") String key); - - /** - * @see S3Client#putObject - */ - @Named("PutObject") - @PUT - @Path("/{key}") - @Headers(keys = EXPECT, values = "100-continue") - @ResponseParser(ParseETagHeader.class) - ListenableFuture<String> putObject( - @Bucket @EndpointParam(parser = AssignCorrectHostnameForBucket.class) @BinderParam(BindAsHostPrefixIfConfigured.class) @ParamValidators(BucketNameValidator.class) String bucketName, - @PathParam("key") @ParamParser(ObjectKey.class) @BinderParam(BindS3ObjectMetadataToRequest.class) S3Object object, - PutObjectOptions... options); - - /** - * @see S3Client#putBucketInRegion - */ - @Named("CreateBucket") - @PUT - @Path("/") - @Endpoint(Bucket.class) - @Fallback(FalseIfBucketAlreadyOwnedByYouOrOperationAbortedWhenBucketExists.class) - ListenableFuture<Boolean> putBucketInRegion( - @BinderParam(BindRegionToXmlPayload.class) @Nullable String region, - @Bucket @BinderParam(BindAsHostPrefixIfConfigured.class) @ParamValidators(BucketNameValidator.class) String bucketName, - PutBucketOptions... options); - - /** - * @see S3Client#deleteBucketIfEmpty - */ - @Named("DeleteBucket") - @DELETE - @Path("/") - @Fallback(TrueOn404OrNotFoundFalseOnIllegalState.class) - ListenableFuture<Boolean> deleteBucketIfEmpty( - @Bucket @EndpointParam(parser = DefaultEndpointThenInvalidateRegion.class) @BinderParam(BindAsHostPrefixIfConfigured.class) @ParamValidators(BucketNameValidator.class) String bucketName); - - /** - * @see S3Client#bucketExists - */ - @Named("BucketExists") - @HEAD - @Path("/") - @Fallback(FalseOnContainerNotFound.class) - ListenableFuture<Boolean> bucketExists( - @Bucket @EndpointParam(parser = AssignCorrectHostnameForBucket.class) @BinderParam(BindAsHostPrefixIfConfigured.class) @ParamValidators(BucketNameValidator.class) String bucketName); - - - /** - * @see S3Client#getBucketLocation - */ - @Named("GetBucketLocation") - @GET - @QueryParams(keys = "location") - @Path("/") - @Endpoint(Bucket.class) - @XMLResponseParser(LocationConstraintHandler.class) - ListenableFuture<String> getBucketLocation( - @Bucket @BinderParam(BindAsHostPrefixIfConfigured.class) @ParamValidators(BucketNameValidator.class) String bucketName); - - /** - * @see S3Client#getBucketPayer - */ - @Named("GetBucketRequestPayment") - @GET - @QueryParams(keys = "requestPayment") - @Path("/") - @XMLResponseParser(PayerHandler.class) - ListenableFuture<Payer> getBucketPayer( - @Bucket @EndpointParam(parser = AssignCorrectHostnameForBucket.class) @BinderParam(BindAsHostPrefixIfConfigured.class) @ParamValidators(BucketNameValidator.class) String bucketName); - - /** - * @see S3Client#setBucketPayer - */ - @Named("PutBucketRequestPayment") - @PUT - @QueryParams(keys = "requestPayment") - @Path("/") - ListenableFuture<Void> setBucketPayer( - @Bucket @EndpointParam(parser = AssignCorrectHostnameForBucket.class) @BinderParam(BindAsHostPrefixIfConfigured.class) @ParamValidators(BucketNameValidator.class) String bucketName, - @BinderParam(BindPayerToXmlPayload.class) Payer payer); - - /** - * @see S3Client#listBucket - */ - @Named("ListBucket") - @GET - @Path("/") - @XMLResponseParser(ListBucketHandler.class) - ListenableFuture<ListBucketResponse> listBucket( - @Bucket @EndpointParam(parser = AssignCorrectHostnameForBucket.class) @BinderParam(BindAsHostPrefixIfConfigured.class) @ParamValidators(BucketNameValidator.class) String bucketName, - ListBucketOptions... options); - - /** - * @see S3Client#listOwnedBuckets - */ - @Named("ListAllMyBuckets") - @GET - @XMLResponseParser(ListAllMyBucketsHandler.class) - @Path("/") - @VirtualHost - ListenableFuture<? extends Set<BucketMetadata>> listOwnedBuckets(); - - /** - * @see S3Client#copyObject - */ - @Named("PutObject") - @PUT - @Path("/{destinationObject}") - @Headers(keys = "x-amz-copy-source", values = "/{sourceBucket}/{sourceObject}") - @XMLResponseParser(CopyObjectHandler.class) - ListenableFuture<ObjectMetadata> copyObject( - @PathParam("sourceBucket") String sourceBucket, - @PathParam("sourceObject") String sourceObject, - @Bucket @EndpointParam(parser = AssignCorrectHostnameForBucket.class) @BinderParam(BindAsHostPrefixIfConfigured.class) @ParamValidators(BucketNameValidator.class) String destinationBucket, - @PathParam("destinationObject") String destinationObject, CopyObjectOptions... options); - - /** - * @see S3Client#getBucketACL - */ - @Named("GetBucketAcl") - @GET - @QueryParams(keys = "acl") - @XMLResponseParser(AccessControlListHandler.class) - @Fallback(ThrowContainerNotFoundOn404.class) - @Path("/") - ListenableFuture<AccessControlList> getBucketACL( - @Bucket @EndpointParam(parser = AssignCorrectHostnameForBucket.class) @BinderParam(BindAsHostPrefixIfConfigured.class) @ParamValidators(BucketNameValidator.class) String bucketName); - - /** - * @see S3Client#putBucketACL - */ - @Named("PutBucketAcl") - @PUT - @Path("/") - @QueryParams(keys = "acl") - ListenableFuture<Boolean> putBucketACL( - @Bucket @EndpointParam(parser = AssignCorrectHostnameForBucket.class) @BinderParam(BindAsHostPrefixIfConfigured.class) @ParamValidators(BucketNameValidator.class) String bucketName, - @BinderParam(BindACLToXMLPayload.class) AccessControlList acl); - - /** - * @see S3Client#getObjectACL - */ - @Named("GetObjectAcl") - @GET - @QueryParams(keys = "acl") - @Path("/{key}") - @XMLResponseParser(AccessControlListHandler.class) - @Fallback(ThrowKeyNotFoundOn404.class) - ListenableFuture<AccessControlList> getObjectACL( - @Bucket @EndpointParam(parser = AssignCorrectHostnameForBucket.class) @BinderParam(BindAsHostPrefixIfConfigured.class) @ParamValidators(BucketNameValidator.class) String bucketName, - @PathParam("key") String key); - - /** - * @see S3Client#putObjectACL - */ - @Named("PutObjectAcl") - @PUT - @QueryParams(keys = "acl") - @Path("/{key}") - ListenableFuture<Boolean> putObjectACL( - @Bucket @EndpointParam(parser = AssignCorrectHostnameForBucket.class) @BinderParam(BindAsHostPrefixIfConfigured.class) @ParamValidators(BucketNameValidator.class) String bucketName, - @PathParam("key") String key, @BinderParam(BindACLToXMLPayload.class) AccessControlList acl); - - /** - * @see S3Client#getBucketLogging - */ - @Named("GetBucketLogging") - @GET - @QueryParams(keys = "logging") - @XMLResponseParser(BucketLoggingHandler.class) - @Fallback(ThrowContainerNotFoundOn404.class) - @Path("/") - ListenableFuture<BucketLogging> getBucketLogging( - @Bucket @EndpointParam(parser = AssignCorrectHostnameForBucket.class) @BinderParam(BindAsHostPrefixIfConfigured.class) @ParamValidators(BucketNameValidator.class) String bucketName); - - /** - * @see S3Client#enableBucketLogging - */ - @Named("PutBucketLogging") - @PUT - @Path("/") - @QueryParams(keys = "logging") - ListenableFuture<Void> enableBucketLogging( - @Bucket @EndpointParam(parser = AssignCorrectHostnameForBucket.class) @BinderParam(BindAsHostPrefixIfConfigured.class) @ParamValidators(BucketNameValidator.class) String bucketName, - @BinderParam(BindBucketLoggingToXmlPayload.class) BucketLogging logging); - - /** - * @see S3Client#putBucketLogging - */ - @Named("PutBucketLogging") - @PUT - @Path("/") - @QueryParams(keys = "logging") - @Produces(MediaType.TEXT_XML) - ListenableFuture<Void> disableBucketLogging( - @Bucket @EndpointParam(parser = AssignCorrectHostnameForBucket.class) @BinderParam(BindNoBucketLoggingToXmlPayload.class) @ParamValidators(BucketNameValidator.class) String bucketName); - -} http://git-wip-us.apache.org/repos/asf/jclouds/blob/b6497556/apis/s3/src/main/java/org/jclouds/s3/S3Client.java ---------------------------------------------------------------------- diff --git a/apis/s3/src/main/java/org/jclouds/s3/S3Client.java b/apis/s3/src/main/java/org/jclouds/s3/S3Client.java index 34ae0f0..ba11992 100644 --- a/apis/s3/src/main/java/org/jclouds/s3/S3Client.java +++ b/apis/s3/src/main/java/org/jclouds/s3/S3Client.java @@ -16,11 +16,51 @@ */ package org.jclouds.s3; +import static com.google.common.net.HttpHeaders.EXPECT; +import static org.jclouds.blobstore.attr.BlobScopes.CONTAINER; +import static org.jclouds.s3.S3Fallbacks.TrueOn404OrNotFoundFalseOnIllegalState; + import java.io.Closeable; import java.util.Set; +import javax.inject.Named; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.HEAD; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; + +import org.jclouds.Fallbacks.VoidOnNotFoundOr404; +import org.jclouds.blobstore.BlobStoreFallbacks.FalseOnContainerNotFound; +import org.jclouds.blobstore.BlobStoreFallbacks.FalseOnKeyNotFound; +import org.jclouds.blobstore.BlobStoreFallbacks.NullOnKeyNotFound; +import org.jclouds.blobstore.BlobStoreFallbacks.ThrowContainerNotFoundOn404; +import org.jclouds.blobstore.BlobStoreFallbacks.ThrowKeyNotFoundOn404; +import org.jclouds.blobstore.attr.BlobScope; +import org.jclouds.http.functions.ParseETagHeader; import org.jclouds.http.options.GetOptions; import org.jclouds.javax.annotation.Nullable; +import org.jclouds.rest.annotations.BinderParam; +import org.jclouds.rest.annotations.Endpoint; +import org.jclouds.rest.annotations.EndpointParam; +import org.jclouds.rest.annotations.Fallback; +import org.jclouds.rest.annotations.Headers; +import org.jclouds.rest.annotations.ParamParser; +import org.jclouds.rest.annotations.ParamValidators; +import org.jclouds.rest.annotations.QueryParams; +import org.jclouds.rest.annotations.RequestFilters; +import org.jclouds.rest.annotations.ResponseParser; +import org.jclouds.rest.annotations.VirtualHost; +import org.jclouds.rest.annotations.XMLResponseParser; +import org.jclouds.s3.binders.BindACLToXMLPayload; +import org.jclouds.s3.binders.BindAsHostPrefixIfConfigured; +import org.jclouds.s3.binders.BindBucketLoggingToXmlPayload; +import org.jclouds.s3.binders.BindNoBucketLoggingToXmlPayload; +import org.jclouds.s3.binders.BindPayerToXmlPayload; +import org.jclouds.s3.binders.BindS3ObjectMetadataToRequest; import org.jclouds.s3.domain.AccessControlList; import org.jclouds.s3.domain.BucketLogging; import org.jclouds.s3.domain.BucketMetadata; @@ -28,22 +68,34 @@ import org.jclouds.s3.domain.ListBucketResponse; import org.jclouds.s3.domain.ObjectMetadata; import org.jclouds.s3.domain.Payer; import org.jclouds.s3.domain.S3Object; +import org.jclouds.s3.fallbacks.FalseIfBucketAlreadyOwnedByYouOrOperationAbortedWhenBucketExists; +import org.jclouds.s3.filters.RequestAuthorizeSignature; +import org.jclouds.s3.functions.AssignCorrectHostnameForBucket; +import org.jclouds.s3.functions.BindRegionToXmlPayload; +import org.jclouds.s3.functions.DefaultEndpointThenInvalidateRegion; +import org.jclouds.s3.functions.ObjectKey; +import org.jclouds.s3.functions.ParseObjectFromHeadersAndHttpContent; +import org.jclouds.s3.functions.ParseObjectMetadataFromHeaders; import org.jclouds.s3.options.CopyObjectOptions; import org.jclouds.s3.options.ListBucketOptions; import org.jclouds.s3.options.PutBucketOptions; import org.jclouds.s3.options.PutObjectOptions; +import org.jclouds.s3.predicates.validators.BucketNameValidator; +import org.jclouds.s3.xml.AccessControlListHandler; +import org.jclouds.s3.xml.BucketLoggingHandler; +import org.jclouds.s3.xml.CopyObjectHandler; +import org.jclouds.s3.xml.ListAllMyBucketsHandler; +import org.jclouds.s3.xml.ListBucketHandler; +import org.jclouds.s3.xml.LocationConstraintHandler; +import org.jclouds.s3.xml.PayerHandler; import com.google.inject.Provides; /** * Provides access to S3 via their REST API. - * <p/> - * All commands return a Future of the result from S3. Any exceptions incurred during - * processing will be backend in an {@link ExecutionException} as documented in - * {@link Future#get()}. - * - * @see <a href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/RESTAPI.html" /> */ +@RequestFilters(RequestAuthorizeSignature.class) +@BlobScope(CONTAINER) public interface S3Client extends Closeable { /** @@ -60,14 +112,14 @@ public interface S3Client extends Closeable { * anonymous user, you can request the object without an authorization header. * * <p /> - * This command allows you to specify {@link GetObjectOptions} to control delivery of content. + * This command allows you to specify {@link GetOptions} to control delivery of content. * * <h2>Note</h2> * If you specify any of the below options, you will receive partial content: * <ul> - * <li>{@link GetObjectOptions#range}</li> - * <li>{@link GetObjectOptions#startAt}</li> - * <li>{@link GetObjectOptions#tail}</li> + * <li>{@link GetOptions#range}</li> + * <li>{@link GetOptions#startAt}</li> + * <li>{@link GetOptions#tail}</li> * </ul> * * @param bucketName @@ -75,20 +127,23 @@ public interface S3Client extends Closeable { * @param key * unique key in the s3Bucket identifying the object * @return Future reference to a fully populated S3Object including data stored in S3 - * or {@link S3Object#NOT_FOUND} if not present. + * or null if not present. * * @throws org.jclouds.http.HttpResponseException * if the conditions requested set were not satisfied by the object on the server. - * @see #getObject(String, String) - * @see GetObjectOptions */ - S3Object getObject(String bucketName, String key, GetOptions... options); + @Named("GetObject") + @GET + @Path("/{key}") + @Fallback(NullOnKeyNotFound.class) + @ResponseParser(ParseObjectFromHeadersAndHttpContent.class) + S3Object getObject(@Bucket @EndpointParam(parser = AssignCorrectHostnameForBucket.class) @BinderParam( + BindAsHostPrefixIfConfigured.class) @ParamValidators(BucketNameValidator.class) String bucketName, + @PathParam("key") String key, GetOptions... options); /** * Retrieves the {@link org.jclouds.s3.domain.internal.BucketListObjectMetadata metadata} of - * the object associated with the key or - * {@link org.jclouds.s3.domain.internal.BucketListObjectMetadata#NOT_FOUND} if not - * available. + * the object associated with the key or null if not available. * * <p/> * The HEAD operation is used to retrieve information about a specific object or object size, @@ -96,21 +151,26 @@ public interface S3Client extends Closeable { * object metadata, and don't want to waste bandwidth on the object data. * * - * @param bucketName - * namespace of the metadata you are retrieving - * @param key - * unique key in the s3Bucket identifying the object - * @return metadata associated with the key or - * {@link org.jclouds.s3.domain.internal.BucketListObjectMetadata#NOT_FOUND} if not - * present; - * @see #getObject(String, String) - * @see <a - * href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?RESTObjectHEAD.html" - * /> + * @param bucketName namespace of the metadata you are retrieving + * @param key unique key in the s3Bucket identifying the object + * @return metadata associated with the key or null if not present. */ - ObjectMetadata headObject(String bucketName, String key); + @Named("GetObject") + @HEAD + @Path("/{key}") + @Fallback(NullOnKeyNotFound.class) + @ResponseParser(ParseObjectMetadataFromHeaders.class) + ObjectMetadata headObject(@Bucket @EndpointParam(parser = AssignCorrectHostnameForBucket.class) @BinderParam( + BindAsHostPrefixIfConfigured.class) @ParamValidators(BucketNameValidator.class) String bucketName, + @PathParam("key") String key); - boolean objectExists(String bucketName, String key); + @Named("GetObject") + @HEAD + @Path("/{key}") + @Fallback(FalseOnKeyNotFound.class) + boolean objectExists(@Bucket @EndpointParam(parser = AssignCorrectHostnameForBucket.class) @BinderParam( + BindAsHostPrefixIfConfigured.class) @ParamValidators(BucketNameValidator.class) String bucketName, + @PathParam("key") String key); /** * Removes the object and metadata associated with the key. @@ -125,10 +185,14 @@ public interface S3Client extends Closeable { * unique key in the s3Bucket identifying the object * @throws org.jclouds.http.HttpResponseException * if the bucket is not available - * @see <a href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html? - * RESTObjectDELETE.html" /> */ - void deleteObject(String bucketName, String key); + @Named("DeleteObject") + @DELETE + @Path("/{key}") + @Fallback(VoidOnNotFoundOr404.class) + void deleteObject(@Bucket @EndpointParam(parser = AssignCorrectHostnameForBucket.class) @BinderParam( + BindAsHostPrefixIfConfigured.class) @ParamValidators(BucketNameValidator.class) String bucketName, + @PathParam("key") String key); /** * Store data by creating or overwriting an object. @@ -149,11 +213,16 @@ public interface S3Client extends Closeable { * @throws org.jclouds.http.HttpResponseException * if the conditions requested set are not satisfied by the object on the server. * @see org.jclouds.s3.domain.CannedAccessPolicy#PRIVATE - * @see <a - * href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?RESTObjectPUT.html" - * /> */ - String putObject(String bucketName, S3Object object, PutObjectOptions... options); + @Named("PutObject") + @PUT + @Path("/{key}") + @Headers(keys = EXPECT, values = "100-continue") + @ResponseParser(ParseETagHeader.class) + String putObject(@Bucket @EndpointParam(parser = AssignCorrectHostnameForBucket.class) @BinderParam( + BindAsHostPrefixIfConfigured.class) @ParamValidators(BucketNameValidator.class) String bucketName, + @PathParam("key") @ParamParser(ObjectKey.class) @BinderParam(BindS3ObjectMetadataToRequest.class) + S3Object object, PutObjectOptions... options); /** * Create and name your own bucket in which to store your objects. @@ -171,12 +240,15 @@ public interface S3Client extends Closeable { * @return true, if the bucket was created or false, if the container was already present * * @see PutBucketOptions - * @see <a - * href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?RESTBucketPUT.html" - * /> - * */ - boolean putBucketInRegion(@Nullable String region, @Bucket String bucketName, PutBucketOptions... options); + @Named("CreateBucket") + @PUT + @Path("/") + @Endpoint(Bucket.class) + @Fallback(FalseIfBucketAlreadyOwnedByYouOrOperationAbortedWhenBucketExists.class) + boolean putBucketInRegion(@BinderParam(BindRegionToXmlPayload.class) @Nullable String region, + @Bucket @BinderParam(BindAsHostPrefixIfConfigured.class) @ParamValidators(BucketNameValidator.class) + String bucketName, PutBucketOptions... options); /** * Deletes the bucket, if it is empty. @@ -187,20 +259,26 @@ public interface S3Client extends Closeable { * Only the owner of a bucket can delete it, regardless of the bucket's access control policy. * * - * @param bucketName - * what to delete + * @param bucketName what to delete * @return false, if the bucket was not empty and therefore not deleted - * @see org.jclouds.s3.commands.DeleteBucket - * @see <a href= - * "http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?RESTBucketDELETE.html" - * /> */ - boolean deleteBucketIfEmpty(String bucketName); + @Named("DeleteBucket") + @DELETE + @Path("/") + @Fallback(TrueOn404OrNotFoundFalseOnIllegalState.class) + boolean deleteBucketIfEmpty(@Bucket @EndpointParam(parser = DefaultEndpointThenInvalidateRegion.class) @BinderParam( + BindAsHostPrefixIfConfigured.class) @ParamValidators(BucketNameValidator.class) String bucketName); + /** * Issues a HEAD command to determine if the bucket exists or not. */ - boolean bucketExists(String bucketName); + @Named("BucketExists") + @HEAD + @Path("/") + @Fallback(FalseOnContainerNotFound.class) + boolean bucketExists(@Bucket @EndpointParam(parser = AssignCorrectHostnameForBucket.class) @BinderParam( + BindAsHostPrefixIfConfigured.class) @ParamValidators(BucketNameValidator.class) String bucketName); /** * Retrieve a {@code S3Bucket} listing. A GET request operation using a bucket URI lists @@ -210,53 +288,60 @@ public interface S3Client extends Closeable { * To list the keys of a bucket, you must have READ access to the bucket. * <p/> * - * @param bucketName - * namespace of the objects you wish to list - * @return Future reference to a fully populated S3Bucket including metadata of the - * S3Objects it contains or {@link BoundedList<ObjectMetadata>#NOT_FOUND} if not present. + * @param bucketName namespace of the objects you wish to list + * @return potentially empty or partial list of the bucket. * @see ListBucketOptions - * - * @see <a - * href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?RESTBucketGET.html" - * /> */ - ListBucketResponse listBucket(String bucketName, ListBucketOptions... options); + @Named("ListBucket") + @GET + @Path("/") + @XMLResponseParser(ListBucketHandler.class) + ListBucketResponse listBucket(@Bucket @EndpointParam(parser = AssignCorrectHostnameForBucket.class) @BinderParam( + BindAsHostPrefixIfConfigured.class) @ParamValidators(BucketNameValidator.class) String bucketName, + ListBucketOptions... options); /** * Returns a list of all of the buckets owned by the authenticated sender of the request. * * @return list of all of the buckets owned by the authenticated sender of the request. - * @see <a - * href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?RESTServiceGET.html" - * /> - * */ + @Named("ListAllMyBuckets") + @GET + @XMLResponseParser(ListAllMyBucketsHandler.class) + @Path("/") + @VirtualHost Set<BucketMetadata> listOwnedBuckets(); + /** * Copies one object to another bucket, retaining UserMetadata from the source. The destination * will have a private acl. The copy operation creates a copy of an object that is already stored * in Amazon S3. * <p/> * When copying an object, you can preserve all metadata (default) or - * {@link CopyObjectOptions#overrideMetadataWith(com.google.common.collect.Multimap) specify new + * {@link CopyObjectOptions#overrideMetadataWith(java.util.Map)} specify new * metadata}. However, the ACL is not preserved and is set to private for the user making the * request. To override the default ACL setting, * {@link CopyObjectOptions#overrideAcl(org.jclouds.s3.domain.CannedAccessPolicy) specify a * new ACL} when generating a copy request. * * @return metadata populated with lastModified and eTag of the new object - * @see org.jclouds.s3.commands.CopyObject - * @see <a - * href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?RESTObjectCOPY.html" - * /> * @throws org.jclouds.http.HttpResponseException * if the conditions requested set are not satisfied by the object on the server. * @see CopyObjectOptions * @see org.jclouds.s3.domain.CannedAccessPolicy */ - ObjectMetadata copyObject(String sourceBucket, String sourceObject, String destinationBucket, - String destinationObject, CopyObjectOptions... options); + @Named("PutObject") + @PUT + @Path("/{destinationObject}") + @Headers(keys = "x-amz-copy-source", values = "/{sourceBucket}/{sourceObject}") + @XMLResponseParser(CopyObjectHandler.class) + ObjectMetadata copyObject(@PathParam("sourceBucket") String sourceBucket, + @PathParam("sourceObject") String sourceObject, + @Bucket @EndpointParam(parser = AssignCorrectHostnameForBucket.class) @BinderParam( + BindAsHostPrefixIfConfigured.class) @ParamValidators(BucketNameValidator.class) String destinationBucket, + @PathParam("destinationObject") String destinationObject, CopyObjectOptions... options); + /** * @@ -266,10 +351,16 @@ public interface S3Client extends Closeable { * To list a bucket's ACL, you must have READ_ACP access to the item. * * @return access permissions of the bucket - * - * @see <a href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/RESTAccessPolicy.html"/> */ - AccessControlList getBucketACL(String bucketName); + @Named("GetBucketAcl") + @GET + @QueryParams(keys = "acl") + @XMLResponseParser(AccessControlListHandler.class) + @Fallback(ThrowContainerNotFoundOn404.class) + @Path("/") + AccessControlList getBucketACL(@Bucket @EndpointParam(parser = AssignCorrectHostnameForBucket.class) @BinderParam( + BindAsHostPrefixIfConfigured.class) @ParamValidators(BucketNameValidator.class) String bucketName); + /** * Update a bucket's Access Control List settings. @@ -285,10 +376,14 @@ public interface S3Client extends Closeable { * the ACL to apply to the bucket. This acl object <strong>must</strong include a valid * owner identifier string in {@link AccessControlList#getOwner()}. * @return true if the bucket's Access Control List was updated successfully. - * - * @see <a href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/RESTAccessPolicy.html"/> */ - boolean putBucketACL(String bucketName, AccessControlList acl); + @Named("PutBucketAcl") + @PUT + @Path("/") + @QueryParams(keys = "acl") + boolean putBucketACL(@Bucket @EndpointParam(parser = AssignCorrectHostnameForBucket.class) @BinderParam( + BindAsHostPrefixIfConfigured.class) @ParamValidators(BucketNameValidator.class) String bucketName, + @BinderParam(BindACLToXMLPayload.class) AccessControlList acl); /** * A GET request operation directed at an object or bucket URI with the "acl" parameter retrieves @@ -297,10 +392,16 @@ public interface S3Client extends Closeable { * To list a object's ACL, you must have READ_ACP access to the item. * * @return access permissions of the object - * - * @see <a href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/RESTAccessPolicy.html"/> */ - AccessControlList getObjectACL(String bucketName, String key); + @Named("GetObjectAcl") + @GET + @QueryParams(keys = "acl") + @Path("/{key}") + @XMLResponseParser(AccessControlListHandler.class) + @Fallback(ThrowKeyNotFoundOn404.class) + AccessControlList getObjectACL(@Bucket @EndpointParam(parser = AssignCorrectHostnameForBucket.class) @BinderParam( + BindAsHostPrefixIfConfigured.class) @ParamValidators(BucketNameValidator.class) String bucketName, + @PathParam("key") String key); /** * Update an object's Access Control List settings. @@ -310,18 +411,23 @@ public interface S3Client extends Closeable { * <p /> * To set a bucket or object's ACL, you must have WRITE_ACP or FULL_CONTROL access to the item. * - * @param bucket + * @param bucketName * the bucket containing the object to be updated - * @param objectKey + * @param key * the key of the object whose Access Control List settings will be updated. * @param acl * the ACL to apply to the object. This acl object <strong>must</strong include a valid * owner identifier string in {@link AccessControlList#getOwner()}. * @return true if the object's Access Control List was updated successfully. - * - * @see <a href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/RESTAccessPolicy.html"/> */ - boolean putObjectACL(String bucketName, String key, AccessControlList acl); + @Named("PutObjectAcl") + @PUT + @QueryParams(keys = "acl") + @Path("/{key}") + boolean putObjectACL(@Bucket @EndpointParam(parser = AssignCorrectHostnameForBucket.class) @BinderParam( + BindAsHostPrefixIfConfigured.class) @ParamValidators(BucketNameValidator.class) String bucketName, + @PathParam("key") String key, @BinderParam(BindACLToXMLPayload.class) AccessControlList acl); + /** * A GET location request operation using a bucket URI lists the location constraint of the @@ -329,16 +435,20 @@ public interface S3Client extends Closeable { * <p/> * To view the location constraint of a bucket, you must be the bucket owner. * - * @param bucket + * @param bucketName * the bucket you wish to know where exists * * @return location of the bucket - * - * @see <a href= - * "http://docs.amazonwebservices.com/AmazonS3/latest/index.html?RESTBucketLocationGET.html" - * /> */ - String getBucketLocation(String bucketName); + @Named("GetBucketLocation") + @GET + @QueryParams(keys = "location") + @Path("/") + @Endpoint(Bucket.class) + @XMLResponseParser(LocationConstraintHandler.class) + String getBucketLocation(@Bucket @BinderParam(BindAsHostPrefixIfConfigured.class) @ParamValidators( + BucketNameValidator.class) String bucketName); + /** * A GET request operation on a requestPayment resource returns the request payment configuration @@ -349,14 +459,17 @@ public interface S3Client extends Closeable { * @param bucketName * the bucket you wish to know the payer status * - * @return {@link Payer.REQUESTER} for a Requester Pays bucket, and {@link Payer.BUCKET_OWNER}, + * @return {@link Payer#REQUESTER} for a Requester Pays bucket, and {@link Payer#BUCKET_OWNER}, * for a normal bucket. - * - * @see <a href= - * "http://docs.amazonwebservices.com/AmazonS3/latest/index.html?RESTrequestPaymentGET.html" - * /> */ - Payer getBucketPayer(String bucketName); + @Named("GetBucketRequestPayment") + @GET + @QueryParams(keys = "requestPayment") + @Path("/") + @XMLResponseParser(PayerHandler.class) + Payer getBucketPayer(@Bucket @EndpointParam(parser = AssignCorrectHostnameForBucket.class) @BinderParam( + BindAsHostPrefixIfConfigured.class) @ParamValidators(BucketNameValidator.class) String bucketName); + /** * The PUT request operation with a requestPayment URI configures an existing bucket to be @@ -371,14 +484,19 @@ public interface S3Client extends Closeable { * the bucket you wish to know the payer status * * @param payer - * {@link Payer.REQUESTER} for a Requester Pays bucket, and {@link Payer.BUCKET_OWNER}, + * {@link Payer#REQUESTER} for a Requester Pays bucket, and {@link Payer#BUCKET_OWNER}, * for a normal bucket. - * - * @see <a href= - * "http://docs.amazonwebservices.com/AmazonS3/latest/index.html?RESTrequestPaymentPUT.html" - * /> */ - void setBucketPayer(String bucketName, Payer payer); + @Named("PutBucketRequestPayment") + @PUT + @QueryParams(keys = "requestPayment") + @Path("/") + void setBucketPayer( + @Bucket @EndpointParam(parser = AssignCorrectHostnameForBucket.class) @BinderParam( + BindAsHostPrefixIfConfigured.class) @ParamValidators(BucketNameValidator.class) String bucketName, + @BinderParam(BindPayerToXmlPayload.class) Payer payer); + + /** * Inspects the logging status for a bucket. @@ -387,11 +505,16 @@ public interface S3Client extends Closeable { * @param bucketName * the bucket you wish to know the logging status * @return bucketLogging configuration or null, if not configured - * - * @see <a href= "http://docs.amazonwebservices.com/AmazonS3/latest/index.html?ServerLogs.html" - * /> */ - BucketLogging getBucketLogging(String bucketName); + @Named("GetBucketLogging") + @GET + @QueryParams(keys = "logging") + @XMLResponseParser(BucketLoggingHandler.class) + @Fallback(ThrowContainerNotFoundOn404.class) + @Path("/") + BucketLogging getBucketLogging(@Bucket @EndpointParam(parser = AssignCorrectHostnameForBucket.class) @BinderParam( + BindAsHostPrefixIfConfigured.class) @ParamValidators(BucketNameValidator.class) String bucketName); + /** * Enables logging for a bucket. @@ -400,19 +523,26 @@ public interface S3Client extends Closeable { * the bucket you wish to enable logging for * @param logging * configuration including destination, prefix, and access rules - * @see <a href= "http://docs.amazonwebservices.com/AmazonS3/latest/index.html?ServerLogs.html" - * /> */ - void enableBucketLogging(String bucketName, BucketLogging logging); + @Named("PutBucketLogging") + @PUT + @Path("/") + @QueryParams(keys = "logging") + void enableBucketLogging(@Bucket @EndpointParam(parser = AssignCorrectHostnameForBucket.class) @BinderParam( + BindAsHostPrefixIfConfigured.class) @ParamValidators(BucketNameValidator.class) String bucketName, + @BinderParam(BindBucketLoggingToXmlPayload.class) BucketLogging logging); /** * Disables logging for a bucket. * * @param bucketName * the bucket you wish to disable logging for - * - * @see <a href= "http://docs.amazonwebservices.com/AmazonS3/latest/index.html?ServerLogs.html" - * /> */ - void disableBucketLogging(String bucketName); + @Named("PutBucketLogging") + @PUT + @Path("/") + @QueryParams(keys = "logging") + @Produces(MediaType.TEXT_XML) + void disableBucketLogging(@Bucket @EndpointParam(parser = AssignCorrectHostnameForBucket.class) @BinderParam( + BindNoBucketLoggingToXmlPayload.class) @ParamValidators(BucketNameValidator.class) String bucketName); } http://git-wip-us.apache.org/repos/asf/jclouds/blob/b6497556/apis/s3/src/main/java/org/jclouds/s3/blobstore/S3AsyncBlobStore.java ---------------------------------------------------------------------- diff --git a/apis/s3/src/main/java/org/jclouds/s3/blobstore/S3AsyncBlobStore.java b/apis/s3/src/main/java/org/jclouds/s3/blobstore/S3AsyncBlobStore.java deleted file mode 100644 index 3725d0a..0000000 --- a/apis/s3/src/main/java/org/jclouds/s3/blobstore/S3AsyncBlobStore.java +++ /dev/null @@ -1,273 +0,0 @@ -/* - * 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.s3.blobstore; - -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.util.concurrent.Futures.transform; - -import java.util.Set; - -import javax.inject.Inject; -import javax.inject.Named; -import javax.inject.Provider; -import javax.inject.Singleton; - -import org.jclouds.Constants; -import org.jclouds.blobstore.BlobStoreContext; -import org.jclouds.blobstore.domain.Blob; -import org.jclouds.blobstore.domain.BlobMetadata; -import org.jclouds.blobstore.domain.PageSet; -import org.jclouds.blobstore.domain.StorageMetadata; -import org.jclouds.blobstore.functions.BlobToHttpGetOptions; -import org.jclouds.blobstore.internal.BaseAsyncBlobStore; -import org.jclouds.blobstore.options.CreateContainerOptions; -import org.jclouds.blobstore.options.ListContainerOptions; -import org.jclouds.blobstore.options.PutOptions; -import org.jclouds.blobstore.strategy.internal.FetchBlobMetadata; -import org.jclouds.blobstore.util.BlobUtils; -import org.jclouds.collect.Memoized; -import org.jclouds.domain.Location; -import org.jclouds.http.options.GetOptions; -import org.jclouds.s3.S3AsyncClient; -import org.jclouds.s3.S3Client; -import org.jclouds.s3.blobstore.functions.BlobToObject; -import org.jclouds.s3.blobstore.functions.BucketToResourceList; -import org.jclouds.s3.blobstore.functions.ContainerToBucketListOptions; -import org.jclouds.s3.blobstore.functions.ObjectToBlob; -import org.jclouds.s3.blobstore.functions.ObjectToBlobMetadata; -import org.jclouds.s3.domain.AccessControlList; -import org.jclouds.s3.domain.AccessControlList.GroupGranteeURI; -import org.jclouds.s3.domain.AccessControlList.Permission; -import org.jclouds.s3.domain.BucketMetadata; -import org.jclouds.s3.domain.CannedAccessPolicy; -import org.jclouds.s3.domain.ListBucketResponse; -import org.jclouds.s3.domain.ObjectMetadata; -import org.jclouds.s3.options.ListBucketOptions; -import org.jclouds.s3.options.PutBucketOptions; -import org.jclouds.s3.options.PutObjectOptions; -import org.jclouds.s3.util.S3Utils; - -import com.google.common.base.Function; -import com.google.common.base.Supplier; -import com.google.common.cache.CacheLoader; -import com.google.common.cache.LoadingCache; -import com.google.common.util.concurrent.ListenableFuture; -import com.google.common.util.concurrent.ListeningExecutorService; - -/** - * - * @deprecated will be removed in jclouds 1.7, as async interfaces are no longer - * supported. Please use {@link S3BlobStore} - */ -@Deprecated -@Singleton -public class S3AsyncBlobStore extends BaseAsyncBlobStore { - - private final S3AsyncClient async; - private final S3Client sync; - private final Function<Set<BucketMetadata>, PageSet<? extends StorageMetadata>> convertBucketsToStorageMetadata; - private final ContainerToBucketListOptions container2BucketListOptions; - private final BlobToHttpGetOptions blob2ObjectGetOptions; - private final BucketToResourceList bucket2ResourceList; - private final ObjectToBlob object2Blob; - private final BlobToObject blob2Object; - private final ObjectToBlobMetadata object2BlobMd; - private final Provider<FetchBlobMetadata> fetchBlobMetadataProvider; - private final LoadingCache<String, AccessControlList> bucketAcls; - - @Inject - protected S3AsyncBlobStore(BlobStoreContext context, BlobUtils blobUtils, - @Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor, Supplier<Location> defaultLocation, - @Memoized Supplier<Set<? extends Location>> locations, S3AsyncClient async, S3Client sync, - Function<Set<BucketMetadata>, PageSet<? extends StorageMetadata>> convertBucketsToStorageMetadata, - ContainerToBucketListOptions container2BucketListOptions, BucketToResourceList bucket2ResourceList, - ObjectToBlob object2Blob, BlobToHttpGetOptions blob2ObjectGetOptions, BlobToObject blob2Object, - ObjectToBlobMetadata object2BlobMd, Provider<FetchBlobMetadata> fetchBlobMetadataProvider, - LoadingCache<String, AccessControlList> bucketAcls) { - super(context, blobUtils, userExecutor, defaultLocation, locations); - this.blob2ObjectGetOptions = checkNotNull(blob2ObjectGetOptions, "blob2ObjectGetOptions"); - this.async = checkNotNull(async, "async"); - this.sync = checkNotNull(sync, "sync"); - this.convertBucketsToStorageMetadata = checkNotNull(convertBucketsToStorageMetadata, "convertBucketsToStorageMetadata"); - this.container2BucketListOptions = checkNotNull(container2BucketListOptions, "container2BucketListOptions"); - this.bucket2ResourceList = checkNotNull(bucket2ResourceList, "bucket2ResourceList"); - this.object2Blob = checkNotNull(object2Blob, "object2Blob"); - this.blob2Object = checkNotNull(blob2Object, "blob2Object"); - this.object2BlobMd = checkNotNull(object2BlobMd, "object2BlobMd"); - this.fetchBlobMetadataProvider = checkNotNull(fetchBlobMetadataProvider, "fetchBlobMetadataProvider"); - this.bucketAcls = checkNotNull(bucketAcls, "bucketAcls"); - } - - /** - * This implementation invokes {@link S3AsyncClient#listOwnedBuckets} - */ - @Override - public ListenableFuture<PageSet<? extends StorageMetadata>> list() { - return transform(async.listOwnedBuckets(), - new Function<Set<BucketMetadata>, org.jclouds.blobstore.domain.PageSet<? extends StorageMetadata>>() { - public org.jclouds.blobstore.domain.PageSet<? extends StorageMetadata> apply(Set<BucketMetadata> from) { - return convertBucketsToStorageMetadata.apply(from); - } - }, userExecutor); - } - - /** - * This implementation invokes {@link S3AsyncClient#bucketExists} - * - * @param container - * bucket name - */ - @Override - public ListenableFuture<Boolean> containerExists(String container) { - return async.bucketExists(container); - } - - /** - * This implementation invokes {@link S3AsyncClient#putBucketInRegion} - * - * @param location - * corresponds to Region - * @param container - * bucket name - */ - @Override - public ListenableFuture<Boolean> createContainerInLocation(Location location, String container) { - return createContainerInLocation(location, container, CreateContainerOptions.NONE); - } - - /** - * This implementation invokes {@link S3AsyncClient#listBucket} - * - * @param container - * bucket name - */ - @Override - // TODO get rid of transform, as it serializes async results when the executor is single-threaded. - public ListenableFuture<PageSet<? extends StorageMetadata>> list(String container, ListContainerOptions options) { - ListBucketOptions httpOptions = container2BucketListOptions.apply(options); - ListenableFuture<ListBucketResponse> returnVal = async.listBucket(container, httpOptions); - ListenableFuture<PageSet<? extends StorageMetadata>> list = transform(returnVal, bucket2ResourceList, - userExecutor); - return (options.isDetailed()) ? transform(list, - fetchBlobMetadataProvider.get().setContainerName(container), userExecutor) : list; - } - - /** - * This implementation invokes {@link S3Utils#deleteAndVerifyContainerGone} - */ - protected boolean deleteAndVerifyContainerGone(final String container) { - return S3Utils.deleteAndVerifyContainerGone(sync, container); - } - - /** - * This implementation invokes {@link S3AsyncClient#objectExists} - * - * @param container - * bucket name - * @param key - * object key - */ - @Override - public ListenableFuture<Boolean> blobExists(String container, String key) { - return async.objectExists(container, key); - } - - /** - * This implementation invokes {@link S3AsyncClient#headObject} - * - * @param container - * bucket name - * @param key - * object key - */ - @Override - public ListenableFuture<BlobMetadata> blobMetadata(String container, String key) { - return transform(async.headObject(container, key), new Function<ObjectMetadata, BlobMetadata>() { - - @Override - public BlobMetadata apply(ObjectMetadata from) { - return object2BlobMd.apply(from); - } - - }, userExecutor); - } - - /** - * This implementation invokes {@link S3AsyncClient#getObject} - * - * @param container - * bucket name - * @param key - * object key - */ - @Override - public ListenableFuture<Blob> getBlob(String container, String key, org.jclouds.blobstore.options.GetOptions options) { - GetOptions httpOptions = blob2ObjectGetOptions.apply(options); - return transform(async.getObject(container, key, httpOptions), object2Blob, userExecutor); - } - - /** - * This implementation invokes {@link S3AsyncClient#putObject} - * - * @param container - * bucket name - * @param blob - * object - */ - @Override - public ListenableFuture<String> putBlob(String container, Blob blob) { - return putBlob(container, blob, PutOptions.NONE); - } - - @Override - public ListenableFuture<String> putBlob(String container, Blob blob, PutOptions overrides) { - // TODO: Make use of options overrides - PutObjectOptions options = new PutObjectOptions(); - try { - AccessControlList acl = bucketAcls.getUnchecked(container); - if (acl.hasPermission(GroupGranteeURI.ALL_USERS, Permission.READ)) - options.withAcl(CannedAccessPolicy.PUBLIC_READ); - } catch (CacheLoader.InvalidCacheLoadException e) { - // nulls not permitted from cache loader - } - return async.putObject(container, blob2Object.apply(blob), options); - } - - /** - * This implementation invokes {@link S3AsyncClient#deleteObject} - * - * @param container - * bucket name - * @param key - * object key - */ - @Override - public ListenableFuture<Void> removeBlob(String container, String key) { - return async.deleteObject(container, key); - } - - @Override - public ListenableFuture<Boolean> createContainerInLocation(Location location, String container, - CreateContainerOptions options) { - PutBucketOptions putBucketOptions = new PutBucketOptions(); - if (options.isPublicRead()) - putBucketOptions.withBucketAcl(CannedAccessPolicy.PUBLIC_READ); - location = location != null ? location : defaultLocation.get(); - return async.putBucketInRegion(location.getId(), container, putBucketOptions); - } - -} http://git-wip-us.apache.org/repos/asf/jclouds/blob/b6497556/apis/s3/src/main/java/org/jclouds/s3/blobstore/S3BlobRequestSigner.java ---------------------------------------------------------------------- diff --git a/apis/s3/src/main/java/org/jclouds/s3/blobstore/S3BlobRequestSigner.java b/apis/s3/src/main/java/org/jclouds/s3/blobstore/S3BlobRequestSigner.java index 2ba56f4..a335754 100644 --- a/apis/s3/src/main/java/org/jclouds/s3/blobstore/S3BlobRequestSigner.java +++ b/apis/s3/src/main/java/org/jclouds/s3/blobstore/S3BlobRequestSigner.java @@ -30,7 +30,7 @@ import org.jclouds.http.HttpRequest; import org.jclouds.http.options.GetOptions; import org.jclouds.reflect.Invocation; import org.jclouds.rest.internal.RestAnnotationProcessor; -import org.jclouds.s3.S3AsyncClient; +import org.jclouds.s3.S3Client; import org.jclouds.s3.blobstore.functions.BlobToObject; import org.jclouds.s3.domain.S3Object; import org.jclouds.s3.options.PutObjectOptions; @@ -39,7 +39,7 @@ import com.google.common.collect.ImmutableList; import com.google.common.reflect.Invokable; @Singleton -public class S3BlobRequestSigner<T extends S3AsyncClient> implements BlobRequestSigner { +public class S3BlobRequestSigner<T extends S3Client> implements BlobRequestSigner { protected final RestAnnotationProcessor processor; protected final BlobToObject blobToObject; protected final BlobToHttpGetOptions blob2HttpGetOptions; http://git-wip-us.apache.org/repos/asf/jclouds/blob/b6497556/apis/s3/src/main/java/org/jclouds/s3/blobstore/S3BlobStoreContext.java ---------------------------------------------------------------------- diff --git a/apis/s3/src/main/java/org/jclouds/s3/blobstore/S3BlobStoreContext.java b/apis/s3/src/main/java/org/jclouds/s3/blobstore/S3BlobStoreContext.java index d4bcd4f..9f32ce8 100644 --- a/apis/s3/src/main/java/org/jclouds/s3/blobstore/S3BlobStoreContext.java +++ b/apis/s3/src/main/java/org/jclouds/s3/blobstore/S3BlobStoreContext.java @@ -26,7 +26,4 @@ public interface S3BlobStoreContext extends BlobStoreContext { @Override S3BlobStore getBlobStore(); - - @Override - S3AsyncBlobStore getAsyncBlobStore(); } http://git-wip-us.apache.org/repos/asf/jclouds/blob/b6497556/apis/s3/src/main/java/org/jclouds/s3/blobstore/config/S3BlobStoreContextModule.java ---------------------------------------------------------------------- diff --git a/apis/s3/src/main/java/org/jclouds/s3/blobstore/config/S3BlobStoreContextModule.java b/apis/s3/src/main/java/org/jclouds/s3/blobstore/config/S3BlobStoreContextModule.java index 3b42159..525f9bd 100644 --- a/apis/s3/src/main/java/org/jclouds/s3/blobstore/config/S3BlobStoreContextModule.java +++ b/apis/s3/src/main/java/org/jclouds/s3/blobstore/config/S3BlobStoreContextModule.java @@ -26,9 +26,9 @@ import org.jclouds.blobstore.AsyncBlobStore; import org.jclouds.blobstore.BlobRequestSigner; import org.jclouds.blobstore.BlobStore; import org.jclouds.blobstore.attr.ConsistencyModel; +import org.jclouds.blobstore.internal.SubmissionAsyncBlobStore; import org.jclouds.domain.Location; -import org.jclouds.s3.S3AsyncClient; -import org.jclouds.s3.blobstore.S3AsyncBlobStore; +import org.jclouds.s3.S3Client; import org.jclouds.s3.blobstore.S3BlobRequestSigner; import org.jclouds.s3.blobstore.S3BlobStore; import org.jclouds.s3.blobstore.functions.LocationFromBucketName; @@ -42,15 +42,12 @@ import com.google.inject.AbstractModule; import com.google.inject.Provides; import com.google.inject.TypeLiteral; -/** - * Configures the {@link S3BlobStoreContext}; requires {@link S3AsyncBlobStore} bound. - */ public class S3BlobStoreContextModule extends AbstractModule { @Override protected void configure() { bind(ConsistencyModel.class).toInstance(ConsistencyModel.EVENTUAL); - bind(AsyncBlobStore.class).to(S3AsyncBlobStore.class).in(SINGLETON); + bind(AsyncBlobStore.class).to(SubmissionAsyncBlobStore.class).in(SINGLETON); bind(BlobStore.class).to(S3BlobStore.class).in(SINGLETON); bind(new TypeLiteral<Function<String, Location>>() { }).to(LocationFromBucketName.class); @@ -58,7 +55,7 @@ public class S3BlobStoreContextModule extends AbstractModule { } protected void bindRequestSigner() { - bind(BlobRequestSigner.class).to(new TypeLiteral<S3BlobRequestSigner<S3AsyncClient>>() { + bind(BlobRequestSigner.class).to(new TypeLiteral<S3BlobRequestSigner<S3Client>>() { }); } http://git-wip-us.apache.org/repos/asf/jclouds/blob/b6497556/apis/s3/src/main/java/org/jclouds/s3/blobstore/internal/S3BlobStoreContextImpl.java ---------------------------------------------------------------------- diff --git a/apis/s3/src/main/java/org/jclouds/s3/blobstore/internal/S3BlobStoreContextImpl.java b/apis/s3/src/main/java/org/jclouds/s3/blobstore/internal/S3BlobStoreContextImpl.java index 79bc913..a2aaf9a 100644 --- a/apis/s3/src/main/java/org/jclouds/s3/blobstore/internal/S3BlobStoreContextImpl.java +++ b/apis/s3/src/main/java/org/jclouds/s3/blobstore/internal/S3BlobStoreContextImpl.java @@ -27,7 +27,6 @@ import org.jclouds.blobstore.attr.ConsistencyModel; import org.jclouds.blobstore.internal.BlobStoreContextImpl; import org.jclouds.location.Provider; import org.jclouds.rest.Utils; -import org.jclouds.s3.blobstore.S3AsyncBlobStore; import org.jclouds.s3.blobstore.S3BlobStore; import org.jclouds.s3.blobstore.S3BlobStoreContext; @@ -49,10 +48,4 @@ public class S3BlobStoreContextImpl extends BlobStoreContextImpl implements S3Bl public S3BlobStore getBlobStore() { return S3BlobStore.class.cast(super.getBlobStore()); } - - @Override - public S3AsyncBlobStore getAsyncBlobStore() { - return S3AsyncBlobStore.class.cast(super.getAsyncBlobStore()); - } - } http://git-wip-us.apache.org/repos/asf/jclouds/blob/b6497556/apis/s3/src/main/java/org/jclouds/s3/config/S3HttpApiModule.java ---------------------------------------------------------------------- diff --git a/apis/s3/src/main/java/org/jclouds/s3/config/S3HttpApiModule.java b/apis/s3/src/main/java/org/jclouds/s3/config/S3HttpApiModule.java new file mode 100644 index 0000000..3841865 --- /dev/null +++ b/apis/s3/src/main/java/org/jclouds/s3/config/S3HttpApiModule.java @@ -0,0 +1,211 @@ +/* + * 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.s3.config; + +import java.net.URI; +import java.util.Set; +import java.util.concurrent.TimeUnit; + +import javax.inject.Named; +import javax.inject.Singleton; + +import org.jclouds.Constants; +import org.jclouds.aws.config.AWSHttpApiModule; +import org.jclouds.aws.handlers.AWSClientErrorRetryHandler; +import org.jclouds.aws.handlers.AWSServerErrorRetryHandler; +import org.jclouds.blobstore.ContainerNotFoundException; +import org.jclouds.blobstore.domain.PageSet; +import org.jclouds.blobstore.domain.StorageMetadata; +import org.jclouds.date.DateService; +import org.jclouds.date.TimeStamp; +import org.jclouds.http.HttpErrorHandler; +import org.jclouds.http.HttpRetryHandler; +import org.jclouds.http.annotation.ClientError; +import org.jclouds.http.annotation.Redirection; +import org.jclouds.http.annotation.ServerError; +import org.jclouds.location.Region; +import org.jclouds.location.functions.RegionToEndpointOrProviderIfNull; +import org.jclouds.rest.ConfiguresHttpApi; +import org.jclouds.rest.RequestSigner; +import org.jclouds.s3.Bucket; +import org.jclouds.s3.S3Client; +import org.jclouds.s3.blobstore.functions.BucketsToStorageMetadata; +import org.jclouds.s3.domain.BucketMetadata; +import org.jclouds.s3.filters.RequestAuthorizeSignature; +import org.jclouds.s3.functions.GetRegionForBucket; +import org.jclouds.s3.handlers.ParseS3ErrorFromXmlContent; +import org.jclouds.s3.handlers.S3RedirectionRetryHandler; + +import com.google.common.base.Function; +import com.google.common.base.Optional; +import com.google.common.base.Supplier; +import com.google.common.base.Suppliers; +import com.google.common.cache.CacheBuilder; +import com.google.common.cache.CacheLoader; +import com.google.common.cache.LoadingCache; +import com.google.common.collect.Iterables; +import com.google.inject.Provides; +import com.google.inject.Scopes; +import com.google.inject.TypeLiteral; + +/** + * Configures the S3 connection, including logging and http transport. + */ +@ConfiguresHttpApi +public class S3HttpApiModule<S extends S3Client> extends AWSHttpApiModule<S> { + + @SuppressWarnings("unchecked") + public S3HttpApiModule() { + this(Class.class.cast(S3Client.class)); + } + + protected S3HttpApiModule(Class<S> syncClientType) { + super(syncClientType); + } + + @Provides + @Bucket + @Singleton + protected CacheLoader<String, Optional<String>> bucketToRegion(@Region Supplier<Set<String>> regionSupplier, + final S3Client client) { + Set<String> regions = regionSupplier.get(); + if (regions.isEmpty()) { + return new CacheLoader<String, Optional<String>>() { + + @Override + public Optional<String> load(String bucket) { + return Optional.absent(); + } + + @Override + public String toString() { + return "noRegions()"; + } + }; + } else if (regions.size() == 1) { + final String onlyRegion = Iterables.getOnlyElement(regions); + return new CacheLoader<String, Optional<String>>() { + Optional<String> onlyRegionOption = Optional.of(onlyRegion); + + @Override + public Optional<String> load(String bucket) { + return onlyRegionOption; + } + + @Override + public String toString() { + return "onlyRegion(" + onlyRegion + ")"; + } + }; + } else { + return new CacheLoader<String, Optional<String>>() { + @Override + public Optional<String> load(String bucket) { + try { + return Optional.fromNullable(client.getBucketLocation(bucket)); + } catch (ContainerNotFoundException e) { + return Optional.absent(); + } + } + + @Override + public String toString() { + return "bucketToRegion()"; + } + }; + } + } + + @Provides + @Bucket + @Singleton + protected LoadingCache<String, Optional<String>> bucketToRegion(@Bucket CacheLoader<String, Optional<String>> loader) { + return CacheBuilder.newBuilder().build(loader); + } + + @Provides + @Bucket + @Singleton + protected Supplier<String> defaultRegionForBucket(@Region Supplier<String> defaultRegion) { + return defaultRegion; + } + + @Provides + @Singleton + @Bucket + protected Supplier<URI> provideBucketURI(@Bucket Supplier<String> defaultRegion, + RegionToEndpointOrProviderIfNull regionToEndpoint) { + return Suppliers.compose(regionToEndpoint, defaultRegion); + } + + @Override + protected void configure() { + super.configure(); + install(new S3ObjectModule()); + install(new S3ParserModule()); + bindRequestSigner(); + bind(new TypeLiteral<Function<String, Optional<String>>>() { + }).annotatedWith(Bucket.class).to(GetRegionForBucket.class); + bind(new TypeLiteral<Function<Set<BucketMetadata>, PageSet<? extends StorageMetadata>>>() { + }).to(BucketsToStorageMetadata.class); + } + + @Override + protected void bindErrorHandlers() { + bind(HttpErrorHandler.class).annotatedWith(Redirection.class).to(ParseS3ErrorFromXmlContent.class); + bind(HttpErrorHandler.class).annotatedWith(ClientError.class).to(ParseS3ErrorFromXmlContent.class); + bind(HttpErrorHandler.class).annotatedWith(ServerError.class).to(ParseS3ErrorFromXmlContent.class); + } + + protected void bindRequestSigner() { + bind(RequestAuthorizeSignature.class).in(Scopes.SINGLETON); + } + + @Provides + @Singleton + protected RequestSigner provideRequestSigner(RequestAuthorizeSignature in) { + return in; + } + + @Override + protected void bindRetryHandlers() { + bind(HttpRetryHandler.class).annotatedWith(Redirection.class).to(S3RedirectionRetryHandler.class); + bind(HttpRetryHandler.class).annotatedWith(ClientError.class).to(AWSClientErrorRetryHandler.class); + bind(HttpRetryHandler.class).annotatedWith(ServerError.class).to(AWSServerErrorRetryHandler.class); + } + + @Provides + @TimeStamp + protected String provideTimeStamp(@TimeStamp Supplier<String> cache) { + return cache.get(); + } + + /** + * borrowing concurrency code to ensure that caching takes place properly + */ + @Provides + @TimeStamp + @Singleton + protected Supplier<String> provideTimeStampCache(@Named(Constants.PROPERTY_SESSION_INTERVAL) long seconds, + final DateService dateService) { + return Suppliers.memoizeWithExpiration(new Supplier<String>() { + public String get() { + return dateService.rfc822DateFormat(); + } + }, seconds, TimeUnit.SECONDS); + } +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/b6497556/apis/s3/src/main/java/org/jclouds/s3/config/S3RestClientModule.java ---------------------------------------------------------------------- diff --git a/apis/s3/src/main/java/org/jclouds/s3/config/S3RestClientModule.java b/apis/s3/src/main/java/org/jclouds/s3/config/S3RestClientModule.java deleted file mode 100644 index 23cf033..0000000 --- a/apis/s3/src/main/java/org/jclouds/s3/config/S3RestClientModule.java +++ /dev/null @@ -1,214 +0,0 @@ -/* - * 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.s3.config; -import static org.jclouds.reflect.Reflection2.typeToken; - -import java.net.URI; -import java.util.Set; -import java.util.concurrent.TimeUnit; - -import javax.inject.Named; -import javax.inject.Singleton; - -import org.jclouds.Constants; -import org.jclouds.aws.config.AWSRestClientModule; -import org.jclouds.aws.handlers.AWSClientErrorRetryHandler; -import org.jclouds.aws.handlers.AWSServerErrorRetryHandler; -import org.jclouds.blobstore.ContainerNotFoundException; -import org.jclouds.blobstore.domain.PageSet; -import org.jclouds.blobstore.domain.StorageMetadata; -import org.jclouds.date.DateService; -import org.jclouds.date.TimeStamp; -import org.jclouds.http.HttpErrorHandler; -import org.jclouds.http.HttpRetryHandler; -import org.jclouds.http.annotation.ClientError; -import org.jclouds.http.annotation.Redirection; -import org.jclouds.http.annotation.ServerError; -import org.jclouds.location.Region; -import org.jclouds.location.functions.RegionToEndpointOrProviderIfNull; -import org.jclouds.rest.ConfiguresRestClient; -import org.jclouds.rest.RequestSigner; -import org.jclouds.s3.Bucket; -import org.jclouds.s3.S3AsyncClient; -import org.jclouds.s3.S3Client; -import org.jclouds.s3.blobstore.functions.BucketsToStorageMetadata; -import org.jclouds.s3.domain.BucketMetadata; -import org.jclouds.s3.filters.RequestAuthorizeSignature; -import org.jclouds.s3.functions.GetRegionForBucket; -import org.jclouds.s3.handlers.ParseS3ErrorFromXmlContent; -import org.jclouds.s3.handlers.S3RedirectionRetryHandler; - -import com.google.common.base.Function; -import com.google.common.base.Optional; -import com.google.common.base.Supplier; -import com.google.common.base.Suppliers; -import com.google.common.cache.CacheBuilder; -import com.google.common.cache.CacheLoader; -import com.google.common.cache.LoadingCache; -import com.google.common.collect.Iterables; -import com.google.common.reflect.TypeToken; -import com.google.inject.Provides; -import com.google.inject.Scopes; -import com.google.inject.TypeLiteral; - -/** - * Configures the S3 connection, including logging and http transport. - */ -@ConfiguresRestClient -public class S3RestClientModule<S extends S3Client, A extends S3AsyncClient> extends AWSRestClientModule<S, A> { - - @SuppressWarnings("unchecked") - public S3RestClientModule() { - this(TypeToken.class.cast(typeToken(S3Client.class)), TypeToken.class.cast(typeToken(S3AsyncClient.class))); - } - - protected S3RestClientModule(TypeToken<S> syncClientType, TypeToken<A> asyncClientType) { - super(syncClientType, asyncClientType); - } - - @Provides - @Bucket - @Singleton - protected CacheLoader<String, Optional<String>> bucketToRegion(@Region Supplier<Set<String>> regionSupplier, - final S3Client client) { - Set<String> regions = regionSupplier.get(); - if (regions.isEmpty()) { - return new CacheLoader<String, Optional<String>>() { - - @Override - public Optional<String> load(String bucket) { - return Optional.absent(); - } - - @Override - public String toString() { - return "noRegions()"; - } - }; - } else if (regions.size() == 1) { - final String onlyRegion = Iterables.getOnlyElement(regions); - return new CacheLoader<String, Optional<String>>() { - Optional<String> onlyRegionOption = Optional.of(onlyRegion); - - @Override - public Optional<String> load(String bucket) { - return onlyRegionOption; - } - - @Override - public String toString() { - return "onlyRegion(" + onlyRegion + ")"; - } - }; - } else { - return new CacheLoader<String, Optional<String>>() { - @Override - public Optional<String> load(String bucket) { - try { - return Optional.fromNullable(client.getBucketLocation(bucket)); - } catch (ContainerNotFoundException e) { - return Optional.absent(); - } - } - - @Override - public String toString() { - return "bucketToRegion()"; - } - }; - } - } - - @Provides - @Bucket - @Singleton - protected LoadingCache<String, Optional<String>> bucketToRegion(@Bucket CacheLoader<String, Optional<String>> loader) { - return CacheBuilder.newBuilder().build(loader); - } - - @Provides - @Bucket - @Singleton - protected Supplier<String> defaultRegionForBucket(@Region Supplier<String> defaultRegion) { - return defaultRegion; - } - - @Provides - @Singleton - @Bucket - protected Supplier<URI> provideBucketURI(@Bucket Supplier<String> defaultRegion, - RegionToEndpointOrProviderIfNull regionToEndpoint) { - return Suppliers.compose(regionToEndpoint, defaultRegion); - } - - @Override - protected void configure() { - super.configure(); - install(new S3ObjectModule()); - install(new S3ParserModule()); - bindRequestSigner(); - bind(new TypeLiteral<Function<String, Optional<String>>>() { - }).annotatedWith(Bucket.class).to(GetRegionForBucket.class); - bind(new TypeLiteral<Function<Set<BucketMetadata>, PageSet<? extends StorageMetadata>>>() { - }).to(BucketsToStorageMetadata.class); - } - - @Override - protected void bindErrorHandlers() { - bind(HttpErrorHandler.class).annotatedWith(Redirection.class).to(ParseS3ErrorFromXmlContent.class); - bind(HttpErrorHandler.class).annotatedWith(ClientError.class).to(ParseS3ErrorFromXmlContent.class); - bind(HttpErrorHandler.class).annotatedWith(ServerError.class).to(ParseS3ErrorFromXmlContent.class); - } - - protected void bindRequestSigner() { - bind(RequestAuthorizeSignature.class).in(Scopes.SINGLETON); - } - - @Provides - @Singleton - protected RequestSigner provideRequestSigner(RequestAuthorizeSignature in) { - return in; - } - - @Override - protected void bindRetryHandlers() { - bind(HttpRetryHandler.class).annotatedWith(Redirection.class).to(S3RedirectionRetryHandler.class); - bind(HttpRetryHandler.class).annotatedWith(ClientError.class).to(AWSClientErrorRetryHandler.class); - bind(HttpRetryHandler.class).annotatedWith(ServerError.class).to(AWSServerErrorRetryHandler.class); - } - - @Provides - @TimeStamp - protected String provideTimeStamp(@TimeStamp Supplier<String> cache) { - return cache.get(); - } - - /** - * borrowing concurrency code to ensure that caching takes place properly - */ - @Provides - @TimeStamp - @Singleton - protected Supplier<String> provideTimeStampCache(@Named(Constants.PROPERTY_SESSION_INTERVAL) long seconds, - final DateService dateService) { - return Suppliers.memoizeWithExpiration(new Supplier<String>() { - public String get() { - return dateService.rfc822DateFormat(); - } - }, seconds, TimeUnit.SECONDS); - } -} http://git-wip-us.apache.org/repos/asf/jclouds/blob/b6497556/apis/s3/src/main/java/org/jclouds/s3/domain/AccessControlList.java ---------------------------------------------------------------------- diff --git a/apis/s3/src/main/java/org/jclouds/s3/domain/AccessControlList.java b/apis/s3/src/main/java/org/jclouds/s3/domain/AccessControlList.java index 0faaa38..7450f30 100644 --- a/apis/s3/src/main/java/org/jclouds/s3/domain/AccessControlList.java +++ b/apis/s3/src/main/java/org/jclouds/s3/domain/AccessControlList.java @@ -36,9 +36,6 @@ import com.google.common.collect.Sets; * has been granted to a specific {@link Grantee}. If an payload tries to access or modify an item * in S3, the operation will be denied unless the item has ACL settings that explicitly permit that * payload to perform that action. - * - * - * @see <a href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/RESTAccessPolicy.html"/> */ public class AccessControlList { http://git-wip-us.apache.org/repos/asf/jclouds/blob/b6497556/apis/s3/src/main/java/org/jclouds/s3/domain/BucketLogging.java ---------------------------------------------------------------------- diff --git a/apis/s3/src/main/java/org/jclouds/s3/domain/BucketLogging.java b/apis/s3/src/main/java/org/jclouds/s3/domain/BucketLogging.java index 3d50a44..1470441 100644 --- a/apis/s3/src/main/java/org/jclouds/s3/domain/BucketLogging.java +++ b/apis/s3/src/main/java/org/jclouds/s3/domain/BucketLogging.java @@ -26,8 +26,6 @@ import com.google.common.collect.Sets; /** * Each Amazon S3 bucket has an associated XML sub-resource that you can read and write in order to * inspect or change the logging status for that bucket. - * - * @see <a href="http://docs.amazonwebservices.com/AmazonS3/latest/index.html?ServerLogs.html"/> */ public class BucketLogging { private final String targetBucket;
