mirror of https://github.com/apache/jclouds.git
Issue 74, Issue 76, Issue 101: revamped blobstore and rest subsystems; Issue 10: removed assisted inject
git-svn-id: http://jclouds.googlecode.com/svn/trunk@2001 3d8758e0-26b5-11de-8745-db77d3ebf521
This commit is contained in:
parent
71377b29a1
commit
050f6e9a82
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
|
@ -27,7 +27,6 @@ import static org.testng.Assert.assertEquals;
|
|||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.jclouds.aws.domain.AWSError;
|
||||
import org.jclouds.aws.xml.ErrorHandler;
|
||||
import org.jclouds.http.HttpException;
|
||||
import org.jclouds.http.functions.BaseHandlerTest;
|
||||
import org.jclouds.http.functions.ParseSax;
|
||||
|
@ -37,7 +36,6 @@ import org.testng.annotations.Test;
|
|||
public class ErrorHandlerTest extends BaseHandlerTest {
|
||||
public static final String errorFromAmazonIfYouDontRemoveTransferEncodingHeader = "<Error><Code>NotImplemented</Code><Message>A header you provided implies functionality that is not implemented</Message><Header>Transfer-Encoding</Header><RequestId>7C59925D75D15561</RequestId><HostId>fbskVU51OZJg2yZS/wNIxoE2PmCf0ZqFd0iH6Vrzw0uKG3KmokswBytL/Bfp/GWb</HostId></Error>";
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
ParseSax<AWSError> createParser() {
|
||||
ParseSax<AWSError> parser = (ParseSax<AWSError>) factory.create(injector
|
||||
.getInstance(ErrorHandler.class));
|
||||
|
|
|
@ -1,4 +1,29 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
|
||||
|
||||
Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
|
||||
====================================================================
|
||||
Licensed to the Apache Software Foundation (ASF) under one
|
||||
or more contributor license agreements. See the NOTICE file
|
||||
distributed with this work for additional information
|
||||
regarding copyright ownership. The ASF licenses this file
|
||||
to you under the Apache License, Version 2.0 (the
|
||||
"License"); you may not use this file except in compliance
|
||||
with the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing,
|
||||
software distributed under the License is distributed on an
|
||||
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
KIND, either express or implied. See the License for the
|
||||
specific language governing permissions and limitations
|
||||
under the License.
|
||||
====================================================================
|
||||
|
||||
-->
|
||||
<Error>
|
||||
<Code>NoSuchKey</Code>
|
||||
<Message>The resource you requested does not exist</Message>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<!--
|
||||
|
||||
|
||||
Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
|
||||
Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
|
||||
====================================================================
|
||||
Licensed to the Apache Software Foundation (ASF) under one
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
|
|
|
@ -1,258 +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.aws.s3;
|
||||
|
||||
import java.util.SortedSet;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
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 org.jclouds.aws.s3.binders.BindS3ObjectToEntity;
|
||||
import org.jclouds.aws.s3.domain.BucketMetadata;
|
||||
import org.jclouds.aws.s3.domain.ListBucketResponse;
|
||||
import org.jclouds.aws.s3.domain.ObjectMetadata;
|
||||
import org.jclouds.aws.s3.domain.S3Object;
|
||||
import org.jclouds.aws.s3.filters.RequestAuthorizeSignature;
|
||||
import org.jclouds.aws.s3.functions.ClearAndDeleteBucketIfNotEmpty;
|
||||
import org.jclouds.aws.s3.functions.ParseObjectFromHeadersAndHttpContent;
|
||||
import org.jclouds.aws.s3.functions.ParseObjectMetadataFromHeaders;
|
||||
import org.jclouds.aws.s3.functions.ReturnTrueIfBucketAlreadyOwnedByYou;
|
||||
import org.jclouds.aws.s3.options.ListBucketOptions;
|
||||
import org.jclouds.aws.s3.xml.ListAllMyBucketsHandler;
|
||||
import org.jclouds.aws.s3.xml.ListBucketHandler;
|
||||
import org.jclouds.blobstore.BlobStore;
|
||||
import org.jclouds.blobstore.domain.Blob;
|
||||
import org.jclouds.blobstore.functions.BlobName;
|
||||
import org.jclouds.blobstore.functions.ReturnVoidOnNotFoundOr404;
|
||||
import org.jclouds.blobstore.functions.ThrowKeyNotFoundOn404;
|
||||
import org.jclouds.http.functions.ParseETagHeader;
|
||||
import org.jclouds.http.functions.ReturnFalseOn404;
|
||||
import org.jclouds.http.options.GetOptions;
|
||||
import org.jclouds.rest.annotations.BinderParam;
|
||||
import org.jclouds.rest.annotations.Endpoint;
|
||||
import org.jclouds.rest.annotations.ExceptionParser;
|
||||
import org.jclouds.rest.annotations.HostPrefixParam;
|
||||
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;
|
||||
|
||||
/**
|
||||
* 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 wrapped in an {@link ExecutionException} as documented in {@link Future#get()}.
|
||||
*
|
||||
* @author Adrian Cole
|
||||
* @author James Murty
|
||||
* @see <a href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/RESTAPI.html" />
|
||||
*/
|
||||
@VirtualHost
|
||||
@SkipEncoding('/')
|
||||
@RequestFilters(RequestAuthorizeSignature.class)
|
||||
@Endpoint(S3.class)
|
||||
public interface S3BlobStore extends BlobStore<BucketMetadata, ObjectMetadata, S3Object> {
|
||||
|
||||
/**
|
||||
* Retrieves the S3Object associated with the Key or {@link Blob <ObjectMetadata>#NOT_FOUND} if
|
||||
* not available;
|
||||
*
|
||||
* <p/>
|
||||
* To use GET, you must have READ access to the object. If READ access is granted to the
|
||||
* 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.
|
||||
*
|
||||
* <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>
|
||||
* </ul>
|
||||
*
|
||||
* @param bucketName
|
||||
* namespace of the object you are retrieving
|
||||
* @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.
|
||||
*
|
||||
* @throws org.jclouds.http.HttpResponseException
|
||||
* if the conditions requested set were not satisfied by the object on the server.
|
||||
* @see #getBlob(String, String)
|
||||
* @see GetObjectOptions
|
||||
*/
|
||||
@GET
|
||||
@Path("{key}")
|
||||
@ExceptionParser(ThrowKeyNotFoundOn404.class)
|
||||
@ResponseParser(ParseObjectFromHeadersAndHttpContent.class)
|
||||
Future<S3Object> getBlob(@HostPrefixParam String bucketName, @PathParam("key") String key);
|
||||
|
||||
@GET
|
||||
@Path("{key}")
|
||||
@ExceptionParser(ThrowKeyNotFoundOn404.class)
|
||||
@ResponseParser(ParseObjectFromHeadersAndHttpContent.class)
|
||||
Future<S3Object> getBlob(@HostPrefixParam String bucketName, @PathParam("key") String key,
|
||||
GetOptions options);
|
||||
|
||||
/**
|
||||
* Retrieves the {@link org.jclouds.aws.s3.domain.ObjectMetadata metadata} of the object
|
||||
* associated with the key or {@link org.jclouds.aws.s3.domain.ObjectMetadata#NOT_FOUND} if not
|
||||
* available.
|
||||
*
|
||||
* <p/>
|
||||
* The HEAD operation is used to retrieve information about a specific object or object size,
|
||||
* without actually fetching the object itself. This is useful if you're only interested in the
|
||||
* 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.aws.s3.domain.ObjectMetadata#NOT_FOUND} if not present;
|
||||
* @see #getBlob(String, String)
|
||||
* @see <a
|
||||
* href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?RESTObjectHEAD.html"
|
||||
* />
|
||||
*/
|
||||
@HEAD
|
||||
@Path("{key}")
|
||||
@ExceptionParser(ThrowKeyNotFoundOn404.class)
|
||||
@ResponseParser(ParseObjectMetadataFromHeaders.class)
|
||||
ObjectMetadata blobMetadata(@HostPrefixParam String bucketName, @PathParam("key") String key);
|
||||
|
||||
/**
|
||||
* Removes the object and metadata associated with the key.
|
||||
* <p/>
|
||||
* The DELETE request operation removes the specified object from Amazon S3. Once deleted, there
|
||||
* is no method to restore or undelete an object.
|
||||
*
|
||||
*
|
||||
* @param bucketName
|
||||
* namespace of the object you are deleting
|
||||
* @param key
|
||||
* unique key in the s3Bucket identifying the object
|
||||
* @return true if deleted
|
||||
* @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" />
|
||||
*/
|
||||
@DELETE
|
||||
@Path("{key}")
|
||||
@ExceptionParser(ReturnVoidOnNotFoundOr404.class)
|
||||
Future<Void> removeBlob(@HostPrefixParam String bucketName, @PathParam("key") String key);
|
||||
|
||||
@PUT
|
||||
@Path("{key}")
|
||||
@ResponseParser(ParseETagHeader.class)
|
||||
Future<String> putBlob(
|
||||
@HostPrefixParam String bucketName,
|
||||
@PathParam("key") @ParamParser(BlobName.class) @BinderParam(BindS3ObjectToEntity.class) S3Object object);
|
||||
|
||||
@PUT
|
||||
@Path("/")
|
||||
@ExceptionParser(ReturnTrueIfBucketAlreadyOwnedByYou.class)
|
||||
Future<Boolean> createContainer(@HostPrefixParam String bucketName);
|
||||
|
||||
/**
|
||||
* Deletes the bucket, if it is empty.
|
||||
* <p/>
|
||||
* The DELETE request operation deletes the bucket named in the URI. All objects in the bucket
|
||||
* must be deleted before the bucket itself can be deleted.
|
||||
* <p />
|
||||
* Only the owner of a bucket can delete it, regardless of the bucket's access control policy.
|
||||
*
|
||||
*
|
||||
* @param bucketName
|
||||
* what to delete
|
||||
* @see org.jclouds.aws.s3.commands.DeleteBucket
|
||||
* @see <a href=
|
||||
* "http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?RESTBucketDELETE.html"
|
||||
* />
|
||||
*/
|
||||
@DELETE
|
||||
@Path("/")
|
||||
@ExceptionParser(ClearAndDeleteBucketIfNotEmpty.class)
|
||||
Future<Void> deleteContainer(@HostPrefixParam String bucketName);
|
||||
|
||||
/**
|
||||
* Issues a HEAD command to determine if the bucket exists or not.
|
||||
*/
|
||||
@HEAD
|
||||
@Path("/")
|
||||
@QueryParams(keys = "max-keys", values = "0")
|
||||
@ExceptionParser(ReturnFalseOn404.class)
|
||||
boolean containerExists(@HostPrefixParam String bucketName);
|
||||
|
||||
/**
|
||||
* Retrieve a <code>S3Bucket</code> listing. A GET request operation using a bucket URI lists
|
||||
* information about the objects in the bucket. You can use {@link ListBucketOptions} to control
|
||||
* the amount of S3Objects to return.
|
||||
* <p />
|
||||
* 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.
|
||||
* @see ListBucketOptions
|
||||
*
|
||||
* @see <a
|
||||
* href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?RESTBucketGET.html"
|
||||
* />
|
||||
*/
|
||||
@GET
|
||||
@Path("/")
|
||||
@XMLResponseParser(ListBucketHandler.class)
|
||||
Future<ListBucketResponse> listBlobs(@HostPrefixParam String bucketName);
|
||||
|
||||
/**
|
||||
* 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"
|
||||
* />
|
||||
*
|
||||
*/
|
||||
@GET
|
||||
@XMLResponseParser(ListAllMyBucketsHandler.class)
|
||||
@Path("/")
|
||||
SortedSet<BucketMetadata> listContainers();
|
||||
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
|
@ -23,6 +23,8 @@
|
|||
*/
|
||||
package org.jclouds.aws.s3;
|
||||
|
||||
import static org.jclouds.blobstore.attr.BlobScopes.CONTAINER;
|
||||
|
||||
import java.util.SortedSet;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Future;
|
||||
|
@ -42,6 +44,7 @@ import org.jclouds.aws.s3.domain.ListBucketResponse;
|
|||
import org.jclouds.aws.s3.domain.ObjectMetadata;
|
||||
import org.jclouds.aws.s3.domain.S3Object;
|
||||
import org.jclouds.aws.s3.filters.RequestAuthorizeSignature;
|
||||
import org.jclouds.aws.s3.functions.ObjectKey;
|
||||
import org.jclouds.aws.s3.functions.ParseObjectFromHeadersAndHttpContent;
|
||||
import org.jclouds.aws.s3.functions.ParseObjectMetadataFromHeaders;
|
||||
import org.jclouds.aws.s3.functions.ReturnTrueIfBucketAlreadyOwnedByYou;
|
||||
|
@ -54,8 +57,7 @@ import org.jclouds.aws.s3.xml.AccessControlListHandler;
|
|||
import org.jclouds.aws.s3.xml.CopyObjectHandler;
|
||||
import org.jclouds.aws.s3.xml.ListAllMyBucketsHandler;
|
||||
import org.jclouds.aws.s3.xml.ListBucketHandler;
|
||||
import org.jclouds.blobstore.domain.Blob;
|
||||
import org.jclouds.blobstore.functions.BlobName;
|
||||
import org.jclouds.blobstore.attr.BlobScope;
|
||||
import org.jclouds.blobstore.functions.ReturnVoidOnNotFoundOr404;
|
||||
import org.jclouds.blobstore.functions.ThrowContainerNotFoundOn404;
|
||||
import org.jclouds.blobstore.functions.ThrowKeyNotFoundOn404;
|
||||
|
@ -89,11 +91,16 @@ import org.jclouds.rest.annotations.XMLResponseParser;
|
|||
@SkipEncoding('/')
|
||||
@RequestFilters(RequestAuthorizeSignature.class)
|
||||
@Endpoint(S3.class)
|
||||
public interface S3Connection {
|
||||
@BlobScope(CONTAINER)
|
||||
public interface S3Client {
|
||||
|
||||
/**
|
||||
* Retrieves the S3Object associated with the Key or {@link Blob <ObjectMetadata>#NOT_FOUND} if
|
||||
* not available;
|
||||
* Creates a default implementation of S3Object
|
||||
*/
|
||||
public S3Object newS3Object();
|
||||
|
||||
/**
|
||||
* Retrieves the S3Object associated with the Key or KeyNotFoundException if not available;
|
||||
*
|
||||
* <p/>
|
||||
* To use GET, you must have READ access to the object. If READ access is granted to the
|
||||
|
@ -129,8 +136,9 @@ public interface S3Connection {
|
|||
GetOptions... options);
|
||||
|
||||
/**
|
||||
* Retrieves the {@link org.jclouds.aws.s3.domain.ObjectMetadata metadata} of the object
|
||||
* associated with the key or {@link org.jclouds.aws.s3.domain.ObjectMetadata#NOT_FOUND} if not
|
||||
* Retrieves the {@link org.jclouds.aws.s3.domain.internal.BucketListObjectMetadata metadata} of
|
||||
* the object associated with the key or
|
||||
* {@link org.jclouds.aws.s3.domain.internal.BucketListObjectMetadata#NOT_FOUND} if not
|
||||
* available.
|
||||
*
|
||||
* <p/>
|
||||
|
@ -144,7 +152,8 @@ public interface S3Connection {
|
|||
* @param key
|
||||
* unique key in the s3Bucket identifying the object
|
||||
* @return metadata associated with the key or
|
||||
* {@link org.jclouds.aws.s3.domain.ObjectMetadata#NOT_FOUND} if not present;
|
||||
* {@link org.jclouds.aws.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"
|
||||
|
@ -206,7 +215,7 @@ public interface S3Connection {
|
|||
@ResponseParser(ParseETagHeader.class)
|
||||
Future<String> putObject(
|
||||
@HostPrefixParam String bucketName,
|
||||
@PathParam("key") @ParamParser(BlobName.class) @BinderParam(BindS3ObjectToEntity.class) S3Object object,
|
||||
@PathParam("key") @ParamParser(ObjectKey.class) @BinderParam(BindS3ObjectToEntity.class) S3Object object,
|
||||
PutObjectOptions... options);
|
||||
|
||||
/**
|
||||
|
@ -303,7 +312,7 @@ public interface S3Connection {
|
|||
@GET
|
||||
@XMLResponseParser(ListAllMyBucketsHandler.class)
|
||||
@Path("/")
|
||||
SortedSet<BucketMetadata> listOwnedBuckets();
|
||||
Future<? extends SortedSet<BucketMetadata>> listOwnedBuckets();
|
||||
|
||||
/**
|
||||
* Copies one object to another bucket, retaining UserMetadata from the source. The destination
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
|
@ -23,26 +23,15 @@
|
|||
*/
|
||||
package org.jclouds.aws.s3;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static org.jclouds.aws.reference.AWSConstants.PROPERTY_AWS_ACCESSKEYID;
|
||||
import static org.jclouds.aws.reference.AWSConstants.PROPERTY_AWS_SECRETACCESSKEY;
|
||||
import static org.jclouds.aws.s3.reference.S3Constants.PROPERTY_S3_SESSIONINTERVAL;
|
||||
import static org.jclouds.blobstore.reference.BlobStoreConstants.PROPERTY_USER_METADATA_PREFIX;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
|
||||
import org.jclouds.aws.s3.config.RestS3ConnectionModule;
|
||||
import org.jclouds.aws.s3.config.S3ContextModule;
|
||||
import org.jclouds.aws.s3.domain.BucketMetadata;
|
||||
import org.jclouds.aws.s3.domain.ObjectMetadata;
|
||||
import org.jclouds.aws.s3.domain.S3Object;
|
||||
import org.jclouds.aws.s3.reference.S3Constants;
|
||||
import org.jclouds.blobstore.BlobStoreContextBuilder;
|
||||
import org.jclouds.aws.s3.config.S3RestClientModule;
|
||||
import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule;
|
||||
import org.jclouds.logging.jdk.config.JDKLoggingModule;
|
||||
import org.jclouds.rest.RestContextBuilder;
|
||||
|
||||
import com.google.inject.Injector;
|
||||
import com.google.inject.Module;
|
||||
|
@ -61,98 +50,12 @@ import com.google.inject.TypeLiteral;
|
|||
* @author Adrian Cole, Andrew Newdigate
|
||||
* @see S3Context
|
||||
*/
|
||||
public class S3ContextBuilder extends
|
||||
BlobStoreContextBuilder<S3Connection, BucketMetadata, ObjectMetadata, S3Object> {
|
||||
public class S3ContextBuilder extends RestContextBuilder<S3Client> {
|
||||
|
||||
@Override
|
||||
public S3Context buildContext() {
|
||||
return this.buildInjector().getInstance(S3Context.class);
|
||||
}
|
||||
|
||||
public S3ContextBuilder(Properties props) {
|
||||
super(new TypeLiteral<S3Connection>() {
|
||||
}, new TypeLiteral<BucketMetadata>() {
|
||||
}, new TypeLiteral<ObjectMetadata>() {
|
||||
}, new TypeLiteral<S3Object>() {
|
||||
super(new TypeLiteral<S3Client>() {
|
||||
}, props);
|
||||
properties.setProperty(S3Constants.PROPERTY_S3_ENDPOINT, "https://s3.amazonaws.com");
|
||||
properties.setProperty(PROPERTY_USER_METADATA_PREFIX, "x-amz-meta-");
|
||||
if (!properties.containsKey(PROPERTY_S3_SESSIONINTERVAL))
|
||||
this.withTimeStampExpiration(60);
|
||||
}
|
||||
|
||||
public S3ContextBuilder(String id, String secret) {
|
||||
this(new Properties());
|
||||
properties.setProperty(PROPERTY_AWS_ACCESSKEYID, checkNotNull(id, "awsAccessKeyId"));
|
||||
properties.setProperty(PROPERTY_AWS_SECRETACCESSKEY, checkNotNull(secret,
|
||||
"awsSecretAccessKey"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public S3ContextBuilder relaxSSLHostname() {
|
||||
return (S3ContextBuilder) super.relaxSSLHostname();
|
||||
}
|
||||
|
||||
@Override
|
||||
public S3ContextBuilder withRequestTimeout(long milliseconds) {
|
||||
return (S3ContextBuilder) super.withRequestTimeout(milliseconds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public S3ContextBuilder withExecutorService(ExecutorService service) {
|
||||
return (S3ContextBuilder) super.withExecutorService(service);
|
||||
}
|
||||
|
||||
@Override
|
||||
public S3ContextBuilder withHttpMaxRedirects(int httpMaxRedirects) {
|
||||
return (S3ContextBuilder) super.withHttpMaxRedirects(httpMaxRedirects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public S3ContextBuilder withHttpMaxRetries(int httpMaxRetries) {
|
||||
return (S3ContextBuilder) super.withHttpMaxRetries(httpMaxRetries);
|
||||
}
|
||||
|
||||
@Override
|
||||
public S3ContextBuilder withModule(Module module) {
|
||||
return (S3ContextBuilder) super.withModule(module);
|
||||
}
|
||||
|
||||
@Override
|
||||
public S3ContextBuilder withModules(Module... modules) {
|
||||
return (S3ContextBuilder) super.withModules(modules);
|
||||
}
|
||||
|
||||
@Override
|
||||
public S3ContextBuilder withPoolIoWorkerThreads(int poolIoWorkerThreads) {
|
||||
return (S3ContextBuilder) super.withPoolIoWorkerThreads(poolIoWorkerThreads);
|
||||
}
|
||||
|
||||
@Override
|
||||
public S3ContextBuilder withPoolMaxConnectionReuse(int poolMaxConnectionReuse) {
|
||||
return (S3ContextBuilder) super.withPoolMaxConnectionReuse(poolMaxConnectionReuse);
|
||||
}
|
||||
|
||||
@Override
|
||||
public S3ContextBuilder withPoolMaxConnections(int poolMaxConnections) {
|
||||
return (S3ContextBuilder) super.withPoolMaxConnections(poolMaxConnections);
|
||||
}
|
||||
|
||||
@Override
|
||||
public S3ContextBuilder withPoolMaxSessionFailures(int poolMaxSessionFailures) {
|
||||
return (S3ContextBuilder) super.withPoolMaxSessionFailures(poolMaxSessionFailures);
|
||||
}
|
||||
|
||||
@Override
|
||||
public S3ContextBuilder withPoolRequestInvokerThreads(int poolRequestInvokerThreads) {
|
||||
return (S3ContextBuilder) super.withPoolRequestInvokerThreads(poolRequestInvokerThreads);
|
||||
}
|
||||
|
||||
@Override
|
||||
public S3ContextBuilder withEndpoint(URI endpoint) {
|
||||
properties.setProperty(S3Constants.PROPERTY_S3_ENDPOINT, checkNotNull(endpoint, "endpoint")
|
||||
.toString());
|
||||
return (S3ContextBuilder) this;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -161,12 +64,18 @@ public class S3ContextBuilder extends
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void addConnectionModule(List<Module> modules) {
|
||||
modules.add(new RestS3ConnectionModule());
|
||||
protected void addClientModule(List<Module> modules) {
|
||||
modules.add(new S3RestClientModule());
|
||||
}
|
||||
|
||||
public S3ContextBuilder withTimeStampExpiration(long seconds) {
|
||||
getProperties().setProperty(PROPERTY_S3_SESSIONINTERVAL, seconds + "");
|
||||
return this;
|
||||
@Override
|
||||
public S3ContextBuilder withExecutorService(ExecutorService service) {
|
||||
return (S3ContextBuilder) super.withExecutorService(service);
|
||||
}
|
||||
|
||||
@Override
|
||||
public S3ContextBuilder withModules(Module... modules) {
|
||||
return (S3ContextBuilder) super.withModules(modules);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
|
@ -24,9 +24,11 @@
|
|||
package org.jclouds.aws.s3;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule;
|
||||
import org.jclouds.logging.jdk.config.JDKLoggingModule;
|
||||
import org.jclouds.rest.RestContext;
|
||||
|
||||
import com.google.inject.Module;
|
||||
|
||||
|
@ -39,20 +41,25 @@ import com.google.inject.Module;
|
|||
* If no <code>Module</code>s are specified, the default {@link JDKLoggingModule logging} and
|
||||
* {@link JavaUrlHttpCommandExecutorServiceModule http transports} will be installed.
|
||||
*
|
||||
* @author Adrian Cole, Andrew Newdigate
|
||||
* @see S3Context
|
||||
* @author Adrian Cole
|
||||
* @see S3Client
|
||||
*/
|
||||
public class S3ContextFactory {
|
||||
|
||||
public static S3Context createContext(
|
||||
String awsAccessKeyId, String awsSecretAccessKey, Module... modules) {
|
||||
return new S3ContextBuilder(awsAccessKeyId, awsSecretAccessKey).withModules(modules)
|
||||
public static RestContext<S3Client> createContext(Properties properties, Module... modules) {
|
||||
return new S3ContextBuilder(new S3PropertiesBuilder(properties).build()).withModules(modules)
|
||||
.buildContext();
|
||||
}
|
||||
|
||||
public static S3Context createContext(
|
||||
URI endpoint, String awsAccessKeyId, String awsSecretAccessKey, Module... modules) {
|
||||
return new S3ContextBuilder(awsAccessKeyId, awsSecretAccessKey).withEndpoint(endpoint)
|
||||
.withModules(modules).buildContext();
|
||||
public static RestContext<S3Client> createContext(String awsAccessKeyId,
|
||||
String awsSecretAccessKey, Module... modules) {
|
||||
return new S3ContextBuilder(new S3PropertiesBuilder(awsAccessKeyId, awsSecretAccessKey)
|
||||
.build()).withModules(modules).buildContext();
|
||||
}
|
||||
|
||||
public static RestContext<S3Client> createContext(URI endpoint, String awsAccessKeyId,
|
||||
String awsSecretAccessKey, Module... modules) {
|
||||
return new S3ContextBuilder(new S3PropertiesBuilder(awsAccessKeyId, awsSecretAccessKey)
|
||||
.withEndpoint(endpoint).build()).withModules(modules).buildContext();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,80 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
package org.jclouds.aws.s3;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static org.jclouds.aws.reference.AWSConstants.PROPERTY_AWS_ACCESSKEYID;
|
||||
import static org.jclouds.aws.reference.AWSConstants.PROPERTY_AWS_SECRETACCESSKEY;
|
||||
import static org.jclouds.aws.s3.reference.S3Constants.PROPERTY_S3_METADATA_PREFIX;
|
||||
import static org.jclouds.aws.s3.reference.S3Constants.PROPERTY_S3_SESSIONINTERVAL;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.jclouds.aws.s3.reference.S3Constants;
|
||||
import org.jclouds.http.HttpPropertiesBuilder;
|
||||
|
||||
/**
|
||||
* Builds properties used in S3 Connections
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class S3PropertiesBuilder extends HttpPropertiesBuilder {
|
||||
@Override
|
||||
protected Properties defaultProperties() {
|
||||
Properties properties = super.defaultProperties();
|
||||
properties.setProperty(S3Constants.PROPERTY_S3_ENDPOINT, "https://s3.amazonaws.com");
|
||||
properties.setProperty(PROPERTY_S3_METADATA_PREFIX, "x-amz-meta-");
|
||||
properties.setProperty(PROPERTY_S3_SESSIONINTERVAL, "60");
|
||||
return properties;
|
||||
}
|
||||
|
||||
public S3PropertiesBuilder(Properties properties) {
|
||||
super(properties);
|
||||
}
|
||||
|
||||
public S3PropertiesBuilder(String id, String secret) {
|
||||
super();
|
||||
withCredentials(id, secret);
|
||||
}
|
||||
|
||||
public S3PropertiesBuilder withCredentials(String id, String secret) {
|
||||
properties.setProperty(PROPERTY_AWS_ACCESSKEYID, checkNotNull(id, "awsAccessKeyId"));
|
||||
properties.setProperty(PROPERTY_AWS_SECRETACCESSKEY, checkNotNull(secret,
|
||||
"awsSecretAccessKey"));
|
||||
return this;
|
||||
}
|
||||
|
||||
public S3PropertiesBuilder withEndpoint(URI endpoint) {
|
||||
properties.setProperty(S3Constants.PROPERTY_S3_ENDPOINT, checkNotNull(endpoint, "endpoint")
|
||||
.toString());
|
||||
return this;
|
||||
}
|
||||
|
||||
public S3PropertiesBuilder withTimeStampExpiration(long seconds) {
|
||||
properties.setProperty(PROPERTY_S3_SESSIONINTERVAL, seconds + "");
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
|
@ -24,45 +24,49 @@
|
|||
package org.jclouds.aws.s3.binders;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static org.jclouds.blobstore.reference.BlobStoreConstants.PROPERTY_USER_METADATA_PREFIX;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.ws.rs.core.HttpHeaders;
|
||||
|
||||
import org.jclouds.aws.s3.blobstore.functions.ObjectToBlob;
|
||||
import org.jclouds.aws.s3.domain.S3Object;
|
||||
import org.jclouds.blobstore.binders.BindBlobToEntityAndUserMetadataToHeadersWithPrefix;
|
||||
import org.jclouds.blobstore.domain.Blob;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.rest.Binder;
|
||||
|
||||
public class BindS3ObjectToEntity implements Binder {
|
||||
private final BindBlobToEntityAndUserMetadataToHeadersWithPrefix blobBinder;
|
||||
private final ObjectToBlob object2Blob;
|
||||
|
||||
public class BindS3ObjectToEntity extends BindBlobToEntityAndUserMetadataToHeadersWithPrefix {
|
||||
@Inject
|
||||
public BindS3ObjectToEntity(@Named(PROPERTY_USER_METADATA_PREFIX) String metadataPrefix) {
|
||||
super(metadataPrefix);
|
||||
public BindS3ObjectToEntity(ObjectToBlob object2Blob,
|
||||
BindBlobToEntityAndUserMetadataToHeadersWithPrefix blobBinder) {
|
||||
this.blobBinder = blobBinder;
|
||||
this.object2Blob = object2Blob;
|
||||
}
|
||||
|
||||
public void bindToRequest(HttpRequest request, Object entity) {
|
||||
Blob<?> object = (Blob<?>) entity;
|
||||
checkArgument(object.getMetadata().getSize() >= 0, "size must be set");
|
||||
checkArgument(object.getContentLength() <= 5 * 1024 * 1024 * 1024,
|
||||
S3Object s3Object = (S3Object) entity;
|
||||
checkNotNull(s3Object.getContentLength(), "contentLength");
|
||||
checkArgument(s3Object.getContentLength() <= 5 * 1024 * 1024 * 1024,
|
||||
"maximum size for put object is 5GB");
|
||||
if (object instanceof S3Object) {
|
||||
S3Object s3Object = (S3Object) object;
|
||||
if (s3Object.getMetadata().getCacheControl() != null) {
|
||||
request.getHeaders().put(HttpHeaders.CACHE_CONTROL,
|
||||
s3Object.getMetadata().getCacheControl());
|
||||
}
|
||||
blobBinder.bindToRequest(request, object2Blob.apply(s3Object));
|
||||
|
||||
if (s3Object.getMetadata().getContentDisposition() != null) {
|
||||
request.getHeaders().put("Content-Disposition",
|
||||
s3Object.getMetadata().getContentDisposition());
|
||||
}
|
||||
|
||||
if (s3Object.getMetadata().getContentEncoding() != null) {
|
||||
request.getHeaders().put(HttpHeaders.CONTENT_ENCODING,
|
||||
s3Object.getMetadata().getContentEncoding());
|
||||
}
|
||||
if (s3Object.getMetadata().getCacheControl() != null) {
|
||||
request.getHeaders().put(HttpHeaders.CACHE_CONTROL,
|
||||
s3Object.getMetadata().getCacheControl());
|
||||
}
|
||||
super.bindToRequest(request, entity);
|
||||
|
||||
if (s3Object.getMetadata().getContentDisposition() != null) {
|
||||
request.getHeaders().put("Content-Disposition",
|
||||
s3Object.getMetadata().getContentDisposition());
|
||||
}
|
||||
|
||||
if (s3Object.getMetadata().getContentEncoding() != null) {
|
||||
request.getHeaders().put(HttpHeaders.CONTENT_ENCODING,
|
||||
s3Object.getMetadata().getContentEncoding());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,181 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
package org.jclouds.aws.s3.blobstore;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static org.jclouds.blobstore.options.ListOptions.Builder.recursive;
|
||||
|
||||
import java.util.SortedSet;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.jclouds.aws.s3.S3Client;
|
||||
import org.jclouds.aws.s3.blobstore.functions.BlobToObject;
|
||||
import org.jclouds.aws.s3.blobstore.functions.BlobToObjectGetOptions;
|
||||
import org.jclouds.aws.s3.blobstore.functions.BucketToResourceList;
|
||||
import org.jclouds.aws.s3.blobstore.functions.BucketToResourceMetadata;
|
||||
import org.jclouds.aws.s3.blobstore.functions.ContainerToBucketListOptions;
|
||||
import org.jclouds.aws.s3.blobstore.functions.ObjectToBlob;
|
||||
import org.jclouds.aws.s3.blobstore.functions.ObjectToBlobMetadata;
|
||||
import org.jclouds.aws.s3.domain.BucketMetadata;
|
||||
import org.jclouds.aws.s3.domain.ListBucketResponse;
|
||||
import org.jclouds.aws.s3.domain.S3Object;
|
||||
import org.jclouds.aws.s3.options.ListBucketOptions;
|
||||
import org.jclouds.blobstore.BlobStore;
|
||||
import org.jclouds.blobstore.attr.ConsistencyModel;
|
||||
import org.jclouds.blobstore.attr.ConsistencyModels;
|
||||
import org.jclouds.blobstore.domain.Blob;
|
||||
import org.jclouds.blobstore.domain.BlobMetadata;
|
||||
import org.jclouds.blobstore.domain.BoundedSortedSet;
|
||||
import org.jclouds.blobstore.domain.ResourceMetadata;
|
||||
import org.jclouds.blobstore.options.ListOptions;
|
||||
import org.jclouds.blobstore.strategy.ClearListStrategy;
|
||||
import org.jclouds.concurrent.FutureFunctionWrapper;
|
||||
import org.jclouds.http.options.GetOptions;
|
||||
import org.jclouds.logging.Logger.LoggerFactory;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
@ConsistencyModel(ConsistencyModels.EVENTUAL)
|
||||
public class S3BlobStore implements BlobStore {
|
||||
private final S3Client connection;
|
||||
private final Blob.Factory blobFactory;
|
||||
private final LoggerFactory logFactory;
|
||||
private final ClearListStrategy clearContainerStrategy;
|
||||
private final ObjectToBlobMetadata object2BlobMd;
|
||||
private final ObjectToBlob object2Blob;
|
||||
private final BlobToObject blob2Object;
|
||||
private final ContainerToBucketListOptions container2BucketListOptions;
|
||||
private final BlobToObjectGetOptions blob2ObjectGetOptions;
|
||||
private final BucketToResourceMetadata bucket2ResourceMd;
|
||||
private final BucketToResourceList bucket2ResourceList;
|
||||
private final ExecutorService service;
|
||||
|
||||
@Inject
|
||||
private S3BlobStore(S3Client connection, Blob.Factory blobFactory, LoggerFactory logFactory,
|
||||
ClearListStrategy clearContainerStrategy, ObjectToBlobMetadata object2BlobMd,
|
||||
ObjectToBlob object2Blob, BlobToObject blob2Object,
|
||||
ContainerToBucketListOptions container2BucketListOptions,
|
||||
BlobToObjectGetOptions blob2ObjectGetOptions,
|
||||
BucketToResourceMetadata bucket2ResourceMd, BucketToResourceList bucket2ResourceList,
|
||||
ExecutorService service) {
|
||||
this.connection = checkNotNull(connection, "connection");
|
||||
this.blobFactory = checkNotNull(blobFactory, "blobFactory");
|
||||
this.logFactory = checkNotNull(logFactory, "logFactory");
|
||||
this.clearContainerStrategy = checkNotNull(clearContainerStrategy, "clearContainerStrategy");
|
||||
this.object2BlobMd = checkNotNull(object2BlobMd, "object2BlobMd");
|
||||
this.object2Blob = checkNotNull(object2Blob, "object2Blob");
|
||||
this.blob2Object = checkNotNull(blob2Object, "blob2Object");
|
||||
this.container2BucketListOptions = checkNotNull(container2BucketListOptions,
|
||||
"container2BucketListOptions");
|
||||
this.blob2ObjectGetOptions = checkNotNull(blob2ObjectGetOptions, "blob2ObjectGetOptions");
|
||||
this.bucket2ResourceMd = checkNotNull(bucket2ResourceMd, "bucket2ResourceMd");
|
||||
this.bucket2ResourceList = checkNotNull(bucket2ResourceList, "bucket2ResourceList");
|
||||
this.service = checkNotNull(service, "service");
|
||||
}
|
||||
|
||||
protected <F, T> Future<T> wrapFuture(Future<? extends F> future, Function<F, T> function) {
|
||||
return new FutureFunctionWrapper<F, T>(future, function, logFactory.getLogger(function
|
||||
.getClass().getName()));
|
||||
}
|
||||
|
||||
/**
|
||||
* This implementation uses the S3 HEAD Object command to return the result
|
||||
*/
|
||||
public BlobMetadata blobMetadata(String container, String key) {
|
||||
return object2BlobMd.apply(connection.headObject(container, key));
|
||||
}
|
||||
|
||||
public Future<Void> clearContainer(final String container) {
|
||||
return service.submit(new Callable<Void>() {
|
||||
|
||||
public Void call() throws Exception {
|
||||
clearContainerStrategy.execute(container, recursive());
|
||||
return null;
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
public Future<Boolean> createContainer(String container) {
|
||||
return connection.putBucketIfNotExists(container);
|
||||
}
|
||||
|
||||
public Future<Void> deleteContainer(final String container) {
|
||||
return service.submit(new Callable<Void>() {
|
||||
|
||||
public Void call() throws Exception {
|
||||
clearContainerStrategy.execute(container, recursive());
|
||||
connection.deleteBucketIfEmpty(container).get();
|
||||
return null;
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
public boolean exists(String container) {
|
||||
return connection.bucketExists(container);
|
||||
}
|
||||
|
||||
public Future<Blob> getBlob(String container, String key,
|
||||
org.jclouds.blobstore.options.GetOptions... optionsList) {
|
||||
GetOptions httpOptions = blob2ObjectGetOptions.apply(optionsList);
|
||||
Future<S3Object> returnVal = connection.getObject(container, key, httpOptions);
|
||||
return wrapFuture(returnVal, object2Blob);
|
||||
}
|
||||
|
||||
public Future<? extends SortedSet<? extends ResourceMetadata>> list() {
|
||||
return wrapFuture(connection.listOwnedBuckets(),
|
||||
new Function<SortedSet<BucketMetadata>, SortedSet<? extends ResourceMetadata>>() {
|
||||
public SortedSet<? extends ResourceMetadata> apply(SortedSet<BucketMetadata> from) {
|
||||
return Sets.newTreeSet(Iterables.transform(from, bucket2ResourceMd));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Future<? extends BoundedSortedSet<? extends ResourceMetadata>> list(String container,
|
||||
ListOptions... optionsList) {
|
||||
ListBucketOptions httpOptions = container2BucketListOptions.apply(optionsList);
|
||||
Future<ListBucketResponse> returnVal = connection.listBucket(container, httpOptions);
|
||||
return wrapFuture(returnVal, bucket2ResourceList);
|
||||
}
|
||||
|
||||
public Future<String> putBlob(String container, Blob blob) {
|
||||
return connection.putObject(container, blob2Object.apply(blob));
|
||||
}
|
||||
|
||||
public Future<Void> removeBlob(String container, String key) {
|
||||
return connection.deleteObject(container, key);
|
||||
}
|
||||
|
||||
public Blob newBlob() {
|
||||
return blobFactory.create(null);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,80 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
package org.jclouds.aws.s3.blobstore;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
|
||||
import org.jclouds.aws.s3.S3Client;
|
||||
import org.jclouds.aws.s3.blobstore.config.S3BlobStoreContextModule;
|
||||
import org.jclouds.aws.s3.config.S3RestClientModule;
|
||||
import org.jclouds.blobstore.BlobStoreContextBuilder;
|
||||
import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule;
|
||||
import org.jclouds.logging.jdk.config.JDKLoggingModule;
|
||||
|
||||
import com.google.inject.Injector;
|
||||
import com.google.inject.Module;
|
||||
import com.google.inject.TypeLiteral;
|
||||
|
||||
/**
|
||||
* Creates {@link S3BlobStoreContext} or {@link Injector} instances based on the most commonly
|
||||
* requested arguments.
|
||||
* <p/>
|
||||
* Note that Threadsafe objects will be bound as singletons to the Injector or Context provided.
|
||||
* <p/>
|
||||
* <p/>
|
||||
* If no <code>Module</code>s are specified, the default {@link JDKLoggingModule logging} and
|
||||
* {@link JavaUrlHttpCommandExecutorServiceModule http transports} will be installed.
|
||||
*
|
||||
* @author Adrian Cole, Andrew Newdigate
|
||||
* @see S3BlobStoreContext
|
||||
*/
|
||||
public class S3BlobStoreContextBuilder extends BlobStoreContextBuilder<S3Client> {
|
||||
|
||||
public S3BlobStoreContextBuilder(Properties props) {
|
||||
super(new TypeLiteral<S3Client>() {
|
||||
}, props);
|
||||
}
|
||||
|
||||
@Override
|
||||
public S3BlobStoreContextBuilder withExecutorService(ExecutorService service) {
|
||||
return (S3BlobStoreContextBuilder) super.withExecutorService(service);
|
||||
}
|
||||
|
||||
@Override
|
||||
public S3BlobStoreContextBuilder withModules(Module... modules) {
|
||||
return (S3BlobStoreContextBuilder) super.withModules(modules);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addContextModule(List<Module> modules) {
|
||||
modules.add(new S3BlobStoreContextModule());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addClientModule(List<Module> modules) {
|
||||
modules.add(new S3RestClientModule());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
package org.jclouds.aws.s3.blobstore;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.jclouds.aws.s3.S3Client;
|
||||
import org.jclouds.blobstore.BlobStoreContext;
|
||||
import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule;
|
||||
import org.jclouds.logging.jdk.config.JDKLoggingModule;
|
||||
|
||||
import com.google.inject.Module;
|
||||
|
||||
/**
|
||||
* Creates {@link S3BlobStoreContext} instances based on the most commonly requested arguments.
|
||||
* <p/>
|
||||
* Note that Threadsafe objects will be bound as singletons to the Injector or Context provided.
|
||||
* <p/>
|
||||
* <p/>
|
||||
* If no <code>Module</code>s are specified, the default {@link JDKLoggingModule logging} and
|
||||
* {@link JavaUrlHttpCommandExecutorServiceModule http transports} will be installed.
|
||||
*
|
||||
* @author Adrian Cole, Andrew Newdigate
|
||||
* @see S3BlobStoreContext
|
||||
*/
|
||||
public class S3BlobStoreContextFactory {
|
||||
public static BlobStoreContext<S3Client> createContext(Properties properties, Module... modules) {
|
||||
return new S3BlobStoreContextBuilder(new S3BlobStorePropertiesBuilder(properties).build())
|
||||
.withModules(modules).buildContext();
|
||||
}
|
||||
|
||||
public static BlobStoreContext<S3Client> createContext(String awsAccessKeyId,
|
||||
String awsSecretAccessKey, Module... modules) {
|
||||
return new S3BlobStoreContextBuilder(new S3BlobStorePropertiesBuilder(awsAccessKeyId,
|
||||
awsSecretAccessKey).build()).withModules(modules).buildContext();
|
||||
}
|
||||
|
||||
public static BlobStoreContext<S3Client> createContext(URI endpoint, String awsAccessKeyId,
|
||||
String awsSecretAccessKey, Module... modules) {
|
||||
return new S3BlobStoreContextBuilder(new S3BlobStorePropertiesBuilder(awsAccessKeyId,
|
||||
awsSecretAccessKey).withEndpoint(endpoint).build()).withModules(modules)
|
||||
.buildContext();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
package org.jclouds.aws.s3.blobstore;
|
||||
|
||||
import static org.jclouds.blobstore.reference.BlobStoreConstants.PROPERTY_USER_METADATA_PREFIX;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
import org.jclouds.aws.s3.S3PropertiesBuilder;
|
||||
import org.jclouds.blobstore.reference.BlobStoreConstants;
|
||||
|
||||
/**
|
||||
* Builds properties used in S3 Blob Stores
|
||||
*
|
||||
* @author Adrian Cole, Andrew Newdigate
|
||||
*/
|
||||
public class S3BlobStorePropertiesBuilder extends S3PropertiesBuilder {
|
||||
|
||||
public S3BlobStorePropertiesBuilder(String id, String secret) {
|
||||
super(id, secret);
|
||||
}
|
||||
|
||||
public S3BlobStorePropertiesBuilder(Properties properties) {
|
||||
super(properties);
|
||||
}
|
||||
|
||||
/**
|
||||
* longest time a single synchronous operation can take before throwing an exception.
|
||||
*/
|
||||
public S3BlobStorePropertiesBuilder withRequestTimeout(long milliseconds) {
|
||||
properties.setProperty(BlobStoreConstants.PROPERTY_BLOBSTORE_TIMEOUT, Long
|
||||
.toString(milliseconds));
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Properties defaultProperties() {
|
||||
Properties props = super.defaultProperties();
|
||||
props.setProperty(PROPERTY_USER_METADATA_PREFIX, "x-amz-meta-");
|
||||
return props;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
package org.jclouds.aws.s3.blobstore.config;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.aws.reference.AWSConstants;
|
||||
import org.jclouds.aws.s3.S3;
|
||||
import org.jclouds.aws.s3.S3Client;
|
||||
import org.jclouds.aws.s3.blobstore.S3BlobStore;
|
||||
import org.jclouds.aws.s3.config.S3ObjectModule;
|
||||
import org.jclouds.blobstore.BlobMap;
|
||||
import org.jclouds.blobstore.BlobStore;
|
||||
import org.jclouds.blobstore.BlobStoreContext;
|
||||
import org.jclouds.blobstore.InputStreamMap;
|
||||
import org.jclouds.blobstore.config.BlobStoreMapModule;
|
||||
import org.jclouds.blobstore.config.BlobStoreObjectModule;
|
||||
import org.jclouds.blobstore.internal.BlobStoreContextImpl;
|
||||
import org.jclouds.lifecycle.Closer;
|
||||
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Provides;
|
||||
|
||||
/**
|
||||
* Configures the {@link S3BlobStoreContext}; requires {@link S3BlobStore} bound.
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class S3BlobStoreContextModule extends AbstractModule {
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
install(new BlobStoreObjectModule());
|
||||
install(new BlobStoreMapModule());
|
||||
install(new S3ObjectModule());
|
||||
bind(BlobStore.class).to(S3BlobStore.class).asEagerSingleton();
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
BlobStoreContext<S3Client> provideContext(BlobMap.Factory blobMapFactory,
|
||||
InputStreamMap.Factory inputStreamMapFactory, Closer closer, BlobStore blobStore,
|
||||
S3Client defaultApi, @S3 URI endPoint,
|
||||
@Named(AWSConstants.PROPERTY_AWS_ACCESSKEYID) String account) {
|
||||
return new BlobStoreContextImpl<S3Client>(blobMapFactory, inputStreamMapFactory, closer,
|
||||
blobStore, defaultApi, endPoint, account);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
|
@ -21,43 +21,36 @@
|
|||
* under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
package org.jclouds.mezeo.pcs2.functions;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
package org.jclouds.aws.s3.blobstore.functions;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.blobstore.ContainerNotFoundException;
|
||||
import org.jclouds.util.Utils;
|
||||
import org.jclouds.aws.s3.domain.S3Object;
|
||||
import org.jclouds.blobstore.domain.Blob;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.ComputationException;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Singleton
|
||||
public class ContainerNameToResourceId implements Function<Object, String> {
|
||||
|
||||
private final ConcurrentMap<String, String> finder;
|
||||
public class BlobToObject implements Function<Blob, S3Object> {
|
||||
private final BlobToObjectMetadata blob2ObjectMd;
|
||||
private final S3Object.Factory objectProvider;
|
||||
|
||||
@Inject
|
||||
public ContainerNameToResourceId(ConcurrentMap<String, String> finder) {
|
||||
this.finder = finder;
|
||||
BlobToObject(BlobToObjectMetadata blob2ObjectMd, S3Object.Factory objectProvider) {
|
||||
this.blob2ObjectMd = blob2ObjectMd;
|
||||
this.objectProvider = objectProvider;
|
||||
}
|
||||
|
||||
public String apply(Object from) {
|
||||
String toFind = checkNotNull(from, "name").toString();
|
||||
try {
|
||||
return finder.get(toFind);
|
||||
} catch (ComputationException e) {
|
||||
Utils.<ContainerNotFoundException> rethrowIfRuntimeOrSameType(e);
|
||||
throw e;
|
||||
}
|
||||
public S3Object apply(Blob from) {
|
||||
S3Object object = objectProvider.create(blob2ObjectMd.apply(from.getMetadata()));
|
||||
if (from.getContentLength() != null)
|
||||
object.setContentLength(from.getContentLength());
|
||||
object.setData(from.getData());
|
||||
object.setAllHeaders(from.getAllHeaders());
|
||||
return object;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
package org.jclouds.aws.s3.blobstore.functions;
|
||||
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.http.options.GetOptions;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Singleton
|
||||
public class BlobToObjectGetOptions implements
|
||||
Function<org.jclouds.blobstore.options.GetOptions[], GetOptions> {
|
||||
public GetOptions apply(org.jclouds.blobstore.options.GetOptions[] from) {
|
||||
GetOptions httpOptions = new GetOptions();
|
||||
if (from.length != 0) {
|
||||
if (from[0].getIfMatch() != null) {
|
||||
httpOptions.ifETagMatches(from[0].getIfMatch());
|
||||
}
|
||||
if (from[0].getIfModifiedSince() != null) {
|
||||
httpOptions.ifModifiedSince(from[0].getIfModifiedSince());
|
||||
}
|
||||
if (from[0].getIfNoneMatch() != null) {
|
||||
httpOptions.ifETagDoesntMatch(from[0].getIfNoneMatch());
|
||||
}
|
||||
if (from[0].getIfUnmodifiedSince() != null) {
|
||||
httpOptions.ifUnmodifiedSince(from[0].getIfUnmodifiedSince());
|
||||
}
|
||||
for (String range : from[0].getRanges()) {
|
||||
String[] firstLast = range.split("\\-");
|
||||
httpOptions.range(Long.parseLong(firstLast[0]), Long.parseLong(firstLast[1]));
|
||||
}
|
||||
}
|
||||
return httpOptions;
|
||||
}
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
|
@ -21,25 +21,33 @@
|
|||
* under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
package org.jclouds.rackspace.cloudfiles;
|
||||
package org.jclouds.aws.s3.blobstore.functions;
|
||||
|
||||
import org.jclouds.blobstore.BlobStoreContext;
|
||||
import org.jclouds.blobstore.domain.Blob;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.aws.s3.domain.MutableObjectMetadata;
|
||||
import org.jclouds.aws.s3.domain.internal.MutableObjectMetadataImpl;
|
||||
import org.jclouds.blobstore.domain.BlobMetadata;
|
||||
import org.jclouds.cloud.CloudContext;
|
||||
import org.jclouds.rackspace.cloudfiles.domain.ContainerMetadata;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
|
||||
/**
|
||||
* Represents an authenticated context to Cloud Files.
|
||||
*
|
||||
* @see <a href="http://www.rackspacecloud.com/cf-devguide-20090311.pdf" />
|
||||
* @see CloudFilesBlobStore
|
||||
* @see CloudContext
|
||||
* @author Adrian Cole
|
||||
*
|
||||
*/
|
||||
public interface CloudFilesContext
|
||||
extends
|
||||
BlobStoreContext<CloudFilesConnection, ContainerMetadata, BlobMetadata, Blob<BlobMetadata>> {
|
||||
@Singleton
|
||||
public class BlobToObjectMetadata implements Function<BlobMetadata, MutableObjectMetadata> {
|
||||
public MutableObjectMetadata apply(BlobMetadata base) {
|
||||
MutableObjectMetadata to = new MutableObjectMetadataImpl();
|
||||
to.setContentType(base.getContentType());
|
||||
to.setETag(base.getETag());
|
||||
to.setContentMD5(base.getContentMD5());
|
||||
to.setKey(base.getName());
|
||||
to.setLastModified(base.getLastModified());
|
||||
if (base.getSize() != null)
|
||||
to.setSize(base.getSize());
|
||||
if (base.getUserMetadata() != null)
|
||||
to.setUserMetadata(base.getUserMetadata());
|
||||
return to;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
package org.jclouds.aws.s3.blobstore.functions;
|
||||
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.aws.s3.options.ListBucketOptions;
|
||||
import org.jclouds.blobstore.options.ListOptions;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Singleton
|
||||
public class BucketToContainerListOptions implements Function<ListBucketOptions[], ListOptions> {
|
||||
public ListOptions apply(ListBucketOptions[] optionsList) {
|
||||
ListOptions options = new ListOptions();
|
||||
if (optionsList.length != 0) {
|
||||
if (optionsList[0].getDelimiter() == null) {
|
||||
options.recursive();
|
||||
} else if (!optionsList[0].getDelimiter().equals("/")) {
|
||||
throw new IllegalArgumentException("only '/' is allowed as a blobstore delimiter");
|
||||
}
|
||||
if (optionsList[0].getMarker() != null) {
|
||||
options.afterMarker(optionsList[0].getMarker());
|
||||
}
|
||||
if (optionsList[0].getMaxResults() != null) {
|
||||
options.maxResults(optionsList[0].getMaxResults());
|
||||
}
|
||||
if (optionsList[0].getPrefix() != null) {
|
||||
options.underPath(optionsList[0].getPrefix());
|
||||
}
|
||||
}
|
||||
return options;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
package org.jclouds.aws.s3.blobstore.functions;
|
||||
|
||||
import java.util.SortedSet;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.aws.s3.domain.ListBucketResponse;
|
||||
import org.jclouds.blobstore.domain.BoundedSortedSet;
|
||||
import org.jclouds.blobstore.domain.ResourceMetadata;
|
||||
import org.jclouds.blobstore.domain.internal.BoundedTreeSet;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Singleton
|
||||
public class BucketToResourceList implements
|
||||
Function<ListBucketResponse, BoundedSortedSet<? extends ResourceMetadata>> {
|
||||
private final ObjectToBlobMetadata object2blobMd;
|
||||
private final CommonPrefixesToResourceMetadata prefix2ResourceMd;
|
||||
|
||||
@Inject
|
||||
public BucketToResourceList(ObjectToBlobMetadata object2blobMd,
|
||||
CommonPrefixesToResourceMetadata prefix2ResourceMd) {
|
||||
this.object2blobMd = object2blobMd;
|
||||
this.prefix2ResourceMd = prefix2ResourceMd;
|
||||
}
|
||||
|
||||
public BoundedSortedSet<? extends ResourceMetadata> apply(ListBucketResponse from) {
|
||||
SortedSet<ResourceMetadata> contents = Sets.newTreeSet(Iterables.concat(Iterables.transform(
|
||||
from, object2blobMd), prefix2ResourceMd.apply(from.getCommonPrefixes())));
|
||||
return new BoundedTreeSet<ResourceMetadata>(contents, from.getPrefix(), from.getMarker(),
|
||||
from.getMaxKeys(), from.isTruncated());
|
||||
|
||||
}
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
|
@ -21,26 +21,27 @@
|
|||
* under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
package org.jclouds.aws.s3;
|
||||
package org.jclouds.aws.s3.blobstore.functions;
|
||||
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.aws.s3.domain.BucketMetadata;
|
||||
import org.jclouds.aws.s3.domain.ObjectMetadata;
|
||||
import org.jclouds.aws.s3.domain.S3Object;
|
||||
import org.jclouds.blobstore.BlobStoreContext;
|
||||
import org.jclouds.blobstore.domain.MutableResourceMetadata;
|
||||
import org.jclouds.blobstore.domain.ResourceMetadata;
|
||||
import org.jclouds.blobstore.domain.ResourceType;
|
||||
import org.jclouds.blobstore.domain.internal.MutableResourceMetadataImpl;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
|
||||
/**
|
||||
* Represents an authenticated context to S3.
|
||||
*
|
||||
* <h2>Note</h2> Please issue {@link #close()} when you are finished with this context in order to
|
||||
* release resources.
|
||||
*
|
||||
*
|
||||
* @see S3BlobStore
|
||||
* @see BlobStoreContext
|
||||
* @author Adrian Cole
|
||||
*
|
||||
*/
|
||||
public interface S3Context extends
|
||||
BlobStoreContext<S3Connection, BucketMetadata, ObjectMetadata, S3Object> {
|
||||
|
||||
@Singleton
|
||||
public class BucketToResourceMetadata implements Function<BucketMetadata, ResourceMetadata> {
|
||||
public ResourceMetadata apply(BucketMetadata from) {
|
||||
MutableResourceMetadata to = new MutableResourceMetadataImpl();
|
||||
to.setName(from.getName());
|
||||
to.setType(ResourceType.CONTAINER);
|
||||
return to;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
package org.jclouds.aws.s3.blobstore.functions;
|
||||
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.blobstore.domain.MutableResourceMetadata;
|
||||
import org.jclouds.blobstore.domain.ResourceMetadata;
|
||||
import org.jclouds.blobstore.domain.ResourceType;
|
||||
import org.jclouds.blobstore.domain.internal.MutableResourceMetadataImpl;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.Iterables;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Singleton
|
||||
public class CommonPrefixesToResourceMetadata implements
|
||||
Function<Iterable<String>, Iterable<ResourceMetadata>> {
|
||||
public Iterable<ResourceMetadata> apply(
|
||||
|
||||
Iterable<String> prefixes) {
|
||||
return Iterables.transform(prefixes, new Function<String, ResourceMetadata>() {
|
||||
public ResourceMetadata apply(String from) {
|
||||
MutableResourceMetadata returnVal = new MutableResourceMetadataImpl();
|
||||
returnVal.setType(ResourceType.RELATIVE_PATH);
|
||||
returnVal.setName(from);
|
||||
return returnVal;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
package org.jclouds.aws.s3.blobstore.functions;
|
||||
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.aws.s3.options.ListBucketOptions;
|
||||
import org.jclouds.blobstore.options.ListOptions;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Singleton
|
||||
public class ContainerToBucketListOptions implements Function<ListOptions[], ListBucketOptions> {
|
||||
public ListBucketOptions apply(ListOptions[] optionsList) {
|
||||
ListBucketOptions httpOptions = new ListBucketOptions();
|
||||
if (optionsList.length != 0) {
|
||||
if (!optionsList[0].getRecursive()) {
|
||||
httpOptions.delimiter("/");
|
||||
}
|
||||
if (optionsList[0].getPath() != null) {
|
||||
httpOptions.withPrefix(optionsList[0].getPath());
|
||||
}
|
||||
if (optionsList[0].getMarker() != null) {
|
||||
httpOptions.afterMarker(optionsList[0].getMarker());
|
||||
}
|
||||
if (optionsList[0].getMaxResults() != null) {
|
||||
httpOptions.maxResults(optionsList[0].getMaxResults());
|
||||
}
|
||||
}
|
||||
return httpOptions;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
package org.jclouds.aws.s3.blobstore.functions;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.aws.s3.domain.S3Object;
|
||||
import org.jclouds.blobstore.domain.Blob;
|
||||
import org.jclouds.blobstore.domain.Blob.Factory;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Singleton
|
||||
public class ObjectToBlob implements Function<S3Object, Blob> {
|
||||
private final Blob.Factory blobFactory;
|
||||
private final ObjectToBlobMetadata object2BlobMd;
|
||||
|
||||
@Inject
|
||||
ObjectToBlob(Factory blobFactory, ObjectToBlobMetadata object2BlobMd) {
|
||||
this.blobFactory = blobFactory;
|
||||
this.object2BlobMd = object2BlobMd;
|
||||
}
|
||||
|
||||
public Blob apply(S3Object from) {
|
||||
Blob blob = blobFactory.create(object2BlobMd.apply(from.getMetadata()));
|
||||
if (from.getContentLength() != null)
|
||||
blob.setContentLength(from.getContentLength());
|
||||
blob.setData(from.getData());
|
||||
blob.setAllHeaders(from.getAllHeaders());
|
||||
return blob;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
package org.jclouds.aws.s3.blobstore.functions;
|
||||
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.aws.s3.domain.ObjectMetadata;
|
||||
import org.jclouds.blobstore.domain.MutableBlobMetadata;
|
||||
import org.jclouds.blobstore.domain.ResourceType;
|
||||
import org.jclouds.blobstore.domain.internal.MutableBlobMetadataImpl;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Singleton
|
||||
public class ObjectToBlobMetadata implements Function<ObjectMetadata, MutableBlobMetadata> {
|
||||
public MutableBlobMetadata apply(ObjectMetadata from) {
|
||||
MutableBlobMetadata to = new MutableBlobMetadataImpl();
|
||||
to.setContentMD5(from.getContentMD5());
|
||||
if (from.getContentType() != null)
|
||||
to.setContentType(from.getContentType());
|
||||
to.setETag(from.getETag());
|
||||
to.setName(from.getKey());
|
||||
to.setSize(from.getSize());
|
||||
to.setType(ResourceType.BLOB);
|
||||
to.setUserMetadata(from.getUserMetadata());
|
||||
if (from.getContentType() != null && from.getContentType().equals("application/directory")) {
|
||||
to.setType(ResourceType.RELATIVE_PATH);
|
||||
}
|
||||
return to;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,92 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
package org.jclouds.aws.s3.blobstore.functions;
|
||||
|
||||
import java.util.SortedSet;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.aws.s3.domain.ListBucketResponse;
|
||||
import org.jclouds.aws.s3.domain.MutableObjectMetadata;
|
||||
import org.jclouds.aws.s3.domain.ObjectMetadata;
|
||||
import org.jclouds.aws.s3.domain.internal.TreeSetListBucketResponse;
|
||||
import org.jclouds.blobstore.domain.BlobMetadata;
|
||||
import org.jclouds.blobstore.domain.BoundedSortedSet;
|
||||
import org.jclouds.blobstore.domain.ResourceMetadata;
|
||||
import org.jclouds.blobstore.domain.ResourceType;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Singleton
|
||||
public class ResourceToBucketList implements
|
||||
Function<BoundedSortedSet<? extends ResourceMetadata>, ListBucketResponse> {
|
||||
private final BlobToObjectMetadata blob2ObjectMd;
|
||||
|
||||
@Inject
|
||||
public ResourceToBucketList(BlobToObjectMetadata blob2ObjectMd) {
|
||||
this.blob2ObjectMd = blob2ObjectMd;
|
||||
}
|
||||
|
||||
public ListBucketResponse apply(BoundedSortedSet<? extends ResourceMetadata> list) {
|
||||
|
||||
SortedSet<ObjectMetadata> contents = Sets.newTreeSet(Iterables.transform(Iterables.filter(
|
||||
list, new Predicate<ResourceMetadata>() {
|
||||
|
||||
public boolean apply(ResourceMetadata input) {
|
||||
return input.getType() == ResourceType.BLOB;
|
||||
}
|
||||
|
||||
}), new Function<ResourceMetadata, ObjectMetadata>() {
|
||||
|
||||
public MutableObjectMetadata apply(ResourceMetadata from) {
|
||||
return blob2ObjectMd.apply((BlobMetadata) from);
|
||||
}
|
||||
|
||||
}));
|
||||
|
||||
SortedSet<String> commonPrefixes = Sets.newTreeSet(Iterables.transform(Iterables.filter(list,
|
||||
new Predicate<ResourceMetadata>() {
|
||||
|
||||
public boolean apply(ResourceMetadata input) {
|
||||
return input.getType() == ResourceType.RELATIVE_PATH;
|
||||
}
|
||||
|
||||
}), new Function<ResourceMetadata, String>() {
|
||||
|
||||
public String apply(ResourceMetadata from) {
|
||||
return from.getName();
|
||||
}
|
||||
|
||||
}));
|
||||
return new TreeSetListBucketResponse(null, contents, list.getPath(), list.getMarker(), list
|
||||
.getMaxResults(), "/", contents.size() == list.getMaxResults(), commonPrefixes);
|
||||
}
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
|
@ -25,28 +25,22 @@ package org.jclouds.aws.s3.config;
|
|||
|
||||
import java.net.URI;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Provider;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.aws.reference.AWSConstants;
|
||||
import org.jclouds.aws.s3.S3;
|
||||
import org.jclouds.aws.s3.S3BlobStore;
|
||||
import org.jclouds.aws.s3.S3Connection;
|
||||
import org.jclouds.aws.s3.S3Context;
|
||||
import org.jclouds.aws.s3.domain.BucketMetadata;
|
||||
import org.jclouds.aws.s3.domain.ObjectMetadata;
|
||||
import org.jclouds.aws.s3.domain.S3Object;
|
||||
import org.jclouds.blobstore.BlobStore;
|
||||
import org.jclouds.blobstore.BlobStoreContextImpl;
|
||||
import org.jclouds.blobstore.BlobMap.Factory;
|
||||
import org.jclouds.aws.s3.S3Client;
|
||||
import org.jclouds.blobstore.config.BlobStoreObjectModule;
|
||||
import org.jclouds.lifecycle.Closer;
|
||||
import org.jclouds.rest.RestContext;
|
||||
import org.jclouds.rest.internal.RestContextImpl;
|
||||
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Scopes;
|
||||
import com.google.inject.Provides;
|
||||
|
||||
/**
|
||||
* Configures the {@link S3Context}; requires {@link S3BlobStore} bound.
|
||||
* Configures the {@link S3ContextModule}; requires {@link S3Client} bound.
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
|
@ -54,23 +48,16 @@ public class S3ContextModule extends AbstractModule {
|
|||
|
||||
@Override
|
||||
protected void configure() {
|
||||
bind(S3Context.class).to(S3ContextImpl.class).in(Scopes.SINGLETON);
|
||||
// for converters
|
||||
install(new BlobStoreObjectModule());
|
||||
install(new S3ObjectModule());
|
||||
}
|
||||
|
||||
public static class S3ContextImpl extends
|
||||
BlobStoreContextImpl<S3Connection, BucketMetadata, ObjectMetadata, S3Object> implements
|
||||
S3Context {
|
||||
@Inject
|
||||
S3ContextImpl(Factory<ObjectMetadata, S3Object> blobMapFactory,
|
||||
org.jclouds.blobstore.InputStreamMap.Factory<ObjectMetadata> inputStreamMapFactory,
|
||||
Closer closer, Provider<S3Object> blobProvider,
|
||||
BlobStore<BucketMetadata, ObjectMetadata, S3Object> blobStore,
|
||||
S3Connection defaultApi, @S3 URI endPoint,
|
||||
@Named(AWSConstants.PROPERTY_AWS_ACCESSKEYID) String account) {
|
||||
super(blobMapFactory, inputStreamMapFactory, closer, blobProvider, blobStore, defaultApi,
|
||||
endPoint, account);
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
RestContext<S3Client> provideContext(Closer closer, S3Client defaultApi, @S3 URI endPoint,
|
||||
@Named(AWSConstants.PROPERTY_AWS_ACCESSKEYID) String account) {
|
||||
return new RestContextImpl<S3Client>(closer, defaultApi, endPoint, account);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,78 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
package org.jclouds.aws.s3.config;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Provider;
|
||||
|
||||
import org.jclouds.aws.s3.domain.MutableObjectMetadata;
|
||||
import org.jclouds.aws.s3.domain.S3Object;
|
||||
import org.jclouds.aws.s3.domain.internal.S3ObjectImpl;
|
||||
import org.jclouds.blobstore.functions.CalculateSize;
|
||||
import org.jclouds.blobstore.functions.GenerateMD5;
|
||||
import org.jclouds.blobstore.functions.GenerateMD5Result;
|
||||
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Provides;
|
||||
import com.google.inject.Scopes;
|
||||
|
||||
/**
|
||||
* Configures the domain object mappings needed for all S3 implementations
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class S3ObjectModule extends AbstractModule {
|
||||
|
||||
|
||||
/**
|
||||
* explicit factories are created here as it has been shown that Assisted Inject is extremely
|
||||
* inefficient. http://code.google.com/p/google-guice/issues/detail?id=435
|
||||
*/
|
||||
@Override
|
||||
protected void configure() {
|
||||
bind(S3Object.Factory.class).to(S3ObjectFactory.class).in(Scopes.SINGLETON);
|
||||
}
|
||||
|
||||
private static class S3ObjectFactory implements S3Object.Factory {
|
||||
@Inject
|
||||
GenerateMD5Result generateMD5Result;
|
||||
@Inject
|
||||
GenerateMD5 generateMD5;
|
||||
@Inject
|
||||
CalculateSize calculateSize;
|
||||
@Inject
|
||||
Provider<MutableObjectMetadata> metadataProvider;
|
||||
|
||||
public S3Object create(MutableObjectMetadata metadata) {
|
||||
return new S3ObjectImpl(generateMD5Result, generateMD5, calculateSize,
|
||||
metadata != null ? metadata : metadataProvider.get());
|
||||
}
|
||||
}
|
||||
|
||||
@Provides
|
||||
S3Object provideS3Object(S3Object.Factory factory) {
|
||||
return factory.create(null);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
|
@ -31,24 +31,19 @@ import javax.inject.Named;
|
|||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.aws.s3.S3;
|
||||
import org.jclouds.aws.s3.S3BlobStore;
|
||||
import org.jclouds.aws.s3.S3Connection;
|
||||
import org.jclouds.aws.s3.domain.BucketMetadata;
|
||||
import org.jclouds.aws.s3.domain.ObjectMetadata;
|
||||
import org.jclouds.aws.s3.domain.S3Object;
|
||||
import org.jclouds.aws.s3.S3Client;
|
||||
import org.jclouds.aws.s3.filters.RequestAuthorizeSignature;
|
||||
import org.jclouds.aws.s3.handlers.AWSClientErrorRetryHandler;
|
||||
import org.jclouds.aws.s3.handlers.AWSRedirectionRetryHandler;
|
||||
import org.jclouds.aws.s3.handlers.ParseAWSErrorFromXmlContent;
|
||||
import org.jclouds.aws.s3.reference.S3Constants;
|
||||
import org.jclouds.blobstore.BlobStore;
|
||||
import org.jclouds.cloud.ConfiguresCloudConnection;
|
||||
import org.jclouds.http.HttpErrorHandler;
|
||||
import org.jclouds.http.HttpRetryHandler;
|
||||
import org.jclouds.http.RequiresHttp;
|
||||
import org.jclouds.http.annotation.ClientError;
|
||||
import org.jclouds.http.annotation.Redirection;
|
||||
import org.jclouds.http.annotation.ServerError;
|
||||
import org.jclouds.rest.ConfiguresRestClient;
|
||||
import org.jclouds.rest.RestClientFactory;
|
||||
import org.jclouds.util.DateService;
|
||||
import org.jclouds.util.TimeStamp;
|
||||
|
@ -64,9 +59,9 @@ import com.google.inject.Scopes;
|
|||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@ConfiguresCloudConnection
|
||||
@ConfiguresRestClient
|
||||
@RequiresHttp
|
||||
public class RestS3ConnectionModule extends AbstractModule {
|
||||
public class S3RestClientModule extends AbstractModule {
|
||||
|
||||
@Provides
|
||||
@TimeStamp
|
||||
|
@ -106,15 +101,8 @@ public class RestS3ConnectionModule extends AbstractModule {
|
|||
|
||||
@Provides
|
||||
@Singleton
|
||||
protected BlobStore<BucketMetadata, ObjectMetadata, S3Object> provideS3BlobStore(
|
||||
RestClientFactory factory) {
|
||||
return factory.create(S3BlobStore.class);
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
protected S3Connection provideS3Connection(RestClientFactory factory) {
|
||||
return factory.create(S3Connection.class);
|
||||
protected S3Client provideS3Client(RestClientFactory factory) {
|
||||
return factory.create(S3Client.class);
|
||||
}
|
||||
|
||||
protected void bindErrorHandlers() {
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
|
@ -22,7 +22,7 @@
|
|||
* ====================================================================
|
||||
*/
|
||||
/**
|
||||
* This package contains modules who manage the dependencies of the S3Context, S3Connection, and S3 Map views.
|
||||
* This package contains modules who manage the dependencies of the S3Context, S3Client, and S3 Map views.
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
package org.jclouds.aws.s3.config;
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
|
@ -410,4 +410,35 @@ public class AccessControlList {
|
|||
sb.append('}');
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((grants == null) ? 0 : grants.hashCode());
|
||||
result = prime * result + ((owner == null) ? 0 : owner.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
AccessControlList other = (AccessControlList) obj;
|
||||
if (grants == null) {
|
||||
if (other.grants != null)
|
||||
return false;
|
||||
} else if (!grants.equals(other.grants))
|
||||
return false;
|
||||
if (owner == null) {
|
||||
if (other.owner != null)
|
||||
return false;
|
||||
} else if (!owner.equals(other.owner))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
|
@ -23,7 +23,6 @@
|
|||
*/
|
||||
package org.jclouds.aws.s3.domain;
|
||||
|
||||
import org.jclouds.blobstore.internal.ContainerMetadataImpl;
|
||||
import org.joda.time.DateTime;
|
||||
|
||||
/**
|
||||
|
@ -31,36 +30,41 @@ import org.joda.time.DateTime;
|
|||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class BucketMetadata extends ContainerMetadataImpl {
|
||||
protected DateTime creationDate;
|
||||
|
||||
public DateTime getCreationDate() {
|
||||
return creationDate;
|
||||
}
|
||||
|
||||
public void setCreationDate(DateTime creationDate) {
|
||||
this.creationDate = creationDate;
|
||||
}
|
||||
public class BucketMetadata implements Comparable<BucketMetadata> {
|
||||
/** The serialVersionUID */
|
||||
private static final long serialVersionUID = -6965068835316857535L;
|
||||
private final DateTime creationDate;
|
||||
private final CanonicalUser owner;
|
||||
private final String name;
|
||||
|
||||
/**
|
||||
* Location constraint of the bucket.
|
||||
*
|
||||
* @author Adrian Cole
|
||||
* @see <a href=
|
||||
* "http://docs.amazonwebservices.com/AmazonS3/latest/RESTBucketLocationGET.html" />
|
||||
* @see <a href= "http://docs.amazonwebservices.com/AmazonS3/latest/RESTBucketLocationGET.html"
|
||||
* />
|
||||
*/
|
||||
public static enum LocationConstraint {
|
||||
EU
|
||||
}
|
||||
|
||||
private CanonicalUser canonicalUser;
|
||||
|
||||
public BucketMetadata(String name) {
|
||||
super(name);
|
||||
public BucketMetadata(String name, DateTime creationDate, CanonicalUser owner) {
|
||||
this.name = name;
|
||||
this.creationDate = creationDate;
|
||||
this.owner = owner;
|
||||
}
|
||||
|
||||
public BucketMetadata() {
|
||||
super();
|
||||
/**
|
||||
* Every bucket and object in Amazon S3 has an owner, the user that created the bucket or object.
|
||||
* The owner of a bucket or object cannot be changed. However, if the object is overwritten by
|
||||
* another user (deleted and rewritten), the new object will have a new owner.
|
||||
*/
|
||||
public CanonicalUser getOwner() {
|
||||
return owner;
|
||||
}
|
||||
|
||||
public DateTime getCreationDate() {
|
||||
return creationDate;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -74,40 +78,20 @@ public class BucketMetadata extends ContainerMetadataImpl {
|
|||
* <p/>
|
||||
* Not be in an IP address style (e.g., "192.168.5.4")
|
||||
*/
|
||||
@Override
|
||||
public void setName(String name) {
|
||||
// note that we cannot enforce this, as invalid buckets may already exist
|
||||
super.setName(name);
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "BucketMetadata [canonicalUser=" + canonicalUser + ", creationDate=" + creationDate
|
||||
+ ", name=" + name + "]";
|
||||
}
|
||||
|
||||
/**
|
||||
* Every bucket and object in Amazon S3 has an owner, the user that created the bucket or
|
||||
* object. The owner of a bucket or object cannot be changed. However, if the object is
|
||||
* overwritten by another user (deleted and rewritten), the new object will have a new owner.
|
||||
*/
|
||||
public CanonicalUser getOwner() {
|
||||
return canonicalUser;
|
||||
}
|
||||
|
||||
public void setOwner(CanonicalUser canonicalUser) {
|
||||
this.canonicalUser = canonicalUser;
|
||||
public int compareTo(BucketMetadata o) {
|
||||
return (this == o) ? 0 : getName().compareTo(o.getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = super.hashCode();
|
||||
result = prime * result + ((canonicalUser == null) ? 0 : canonicalUser.hashCode());
|
||||
int result = 1;
|
||||
result = prime * result + ((name == null) ? 0 : name.hashCode());
|
||||
result = prime * result + ((owner == null) ? 0 : owner.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -115,17 +99,21 @@ public class BucketMetadata extends ContainerMetadataImpl {
|
|||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (!super.equals(obj))
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
BucketMetadata other = (BucketMetadata) obj;
|
||||
if (canonicalUser == null) {
|
||||
if (other.canonicalUser != null)
|
||||
if (name == null) {
|
||||
if (other.name != null)
|
||||
return false;
|
||||
} else if (!canonicalUser.equals(other.canonicalUser))
|
||||
} else if (!name.equals(other.name))
|
||||
return false;
|
||||
if (owner == null) {
|
||||
if (other.owner != null)
|
||||
return false;
|
||||
} else if (!owner.equals(other.owner))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
|
@ -24,10 +24,9 @@
|
|||
package org.jclouds.aws.s3.domain;
|
||||
|
||||
/**
|
||||
* Every bucket and object in Amazon S3 has an owner, the user that created the
|
||||
* bucket or object. The owner of a bucket or object cannot be changed. However,
|
||||
* if the object is overwritten by another user (deleted and rewritten), the new
|
||||
* object will have a new owner.
|
||||
* Every bucket and object in Amazon S3 has an owner, the user that created the bucket or object.
|
||||
* The owner of a bucket or object cannot be changed. However, if the object is overwritten by
|
||||
* another user (deleted and rewritten), the new object will have a new owner.
|
||||
* <p/>
|
||||
*
|
||||
* @see <a href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?
|
||||
|
@ -35,66 +34,61 @@ package org.jclouds.aws.s3.domain;
|
|||
* @author Adrian Cole
|
||||
*/
|
||||
public class CanonicalUser {
|
||||
private final String id;
|
||||
private String displayName;
|
||||
private final String id;
|
||||
private String displayName;
|
||||
|
||||
public CanonicalUser(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
public CanonicalUser(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
sb.append("S3Owner");
|
||||
sb.append("{id='").append(id).append('\'');
|
||||
sb.append(", displayName='").append(displayName).append('\'');
|
||||
sb.append('}');
|
||||
return sb.toString();
|
||||
}
|
||||
public CanonicalUser(String id, String displayName) {
|
||||
this(id);
|
||||
this.displayName = displayName;
|
||||
}
|
||||
|
||||
/**
|
||||
* To locate the CanonicalUser ID for a user, the user must perform the
|
||||
* {@link org.jclouds.aws.s3.S3BlobStore#listBlobs(String)} and retrieve
|
||||
* {@link BucketMetadata#getOwner()}
|
||||
*/
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
/**
|
||||
* To locate the CanonicalUser ID for a user, the user must perform the
|
||||
* {@link org.jclouds.aws.s3.blobstore.S3BlobStore#list(String)} and retrieve
|
||||
* {@link BucketMetadata#getOwner()}
|
||||
*/
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* read-only as is maintained by Amazon.
|
||||
*/
|
||||
public String getDisplayName() {
|
||||
return displayName;
|
||||
}
|
||||
/**
|
||||
* read-only as is maintained by Amazon.
|
||||
*/
|
||||
public String getDisplayName() {
|
||||
return displayName;
|
||||
}
|
||||
|
||||
public void setDisplayName(String displayName) {
|
||||
this.displayName = displayName;
|
||||
}
|
||||
public void setDisplayName(String displayName) {
|
||||
this.displayName = displayName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o)
|
||||
return true;
|
||||
if (!(o instanceof CanonicalUser))
|
||||
return false;
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((id == null) ? 0 : id.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
CanonicalUser s3Owner = (CanonicalUser) o;
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
CanonicalUser other = (CanonicalUser) obj;
|
||||
if (id == null) {
|
||||
if (other.id != null)
|
||||
return false;
|
||||
} else if (!id.equals(other.id))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (displayName != null ? !displayName.equals(s3Owner.displayName)
|
||||
: s3Owner.displayName != null)
|
||||
return false;
|
||||
if (!id.equals(s3Owner.id))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = id.hashCode();
|
||||
result = 31 * result
|
||||
+ (displayName != null ? displayName.hashCode() : 0);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
|
@ -48,7 +48,40 @@ import java.util.SortedSet;
|
|||
* @author Adrian Cole
|
||||
* @see <a href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html" />
|
||||
*/
|
||||
public interface ListBucketResponse extends org.jclouds.rest.internal.BoundedSortedSet<ObjectMetadata> {
|
||||
public interface ListBucketResponse extends SortedSet<ObjectMetadata> {
|
||||
|
||||
/**
|
||||
* Limits the response to keys which begin with the indicated prefix. You can use prefixes to
|
||||
* separate a bucket into different sets of keys in a way similar to how a file system uses
|
||||
* folders.
|
||||
*/
|
||||
String getPrefix();
|
||||
|
||||
/**
|
||||
* Indicates where in the bucket to begin listing. The list will only include keys that occur
|
||||
* lexicographically after marker. This is convenient for pagination: To get the next page of
|
||||
* results use the last key of the current page as the marker.
|
||||
*/
|
||||
String getMarker();
|
||||
|
||||
/**
|
||||
* The maximum number of keys you'd like to see in the response body. The server might return
|
||||
* fewer than this many keys, but will not return more.
|
||||
*/
|
||||
int getMaxKeys();
|
||||
|
||||
/**
|
||||
* There are more then maxKeys available
|
||||
*/
|
||||
boolean isTruncated();
|
||||
|
||||
/**
|
||||
* Causes keys that contain the same string between the prefix and the first occurrence of the
|
||||
* delimiter to be rolled up into a single result element in the CommonPrefixes collection. These
|
||||
* rolled-up keys are not returned elsewhere in the response.
|
||||
*
|
||||
*/
|
||||
String getDelimiter();
|
||||
|
||||
/**
|
||||
* Example:
|
||||
|
@ -65,12 +98,12 @@ public interface ListBucketResponse extends org.jclouds.rest.internal.BoundedSor
|
|||
*
|
||||
* @see org.jclouds.aws.s3.options.ListBucketOptions#getPrefix()
|
||||
*/
|
||||
public SortedSet<String> getCommonPrefixes();
|
||||
|
||||
public String getBucketName();
|
||||
|
||||
public String getDelimiter();
|
||||
|
||||
public boolean isTruncated();
|
||||
SortedSet<String> getCommonPrefixes();
|
||||
|
||||
/**
|
||||
* name of the Bucket FIXME Comment this
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String getName();
|
||||
}
|
|
@ -0,0 +1,118 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
package org.jclouds.aws.s3.domain;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.jclouds.aws.s3.domain.internal.MutableObjectMetadataImpl;
|
||||
import org.joda.time.DateTime;
|
||||
|
||||
import com.google.inject.ImplementedBy;
|
||||
|
||||
/**
|
||||
* /** Amazon S3 is designed to store objects. Objects are stored in {@link S3BucketListing buckets}
|
||||
* and consist of a {@link org.jclouds.aws.s3.domain.S3Object#getData() value}, a
|
||||
* {@link S3Object#getKey key}, {@link MutableObjectMetadata#getUserMetadata() metadata}, and an
|
||||
* access control policy.
|
||||
*
|
||||
* @author Adrian Cole
|
||||
* @see <a href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?UsingObjects.html"
|
||||
*
|
||||
* @see <a href= "http://docs.amazonwebservices.com/AmazonS3/2006-03-01/UsingMetadata.html" />
|
||||
*/
|
||||
@ImplementedBy(MutableObjectMetadataImpl.class)
|
||||
public interface MutableObjectMetadata extends ObjectMetadata {
|
||||
|
||||
/**
|
||||
* The key is the handle that you assign to an object that allows you retrieve it later. A key is
|
||||
* a sequence of Unicode characters whose UTF-8 encoding is at most 1024 bytes long. Each object
|
||||
* in a bucket must have a unique key.
|
||||
*
|
||||
* @see <a href= "http://docs.amazonwebservices.com/AmazonHTTP/2006-03-01/UsingKeys.html" />
|
||||
*/
|
||||
void setKey(String key);
|
||||
|
||||
/**
|
||||
* Every bucket and object in Amazon S3 has an owner, the user that created the bucket or object.
|
||||
* The owner of a bucket or object cannot be changed. However, if the object is overwritten by
|
||||
* another user (deleted and rewritten), the new object will have a new owner.
|
||||
*/
|
||||
void setOwner(CanonicalUser owner);
|
||||
|
||||
/**
|
||||
* Currently defaults to 'STANDARD' and not used.
|
||||
*/
|
||||
void setStorageClass(StorageClass storageClass);
|
||||
|
||||
/**
|
||||
* Can be used to specify caching behavior along the request/reply chain.
|
||||
*
|
||||
* @link http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html?sec14.9.
|
||||
*/
|
||||
void setCacheControl(String cacheControl);
|
||||
|
||||
/**
|
||||
* Specifies presentational information for the object.
|
||||
*
|
||||
* @see <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec19.html?sec19.5.1."/>
|
||||
*/
|
||||
void setContentDisposition(String contentDisposition);
|
||||
|
||||
/**
|
||||
* Specifies what content encodings have been applied to the object and thus what decoding
|
||||
* mechanisms must be applied in order to obtain the media-type referenced by the Content-Type
|
||||
* header field.
|
||||
*
|
||||
* @see <a href= "http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html?sec14.11" />
|
||||
*/
|
||||
void setContentEncoding(String encoding);
|
||||
|
||||
/**
|
||||
*
|
||||
* A standard MIME type describing the format of the contents. If none is provided, the default
|
||||
* is binary/octet-stream.
|
||||
*
|
||||
* @see <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.17"/>
|
||||
*/
|
||||
void setContentType(String type);
|
||||
|
||||
/**
|
||||
* The base64 decoded 128-bit MD5 digest of the message (without the headers) according to RFC
|
||||
* 1864. This header can be used as a message integrity check to verify that the data is the same
|
||||
* data that was originally sent. Although it is optional, we recommend using the Content-MD5
|
||||
* mechanism as an end-to-end integrity check.
|
||||
*
|
||||
* @see <a href="http://docs.amazonwebservices.com/AmazonS3/latest/RESTAuthentication.html"/>
|
||||
*/
|
||||
void setContentMD5(byte[] md5);
|
||||
|
||||
void setLastModified(DateTime lastModified);
|
||||
|
||||
void setETag(String eTag);
|
||||
|
||||
void setSize(long size);
|
||||
|
||||
void setUserMetadata(Map<String, String> userMetadata);
|
||||
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
|
@ -23,9 +23,9 @@
|
|||
*/
|
||||
package org.jclouds.aws.s3.domain;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Map;
|
||||
|
||||
import org.jclouds.blobstore.internal.BlobMetadataImpl;
|
||||
import org.joda.time.DateTime;
|
||||
|
||||
/**
|
||||
* /** Amazon S3 is designed to store objects. Objects are stored in {@link S3BucketListing buckets}
|
||||
|
@ -38,160 +38,46 @@ import org.jclouds.blobstore.internal.BlobMetadataImpl;
|
|||
*
|
||||
* @see <a href= "http://docs.amazonwebservices.com/AmazonS3/2006-03-01/UsingMetadata.html" />
|
||||
*/
|
||||
public class ObjectMetadata extends BlobMetadataImpl implements Serializable {
|
||||
public interface ObjectMetadata extends Comparable<ObjectMetadata> {
|
||||
|
||||
/** The serialVersionUID */
|
||||
private static final long serialVersionUID = -4415449798024051115L;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append("Metadata [accessControlList=").append(accessControlList).append(
|
||||
", cacheControl=").append(cacheControl).append(", dataDisposition=").append(
|
||||
dataDisposition).append(", owner=").append(owner).append(", storageClass=").append(
|
||||
storageClass).append(", allHeaders=").append(allHeaders).append(", dataEncoding=")
|
||||
.append(dataEncoding).append(", dataType=").append(dataType).append(", eTag=")
|
||||
.append(eTag).append(", key=").append(name).append(", lastModified=").append(
|
||||
lastModified).append(", size=").append(size).append(", userMetadata=")
|
||||
.append(userMetadata).append("]");
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
private String cacheControl;
|
||||
private String dataDisposition;
|
||||
private AccessControlList accessControlList;
|
||||
|
||||
// only parsed on list
|
||||
private CanonicalUser owner = null;
|
||||
private String storageClass = null;
|
||||
protected String dataEncoding;
|
||||
|
||||
public ObjectMetadata() {
|
||||
super();
|
||||
public enum StorageClass {
|
||||
STANDARD
|
||||
}
|
||||
|
||||
/**
|
||||
* @param key
|
||||
* @see #getKey()
|
||||
* The key is the handle that you assign to an object that allows you retrieve it later. A key is
|
||||
* a sequence of Unicode characters whose UTF-8 encoding is at most 1024 bytes long. Each object
|
||||
* in a bucket must have a unique key.
|
||||
*
|
||||
* @see <a href= "http://docs.amazonwebservices.com/AmazonHTTP/2006-03-01/UsingKeys.html" />
|
||||
*/
|
||||
public ObjectMetadata(String key) {
|
||||
super(key);
|
||||
}
|
||||
|
||||
public void setOwner(CanonicalUser owner) {
|
||||
this.owner = owner;
|
||||
}
|
||||
String getKey();
|
||||
|
||||
/**
|
||||
* Every bucket and object in Amazon S3 has an owner, the user that created the bucket or object.
|
||||
* The owner of a bucket or object cannot be changed. However, if the object is overwritten by
|
||||
* another user (deleted and rewritten), the new object will have a new owner.
|
||||
*/
|
||||
public CanonicalUser getOwner() {
|
||||
return owner;
|
||||
}
|
||||
|
||||
public void setStorageClass(String storageClass) {
|
||||
this.storageClass = storageClass;
|
||||
}
|
||||
CanonicalUser getOwner();
|
||||
|
||||
/**
|
||||
* Currently defaults to 'STANDARD' and not used.
|
||||
*/
|
||||
public String getStorageClass() {
|
||||
return storageClass;
|
||||
}
|
||||
|
||||
public void setCacheControl(String cacheControl) {
|
||||
this.cacheControl = cacheControl;
|
||||
}
|
||||
StorageClass getStorageClass();
|
||||
|
||||
/**
|
||||
* Can be used to specify caching behavior along the request/reply chain.
|
||||
*
|
||||
* @link http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html?sec14.9.
|
||||
*/
|
||||
public String getCacheControl() {
|
||||
return cacheControl;
|
||||
}
|
||||
|
||||
public void setContentDisposition(String dataDisposition) {
|
||||
this.dataDisposition = dataDisposition;
|
||||
}
|
||||
String getCacheControl();
|
||||
|
||||
/**
|
||||
* Specifies presentational information for the object.
|
||||
*
|
||||
* @see <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec19.html?sec19.5.1."/>
|
||||
*/
|
||||
public String getContentDisposition() {
|
||||
return dataDisposition;
|
||||
}
|
||||
|
||||
public void setAccessControlList(AccessControlList acl) {
|
||||
this.accessControlList = acl;
|
||||
}
|
||||
|
||||
public AccessControlList getAccessControlList() {
|
||||
return this.accessControlList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = super.hashCode();
|
||||
result = prime * result + ((accessControlList == null) ? 0 : accessControlList.hashCode());
|
||||
result = prime * result + ((cacheControl == null) ? 0 : cacheControl.hashCode());
|
||||
result = prime * result + ((dataDisposition == null) ? 0 : dataDisposition.hashCode());
|
||||
result = prime * result + ((owner == null) ? 0 : owner.hashCode());
|
||||
result = prime * result + ((storageClass == null) ? 0 : storageClass.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (!super.equals(obj))
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
ObjectMetadata other = (ObjectMetadata) obj;
|
||||
if (accessControlList == null) {
|
||||
if (other.accessControlList != null)
|
||||
return false;
|
||||
} else if (!accessControlList.equals(other.accessControlList))
|
||||
return false;
|
||||
if (cacheControl == null) {
|
||||
if (other.cacheControl != null)
|
||||
return false;
|
||||
} else if (!cacheControl.equals(other.cacheControl))
|
||||
return false;
|
||||
if (dataDisposition == null) {
|
||||
if (other.dataDisposition != null)
|
||||
return false;
|
||||
} else if (!dataDisposition.equals(other.dataDisposition))
|
||||
return false;
|
||||
if (owner == null) {
|
||||
if (other.owner != null)
|
||||
return false;
|
||||
} else if (!owner.equals(other.owner))
|
||||
return false;
|
||||
if (storageClass == null) {
|
||||
if (other.storageClass != null)
|
||||
return false;
|
||||
} else if (!storageClass.equals(other.storageClass))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public int compareTo(ObjectMetadata o) {
|
||||
return (this == o) ? 0 : getName().compareTo(o.getName());
|
||||
}
|
||||
|
||||
public void setContentEncoding(String dataEncoding) {
|
||||
this.dataEncoding = dataEncoding;
|
||||
}
|
||||
String getContentDisposition();
|
||||
|
||||
/**
|
||||
* Specifies what content encodings have been applied to the object and thus what decoding
|
||||
|
@ -200,8 +86,33 @@ public class ObjectMetadata extends BlobMetadataImpl implements Serializable {
|
|||
*
|
||||
* @see <a href= "http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html?sec14.11" />
|
||||
*/
|
||||
public String getContentEncoding() {
|
||||
return dataEncoding;
|
||||
}
|
||||
String getContentEncoding();
|
||||
|
||||
/**
|
||||
*
|
||||
* A standard MIME type describing the format of the contents. If none is provided, the default
|
||||
* is binary/octet-stream.
|
||||
*
|
||||
* @see <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.17"/>
|
||||
*/
|
||||
String getContentType();
|
||||
|
||||
/**
|
||||
* The base64 decoded 128-bit MD5 digest of the message (without the headers) according to RFC
|
||||
* 1864. This header can be used as a message integrity check to verify that the data is the same
|
||||
* data that was originally sent. Although it is optional, we recommend using the Content-MD5
|
||||
* mechanism as an end-to-end integrity check.
|
||||
*
|
||||
* @see <a href="http://docs.amazonwebservices.com/AmazonS3/latest/RESTAuthentication.html"/>
|
||||
*/
|
||||
byte[] getContentMD5();
|
||||
|
||||
DateTime getLastModified();
|
||||
|
||||
String getETag();
|
||||
|
||||
Long getSize();
|
||||
|
||||
Map<String, String> getUserMetadata();
|
||||
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
|
@ -23,41 +23,76 @@
|
|||
*/
|
||||
package org.jclouds.aws.s3.domain;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.jclouds.blobstore.internal.BlobImpl;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.inject.internal.Nullable;
|
||||
|
||||
/**
|
||||
* Amazon S3 is designed to store objects. Objects are stored in {@link S3Bucket buckets} and
|
||||
* consist of a {@link org.jclouds.aws.s3.domain.S3Object#getData() value}, a
|
||||
* {@link S3Object#getKey key}, {@link S3Object.Metadata#getUserMetadata() metadata}, and an access
|
||||
* control policy.
|
||||
* Amazon S3 is designed to store objects. Objects are stored in buckets and consist of a
|
||||
* {@link ObjectMetadataS3Object#getData() value}, a {@link ObjectMetadata#getKey key},
|
||||
* {@link ObjectMetadata#getUserMetadata() metadata}, and an access control policy.
|
||||
*
|
||||
* @author Adrian Cole
|
||||
* @see <a href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?UsingObjects.html"
|
||||
* />
|
||||
*/
|
||||
public class S3Object extends BlobImpl<ObjectMetadata> {
|
||||
|
||||
public S3Object(ObjectMetadata metadata, Object data) {
|
||||
super(metadata, data);
|
||||
public interface S3Object extends Comparable<S3Object> {
|
||||
public interface Factory {
|
||||
S3Object create(@Nullable MutableObjectMetadata metadata);
|
||||
}
|
||||
|
||||
public S3Object(ObjectMetadata metadata) {
|
||||
super(metadata);
|
||||
}
|
||||
/**
|
||||
* Sets entity for the request or the content from the response. If size isn't set, this will
|
||||
* attempt to discover it.
|
||||
*
|
||||
* @param data
|
||||
* typically InputStream for downloads, or File, byte [], String, or InputStream for
|
||||
* uploads.
|
||||
*/
|
||||
void setData(Object data);
|
||||
|
||||
public S3Object(String key, Object data) {
|
||||
this(new ObjectMetadata(key), data);
|
||||
}
|
||||
/**
|
||||
* @return InputStream, if downloading, or whatever was set during {@link #setData(Object)}
|
||||
*/
|
||||
Object getData();
|
||||
|
||||
@Inject
|
||||
public S3Object() {
|
||||
this(new ObjectMetadata());
|
||||
}
|
||||
/**
|
||||
* generate an MD5 Hash for the current data.
|
||||
* <p/>
|
||||
* <h2>Note</h2>
|
||||
* <p/>
|
||||
* If this is an InputStream, it will be converted to a byte array first.
|
||||
*
|
||||
* @throws IOException
|
||||
* if there is a problem generating the hash.
|
||||
*/
|
||||
void generateMD5() throws IOException;
|
||||
|
||||
public S3Object(String key) {
|
||||
this(new ObjectMetadata(key));
|
||||
}
|
||||
void setContentLength(long contentLength);
|
||||
|
||||
/**
|
||||
* Returns the total size of the downloaded object, or the chunk that's available.
|
||||
* <p/>
|
||||
* Chunking is only used when org.jclouds.http.GetOptions is called with options like tail,
|
||||
* range, or startAt.
|
||||
*
|
||||
* @return the length in bytes that can be be obtained from {@link #getData()}
|
||||
* @see org.jclouds.http.HttpHeaders#CONTENT_LENGTH
|
||||
* @see GetObjectOptions
|
||||
*/
|
||||
Long getContentLength();
|
||||
|
||||
/**
|
||||
* @return System and User metadata relevant to this object.
|
||||
*/
|
||||
MutableObjectMetadata getMetadata();
|
||||
|
||||
Multimap<String, String> getAllHeaders();
|
||||
|
||||
void setAccessControlList(AccessControlList acl);
|
||||
|
||||
AccessControlList getAccessControlList();
|
||||
|
||||
void setAllHeaders(Multimap<String, String> allHeaders);
|
||||
}
|
|
@ -0,0 +1,251 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
package org.jclouds.aws.s3.domain.internal;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
|
||||
import org.jclouds.aws.s3.domain.CanonicalUser;
|
||||
import org.jclouds.aws.s3.domain.ObjectMetadata;
|
||||
import org.joda.time.DateTime;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
/**
|
||||
* Returns the metadata parsable from a bucket listing
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class BucketListObjectMetadata implements Serializable, ObjectMetadata {
|
||||
|
||||
/** The serialVersionUID */
|
||||
private static final long serialVersionUID = -4415449798024051115L;
|
||||
|
||||
private final String key;
|
||||
private final DateTime lastModified;
|
||||
private final String eTag;
|
||||
private final long size;
|
||||
private final CanonicalUser owner;
|
||||
private final StorageClass storageClass;
|
||||
private final String contentType;
|
||||
private final byte[] contentMD5;
|
||||
private final String cacheControl;
|
||||
private final String contentDisposition;
|
||||
private final String contentEncoding;
|
||||
private final Map<String, String> userMetadata;
|
||||
|
||||
public BucketListObjectMetadata(String key, DateTime lastModified, String eTag, byte[] md5,
|
||||
long size, CanonicalUser owner, StorageClass storageClass) {
|
||||
this.key = key;
|
||||
this.lastModified = lastModified;
|
||||
this.eTag = eTag;
|
||||
this.size = size;
|
||||
this.owner = owner;
|
||||
this.contentMD5 = md5;
|
||||
this.storageClass = storageClass;
|
||||
this.contentType = null;
|
||||
this.cacheControl = null;
|
||||
this.contentDisposition = null;
|
||||
this.contentEncoding = null;
|
||||
this.userMetadata = Maps.newHashMap();
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
public String getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
public CanonicalUser getOwner() {
|
||||
return owner;
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
public StorageClass getStorageClass() {
|
||||
return storageClass;
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
public String getCacheControl() {
|
||||
return cacheControl;
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
public String getContentDisposition() {
|
||||
return contentDisposition;
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
public String getContentEncoding() {
|
||||
return contentEncoding;
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
public String getContentType() {
|
||||
return contentType;
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
public DateTime getLastModified() {
|
||||
return lastModified;
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
public String getETag() {
|
||||
return eTag;
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
public Long getSize() {
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
public int compareTo(ObjectMetadata o) {
|
||||
return (this == o) ? 0 : getKey().compareTo(o.getKey());
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
public Map<String, String> getUserMetadata() {
|
||||
return userMetadata;
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
public byte[] getContentMD5() {
|
||||
return contentMD5;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((cacheControl == null) ? 0 : cacheControl.hashCode());
|
||||
result = prime * result + ((contentDisposition == null) ? 0 : contentDisposition.hashCode());
|
||||
result = prime * result + ((contentEncoding == null) ? 0 : contentEncoding.hashCode());
|
||||
result = prime * result + Arrays.hashCode(contentMD5);
|
||||
result = prime * result + ((contentType == null) ? 0 : contentType.hashCode());
|
||||
result = prime * result + ((eTag == null) ? 0 : eTag.hashCode());
|
||||
result = prime * result + ((key == null) ? 0 : key.hashCode());
|
||||
result = prime * result + ((lastModified == null) ? 0 : lastModified.hashCode());
|
||||
result = prime * result + ((owner == null) ? 0 : owner.hashCode());
|
||||
result = prime * result + (int) (size ^ (size >>> 32));
|
||||
result = prime * result + ((storageClass == null) ? 0 : storageClass.hashCode());
|
||||
result = prime * result + ((userMetadata == null) ? 0 : userMetadata.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
BucketListObjectMetadata other = (BucketListObjectMetadata) obj;
|
||||
if (cacheControl == null) {
|
||||
if (other.cacheControl != null)
|
||||
return false;
|
||||
} else if (!cacheControl.equals(other.cacheControl))
|
||||
return false;
|
||||
if (contentDisposition == null) {
|
||||
if (other.contentDisposition != null)
|
||||
return false;
|
||||
} else if (!contentDisposition.equals(other.contentDisposition))
|
||||
return false;
|
||||
if (contentEncoding == null) {
|
||||
if (other.contentEncoding != null)
|
||||
return false;
|
||||
} else if (!contentEncoding.equals(other.contentEncoding))
|
||||
return false;
|
||||
if (!Arrays.equals(contentMD5, other.contentMD5))
|
||||
return false;
|
||||
if (contentType == null) {
|
||||
if (other.contentType != null)
|
||||
return false;
|
||||
} else if (!contentType.equals(other.contentType))
|
||||
return false;
|
||||
if (eTag == null) {
|
||||
if (other.eTag != null)
|
||||
return false;
|
||||
} else if (!eTag.equals(other.eTag))
|
||||
return false;
|
||||
if (key == null) {
|
||||
if (other.key != null)
|
||||
return false;
|
||||
} else if (!key.equals(other.key))
|
||||
return false;
|
||||
if (lastModified == null) {
|
||||
if (other.lastModified != null)
|
||||
return false;
|
||||
} else if (!lastModified.equals(other.lastModified))
|
||||
return false;
|
||||
if (owner == null) {
|
||||
if (other.owner != null)
|
||||
return false;
|
||||
} else if (!owner.equals(other.owner))
|
||||
return false;
|
||||
if (size != other.size)
|
||||
return false;
|
||||
if (storageClass == null) {
|
||||
if (other.storageClass != null)
|
||||
return false;
|
||||
} else if (!storageClass.equals(other.storageClass))
|
||||
return false;
|
||||
if (userMetadata == null) {
|
||||
if (other.userMetadata != null)
|
||||
return false;
|
||||
} else if (!userMetadata.equals(other.userMetadata))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,252 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
package org.jclouds.aws.s3.domain.internal;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
|
||||
import org.jclouds.aws.s3.domain.CanonicalUser;
|
||||
import org.jclouds.aws.s3.domain.ObjectMetadata;
|
||||
import org.joda.time.DateTime;
|
||||
|
||||
/**
|
||||
* Returns the metadata parsable from a bucket listing
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class CopyObjectResult implements Serializable, ObjectMetadata {
|
||||
|
||||
/** The serialVersionUID */
|
||||
private static final long serialVersionUID = -4415449798024051115L;
|
||||
|
||||
private final String key;
|
||||
private final DateTime lastModified;
|
||||
private final String eTag;
|
||||
private final Long size;
|
||||
private final CanonicalUser owner;
|
||||
private final StorageClass storageClass;
|
||||
private final String contentType;
|
||||
private final byte[] contentMD5;
|
||||
private final String cacheControl;
|
||||
private final String contentDisposition;
|
||||
private final String contentEncoding;
|
||||
private final Map<String, String> userMetadata;
|
||||
|
||||
public CopyObjectResult(DateTime lastModified, String eTag) {
|
||||
this.key = null;
|
||||
this.lastModified = lastModified;
|
||||
this.eTag = eTag;
|
||||
this.size = null;
|
||||
this.owner = null;
|
||||
this.storageClass = StorageClass.STANDARD;
|
||||
this.contentType = null;
|
||||
this.contentMD5 = null;
|
||||
this.cacheControl = null;
|
||||
this.contentDisposition = null;
|
||||
this.contentEncoding = null;
|
||||
this.userMetadata = null;
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
public String getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
public CanonicalUser getOwner() {
|
||||
return owner;
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
public StorageClass getStorageClass() {
|
||||
return storageClass;
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
public String getCacheControl() {
|
||||
return cacheControl;
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
public String getContentDisposition() {
|
||||
return contentDisposition;
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
public String getContentEncoding() {
|
||||
return contentEncoding;
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
public String getContentType() {
|
||||
return contentType;
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
public DateTime getLastModified() {
|
||||
return lastModified;
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
public String getETag() {
|
||||
return eTag;
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
public Long getSize() {
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
public int compareTo(ObjectMetadata o) {
|
||||
return (this == o) ? 0 : getKey().compareTo(o.getKey());
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
public Map<String, String> getUserMetadata() {
|
||||
return userMetadata;
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
public byte[] getContentMD5() {
|
||||
return contentMD5;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((cacheControl == null) ? 0 : cacheControl.hashCode());
|
||||
result = prime * result + ((contentDisposition == null) ? 0 : contentDisposition.hashCode());
|
||||
result = prime * result + ((contentEncoding == null) ? 0 : contentEncoding.hashCode());
|
||||
result = prime * result + Arrays.hashCode(contentMD5);
|
||||
result = prime * result + ((contentType == null) ? 0 : contentType.hashCode());
|
||||
result = prime * result + ((eTag == null) ? 0 : eTag.hashCode());
|
||||
result = prime * result + ((key == null) ? 0 : key.hashCode());
|
||||
result = prime * result + ((lastModified == null) ? 0 : lastModified.hashCode());
|
||||
result = prime * result + ((owner == null) ? 0 : owner.hashCode());
|
||||
result = prime * result + ((size == null) ? 0 : size.hashCode());
|
||||
result = prime * result + ((storageClass == null) ? 0 : storageClass.hashCode());
|
||||
result = prime * result + ((userMetadata == null) ? 0 : userMetadata.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
CopyObjectResult other = (CopyObjectResult) obj;
|
||||
if (cacheControl == null) {
|
||||
if (other.cacheControl != null)
|
||||
return false;
|
||||
} else if (!cacheControl.equals(other.cacheControl))
|
||||
return false;
|
||||
if (contentDisposition == null) {
|
||||
if (other.contentDisposition != null)
|
||||
return false;
|
||||
} else if (!contentDisposition.equals(other.contentDisposition))
|
||||
return false;
|
||||
if (contentEncoding == null) {
|
||||
if (other.contentEncoding != null)
|
||||
return false;
|
||||
} else if (!contentEncoding.equals(other.contentEncoding))
|
||||
return false;
|
||||
if (!Arrays.equals(contentMD5, other.contentMD5))
|
||||
return false;
|
||||
if (contentType == null) {
|
||||
if (other.contentType != null)
|
||||
return false;
|
||||
} else if (!contentType.equals(other.contentType))
|
||||
return false;
|
||||
if (eTag == null) {
|
||||
if (other.eTag != null)
|
||||
return false;
|
||||
} else if (!eTag.equals(other.eTag))
|
||||
return false;
|
||||
if (key == null) {
|
||||
if (other.key != null)
|
||||
return false;
|
||||
} else if (!key.equals(other.key))
|
||||
return false;
|
||||
if (lastModified == null) {
|
||||
if (other.lastModified != null)
|
||||
return false;
|
||||
} else if (!lastModified.equals(other.lastModified))
|
||||
return false;
|
||||
if (owner == null) {
|
||||
if (other.owner != null)
|
||||
return false;
|
||||
} else if (!owner.equals(other.owner))
|
||||
return false;
|
||||
if (size == null) {
|
||||
if (other.size != null)
|
||||
return false;
|
||||
} else if (!size.equals(other.size))
|
||||
return false;
|
||||
if (storageClass == null) {
|
||||
if (other.storageClass != null)
|
||||
return false;
|
||||
} else if (!storageClass.equals(other.storageClass))
|
||||
return false;
|
||||
if (userMetadata == null) {
|
||||
if (other.userMetadata != null)
|
||||
return false;
|
||||
} else if (!userMetadata.equals(other.userMetadata))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,334 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
package org.jclouds.aws.s3.domain.internal;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
|
||||
import org.jclouds.aws.s3.domain.CanonicalUser;
|
||||
import org.jclouds.aws.s3.domain.MutableObjectMetadata;
|
||||
import org.jclouds.aws.s3.domain.ObjectMetadata;
|
||||
import org.joda.time.DateTime;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
/**
|
||||
* Allows you to manipulate metadata.
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class MutableObjectMetadataImpl implements Serializable, MutableObjectMetadata {
|
||||
|
||||
/** The serialVersionUID */
|
||||
private static final long serialVersionUID = -4648755473986695062L;
|
||||
|
||||
private String key;
|
||||
private DateTime lastModified;
|
||||
private String eTag;
|
||||
private long size;
|
||||
private CanonicalUser owner;
|
||||
private StorageClass storageClass;
|
||||
private String contentType;
|
||||
private byte[] contentMD5;
|
||||
private String cacheControl;
|
||||
private String contentDisposition;
|
||||
private String contentEncoding;
|
||||
private Map<String, String> userMetadata = Maps.newHashMap();
|
||||
|
||||
public MutableObjectMetadataImpl() {
|
||||
this.storageClass = StorageClass.STANDARD;
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
public String getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
public CanonicalUser getOwner() {
|
||||
return owner;
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
public StorageClass getStorageClass() {
|
||||
return storageClass;
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
public String getCacheControl() {
|
||||
return cacheControl;
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
public String getContentDisposition() {
|
||||
return contentDisposition;
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
public String getContentEncoding() {
|
||||
return contentEncoding;
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
public String getContentType() {
|
||||
return contentType;
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
public DateTime getLastModified() {
|
||||
return lastModified;
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
public String getETag() {
|
||||
return eTag;
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
public Long getSize() {
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
public int compareTo(ObjectMetadata o) {
|
||||
return (this == o) ? 0 : getKey().compareTo(o.getKey());
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
public Map<String, String> getUserMetadata() {
|
||||
return userMetadata;
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
public byte[] getContentMD5() {
|
||||
if (contentMD5 != null) {
|
||||
byte[] retval = new byte[contentMD5.length];
|
||||
System.arraycopy(this.contentMD5, 0, retval, 0, contentMD5.length);
|
||||
return retval;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
public void setCacheControl(String cacheControl) {
|
||||
this.cacheControl = cacheControl;
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
public void setContentDisposition(String contentDisposition) {
|
||||
this.contentDisposition = contentDisposition;
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
public void setContentEncoding(String encoding) {
|
||||
this.contentEncoding = encoding;
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
public void setContentMD5(byte[] md5) {
|
||||
if (md5 != null) {
|
||||
byte[] retval = new byte[md5.length];
|
||||
System.arraycopy(md5, 0, retval, 0, md5.length);
|
||||
this.contentMD5 = md5;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
public void setContentType(String contentType) {
|
||||
this.contentType = contentType;
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
public void setETag(String eTag) {
|
||||
this.eTag = eTag;
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
public void setKey(String key) {
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
public void setLastModified(DateTime lastModified) {
|
||||
this.lastModified = lastModified;
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
public void setOwner(CanonicalUser owner) {
|
||||
this.owner = owner;
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
public void setSize(long size) {
|
||||
this.size = size;
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
public void setStorageClass(StorageClass storageClass) {
|
||||
this.storageClass = storageClass;
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
public void setUserMetadata(Map<String, String> userMetadata) {
|
||||
this.userMetadata = userMetadata;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((cacheControl == null) ? 0 : cacheControl.hashCode());
|
||||
result = prime * result + ((contentDisposition == null) ? 0 : contentDisposition.hashCode());
|
||||
result = prime * result + ((contentEncoding == null) ? 0 : contentEncoding.hashCode());
|
||||
result = prime * result + Arrays.hashCode(contentMD5);
|
||||
result = prime * result + ((contentType == null) ? 0 : contentType.hashCode());
|
||||
result = prime * result + ((eTag == null) ? 0 : eTag.hashCode());
|
||||
result = prime * result + ((key == null) ? 0 : key.hashCode());
|
||||
result = prime * result + ((lastModified == null) ? 0 : lastModified.hashCode());
|
||||
result = prime * result + ((owner == null) ? 0 : owner.hashCode());
|
||||
result = prime * result + (int) (size ^ (size >>> 32));
|
||||
result = prime * result + ((storageClass == null) ? 0 : storageClass.hashCode());
|
||||
result = prime * result + ((userMetadata == null) ? 0 : userMetadata.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
MutableObjectMetadataImpl other = (MutableObjectMetadataImpl) obj;
|
||||
if (cacheControl == null) {
|
||||
if (other.cacheControl != null)
|
||||
return false;
|
||||
} else if (!cacheControl.equals(other.cacheControl))
|
||||
return false;
|
||||
if (contentDisposition == null) {
|
||||
if (other.contentDisposition != null)
|
||||
return false;
|
||||
} else if (!contentDisposition.equals(other.contentDisposition))
|
||||
return false;
|
||||
if (contentEncoding == null) {
|
||||
if (other.contentEncoding != null)
|
||||
return false;
|
||||
} else if (!contentEncoding.equals(other.contentEncoding))
|
||||
return false;
|
||||
if (!Arrays.equals(contentMD5, other.contentMD5))
|
||||
return false;
|
||||
if (contentType == null) {
|
||||
if (other.contentType != null)
|
||||
return false;
|
||||
} else if (!contentType.equals(other.contentType))
|
||||
return false;
|
||||
if (eTag == null) {
|
||||
if (other.eTag != null)
|
||||
return false;
|
||||
} else if (!eTag.equals(other.eTag))
|
||||
return false;
|
||||
if (key == null) {
|
||||
if (other.key != null)
|
||||
return false;
|
||||
} else if (!key.equals(other.key))
|
||||
return false;
|
||||
if (lastModified == null) {
|
||||
if (other.lastModified != null)
|
||||
return false;
|
||||
} else if (!lastModified.equals(other.lastModified))
|
||||
return false;
|
||||
if (owner == null) {
|
||||
if (other.owner != null)
|
||||
return false;
|
||||
} else if (!owner.equals(other.owner))
|
||||
return false;
|
||||
if (size != other.size)
|
||||
return false;
|
||||
if (storageClass == null) {
|
||||
if (other.storageClass != null)
|
||||
return false;
|
||||
} else if (!storageClass.equals(other.storageClass))
|
||||
return false;
|
||||
if (userMetadata == null) {
|
||||
if (other.userMetadata != null)
|
||||
return false;
|
||||
} else if (!userMetadata.equals(other.userMetadata))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,210 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
package org.jclouds.aws.s3.domain.internal;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.base.Preconditions.checkState;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.jclouds.aws.s3.domain.AccessControlList;
|
||||
import org.jclouds.aws.s3.domain.MutableObjectMetadata;
|
||||
import org.jclouds.aws.s3.domain.S3Object;
|
||||
import org.jclouds.blobstore.domain.MD5InputStreamResult;
|
||||
import org.jclouds.blobstore.functions.CalculateSize;
|
||||
import org.jclouds.blobstore.functions.GenerateMD5;
|
||||
import org.jclouds.blobstore.functions.GenerateMD5Result;
|
||||
|
||||
import com.google.common.collect.HashMultimap;
|
||||
import com.google.common.collect.Multimap;
|
||||
|
||||
/**
|
||||
* Default Implementation of {@link S3Object}.
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class S3ObjectImpl implements S3Object, Comparable<S3Object> {
|
||||
private final GenerateMD5Result generateMD5Result;
|
||||
private final GenerateMD5 generateMD5;
|
||||
private final CalculateSize calculateSize;
|
||||
private final MutableObjectMetadata metadata;
|
||||
private Object data;
|
||||
private Multimap<String, String> allHeaders = HashMultimap.create();
|
||||
private Long contentLength;
|
||||
|
||||
@Inject
|
||||
public S3ObjectImpl(GenerateMD5Result generateMD5Result, GenerateMD5 generateMD5,
|
||||
CalculateSize calculateSize, MutableObjectMetadata metadata) {
|
||||
this.generateMD5Result = generateMD5Result;
|
||||
this.generateMD5 = generateMD5;
|
||||
this.calculateSize = calculateSize;
|
||||
this.metadata = metadata;
|
||||
}
|
||||
|
||||
private AccessControlList accessControlList;
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public void setAccessControlList(AccessControlList acl) {
|
||||
this.accessControlList = acl;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public AccessControlList getAccessControlList() {
|
||||
return this.accessControlList;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public void generateMD5() {
|
||||
checkState(data != null, "data");
|
||||
if (data instanceof InputStream) {
|
||||
MD5InputStreamResult result = generateMD5Result.apply((InputStream) data);
|
||||
getMetadata().setContentMD5(result.md5);
|
||||
setContentLength(result.length);
|
||||
setData(result.data);
|
||||
} else {
|
||||
getMetadata().setContentMD5(generateMD5.apply(data));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public Object getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public void setData(Object data) {
|
||||
this.data = checkNotNull(data, "data");
|
||||
if (getContentLength() == null) {
|
||||
Long size = calculateSize.apply(data);
|
||||
if (size != null)
|
||||
this.setContentLength(size);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public Long getContentLength() {
|
||||
return contentLength;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public void setContentLength(long contentLength) {
|
||||
this.contentLength = contentLength;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public MutableObjectMetadata getMetadata() {
|
||||
return metadata;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public Multimap<String, String> getAllHeaders() {
|
||||
return allHeaders;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public void setAllHeaders(Multimap<String, String> allHeaders) {
|
||||
this.allHeaders = checkNotNull(allHeaders, "allHeaders");
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public int compareTo(S3Object o) {
|
||||
if (getMetadata().getKey() == null)
|
||||
return -1;
|
||||
return (this == o) ? 0 : getMetadata().getKey().compareTo(o.getMetadata().getKey());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((accessControlList == null) ? 0 : accessControlList.hashCode());
|
||||
result = prime * result + ((allHeaders == null) ? 0 : allHeaders.hashCode());
|
||||
result = prime * result + ((contentLength == null) ? 0 : contentLength.hashCode());
|
||||
result = prime * result + ((data == null) ? 0 : data.hashCode());
|
||||
result = prime * result + ((metadata == null) ? 0 : metadata.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
S3ObjectImpl other = (S3ObjectImpl) obj;
|
||||
if (accessControlList == null) {
|
||||
if (other.accessControlList != null)
|
||||
return false;
|
||||
} else if (!accessControlList.equals(other.accessControlList))
|
||||
return false;
|
||||
if (allHeaders == null) {
|
||||
if (other.allHeaders != null)
|
||||
return false;
|
||||
} else if (!allHeaders.equals(other.allHeaders))
|
||||
return false;
|
||||
if (contentLength == null) {
|
||||
if (other.contentLength != null)
|
||||
return false;
|
||||
} else if (!contentLength.equals(other.contentLength))
|
||||
return false;
|
||||
if (data == null) {
|
||||
if (other.data != null)
|
||||
return false;
|
||||
} else if (!data.equals(other.data))
|
||||
return false;
|
||||
if (metadata == null) {
|
||||
if (other.metadata != null)
|
||||
return false;
|
||||
} else if (!metadata.equals(other.metadata))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,168 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
package org.jclouds.aws.s3.domain.internal;
|
||||
|
||||
import java.util.SortedSet;
|
||||
import java.util.TreeSet;
|
||||
|
||||
import org.jclouds.aws.s3.domain.ListBucketResponse;
|
||||
import org.jclouds.aws.s3.domain.ObjectMetadata;
|
||||
|
||||
import com.google.common.collect.Iterables;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*
|
||||
*/
|
||||
public class TreeSetListBucketResponse extends TreeSet<ObjectMetadata> implements
|
||||
ListBucketResponse {
|
||||
/** The serialVersionUID */
|
||||
private static final long serialVersionUID = -4475709781001190244L;
|
||||
private final String name;
|
||||
protected final String prefix;
|
||||
protected final int maxKeys;
|
||||
private final String delimiter;
|
||||
protected final String marker;
|
||||
private final SortedSet<String> commonPrefixes;
|
||||
protected final boolean truncated;
|
||||
|
||||
public TreeSetListBucketResponse(String name, Iterable<ObjectMetadata> contents, String prefix,
|
||||
String marker, int maxKeys, String delimiter, boolean isTruncated,
|
||||
SortedSet<String> commonPrefixes) {
|
||||
Iterables.addAll(this, contents);
|
||||
this.name = name;
|
||||
this.prefix = prefix;
|
||||
this.marker = marker;
|
||||
this.maxKeys = maxKeys;
|
||||
this.truncated = isTruncated;
|
||||
this.delimiter = delimiter;
|
||||
this.commonPrefixes = commonPrefixes;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public SortedSet<String> getCommonPrefixes() {
|
||||
return commonPrefixes;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public String getDelimiter() {
|
||||
return delimiter;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public String getMarker() {
|
||||
return marker;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public int getMaxKeys() {
|
||||
return maxKeys;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public String getPrefix() {
|
||||
return prefix;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public boolean isTruncated() {
|
||||
return truncated;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = super.hashCode();
|
||||
result = prime * result + ((commonPrefixes == null) ? 0 : commonPrefixes.hashCode());
|
||||
result = prime * result + ((delimiter == null) ? 0 : delimiter.hashCode());
|
||||
result = prime * result + ((marker == null) ? 0 : marker.hashCode());
|
||||
result = prime * result + maxKeys;
|
||||
result = prime * result + ((name == null) ? 0 : name.hashCode());
|
||||
result = prime * result + ((prefix == null) ? 0 : prefix.hashCode());
|
||||
result = prime * result + (truncated ? 1231 : 1237);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (!super.equals(obj))
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
TreeSetListBucketResponse other = (TreeSetListBucketResponse) obj;
|
||||
if (commonPrefixes == null) {
|
||||
if (other.commonPrefixes != null)
|
||||
return false;
|
||||
} else if (!commonPrefixes.equals(other.commonPrefixes))
|
||||
return false;
|
||||
if (delimiter == null) {
|
||||
if (other.delimiter != null)
|
||||
return false;
|
||||
} else if (!delimiter.equals(other.delimiter))
|
||||
return false;
|
||||
if (marker == null) {
|
||||
if (other.marker != null)
|
||||
return false;
|
||||
} else if (!marker.equals(other.marker))
|
||||
return false;
|
||||
if (maxKeys != other.maxKeys)
|
||||
return false;
|
||||
if (name == null) {
|
||||
if (other.name != null)
|
||||
return false;
|
||||
} else if (!name.equals(other.name))
|
||||
return false;
|
||||
if (prefix == null) {
|
||||
if (other.prefix != null)
|
||||
return false;
|
||||
} else if (!prefix.equals(other.prefix))
|
||||
return false;
|
||||
if (truncated != other.truncated)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
|
|
|
@ -1,45 +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.aws.s3.functions;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.jclouds.aws.s3.domain.BucketMetadata;
|
||||
import org.jclouds.aws.s3.domain.ObjectMetadata;
|
||||
import org.jclouds.aws.s3.domain.S3Object;
|
||||
import org.jclouds.blobstore.BlobStore;
|
||||
import org.jclouds.blobstore.functions.ClearAndDeleteIfNotEmpty;
|
||||
import org.jclouds.blobstore.strategy.ClearContainerStrategy;
|
||||
|
||||
public class ClearAndDeleteBucketIfNotEmpty extends
|
||||
ClearAndDeleteIfNotEmpty<BucketMetadata, ObjectMetadata, S3Object> {
|
||||
|
||||
@Inject
|
||||
ClearAndDeleteBucketIfNotEmpty(
|
||||
ClearContainerStrategy<BucketMetadata, ObjectMetadata, S3Object> clear,
|
||||
BlobStore<BucketMetadata, ObjectMetadata, S3Object> connection) {
|
||||
super(clear, connection);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
package org.jclouds.aws.s3.functions;
|
||||
|
||||
import org.jclouds.aws.s3.domain.S3Object;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class ObjectKey implements Function<Object, String> {
|
||||
|
||||
public String apply(Object from) {
|
||||
return ((S3Object) from).getMetadata().getKey();
|
||||
}
|
||||
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
|
@ -24,11 +24,17 @@
|
|||
package org.jclouds.aws.s3.functions;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Provider;
|
||||
import javax.ws.rs.core.HttpHeaders;
|
||||
|
||||
import org.jclouds.aws.s3.domain.ObjectMetadata;
|
||||
import org.jclouds.aws.s3.domain.S3Object;
|
||||
import org.jclouds.blobstore.functions.ParseBlobFromHeadersAndHttpContent;
|
||||
import org.jclouds.blobstore.functions.ParseSystemAndUserMetadataFromHeaders;
|
||||
import org.jclouds.http.HttpException;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.jclouds.rest.InvocationContext;
|
||||
import org.jclouds.rest.internal.GeneratedHttpRequest;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.base.Function;
|
||||
|
||||
/**
|
||||
* Parses response headers and creates a new S3Object from them and the HTTP content.
|
||||
|
@ -36,13 +42,60 @@ import org.jclouds.blobstore.functions.ParseBlobFromHeadersAndHttpContent;
|
|||
* @see ParseMetadataFromHeaders
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class ParseObjectFromHeadersAndHttpContent extends
|
||||
ParseBlobFromHeadersAndHttpContent<ObjectMetadata, S3Object> {
|
||||
public class ParseObjectFromHeadersAndHttpContent implements Function<HttpResponse, S3Object>,
|
||||
InvocationContext {
|
||||
|
||||
private final ParseObjectMetadataFromHeaders metadataParser;
|
||||
private final S3Object.Factory objectProvider;
|
||||
|
||||
@Inject
|
||||
public ParseObjectFromHeadersAndHttpContent(ParseObjectMetadataFromHeaders metadataParser,
|
||||
Provider<S3Object> blobFactory) {
|
||||
super(metadataParser, blobFactory);
|
||||
S3Object.Factory objectProvider) {
|
||||
this.metadataParser = metadataParser;
|
||||
this.objectProvider = objectProvider;
|
||||
}
|
||||
|
||||
/**
|
||||
* First, calls {@link ParseSystemAndUserMetadataFromHeaders}.
|
||||
*
|
||||
* Then, sets the object size based on the Content-Length header and adds the content to the
|
||||
* {@link S3Object} result.
|
||||
*
|
||||
* @throws org.jclouds.http.HttpException
|
||||
*/
|
||||
public S3Object apply(HttpResponse from) {
|
||||
S3Object object = objectProvider.create(metadataParser.apply(from));
|
||||
addAllHeadersTo(from, object);
|
||||
object.setData(from.getContent());
|
||||
attemptToParseSizeAndRangeFromHeaders(from, object);
|
||||
return object;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void attemptToParseSizeAndRangeFromHeaders(HttpResponse from, S3Object object)
|
||||
throws HttpException {
|
||||
String contentLength = from.getFirstHeaderOrNull(HttpHeaders.CONTENT_LENGTH);
|
||||
String contentRange = from.getFirstHeaderOrNull("Content-Range");
|
||||
|
||||
if (contentLength != null) {
|
||||
object.setContentLength(Long.parseLong(contentLength));
|
||||
}
|
||||
|
||||
if (contentRange == null && contentLength != null) {
|
||||
object.getMetadata().setSize(object.getContentLength());
|
||||
} else if (contentRange != null) {
|
||||
object.getMetadata().setSize(
|
||||
Long.parseLong(contentRange.substring(contentRange.lastIndexOf('/') + 1)));
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void addAllHeadersTo(HttpResponse from, S3Object object) {
|
||||
object.getAllHeaders().putAll(from.getHeaders());
|
||||
}
|
||||
|
||||
public void setContext(GeneratedHttpRequest<?> request) {
|
||||
metadataParser.setContext(request);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
|
@ -23,45 +23,50 @@
|
|||
*/
|
||||
package org.jclouds.aws.s3.functions;
|
||||
|
||||
import static org.jclouds.blobstore.reference.BlobStoreConstants.PROPERTY_USER_METADATA_PREFIX;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Provider;
|
||||
import javax.ws.rs.core.HttpHeaders;
|
||||
|
||||
import org.jclouds.aws.s3.domain.ObjectMetadata;
|
||||
import org.jclouds.aws.s3.blobstore.functions.BlobToObjectMetadata;
|
||||
import org.jclouds.aws.s3.domain.MutableObjectMetadata;
|
||||
import org.jclouds.aws.s3.reference.S3Headers;
|
||||
import org.jclouds.blobstore.domain.BlobMetadata;
|
||||
import org.jclouds.blobstore.functions.ParseSystemAndUserMetadataFromHeaders;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.jclouds.http.HttpUtils;
|
||||
import org.jclouds.util.DateService;
|
||||
import org.jclouds.rest.InvocationContext;
|
||||
import org.jclouds.rest.internal.GeneratedHttpRequest;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.base.Function;
|
||||
|
||||
/**
|
||||
* This parses @{link {@link org.jclouds.aws.s3.domain.ObjectMetadata} from HTTP headers.
|
||||
* This parses @{link {@link org.jclouds.aws.s3.domain.internal.MutableObjectMetadata} from HTTP
|
||||
* headers.
|
||||
*
|
||||
* @see <a href="http://docs.amazonwebservices.com/AmazonS3/latest/RESTObjectGET.html" />
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class ParseObjectMetadataFromHeaders extends
|
||||
ParseSystemAndUserMetadataFromHeaders<ObjectMetadata> {
|
||||
public class ParseObjectMetadataFromHeaders implements
|
||||
Function<HttpResponse, MutableObjectMetadata>, InvocationContext {
|
||||
private final ParseSystemAndUserMetadataFromHeaders blobMetadataParser;
|
||||
private final BlobToObjectMetadata blobToObjectMetadata;
|
||||
|
||||
@Inject
|
||||
public ParseObjectMetadataFromHeaders(DateService dateParser,
|
||||
@Named(PROPERTY_USER_METADATA_PREFIX) String metadataPrefix,
|
||||
Provider<ObjectMetadata> metadataFactory) {
|
||||
super(dateParser, metadataPrefix, metadataFactory);
|
||||
public ParseObjectMetadataFromHeaders(ParseSystemAndUserMetadataFromHeaders blobMetadataParser,
|
||||
BlobToObjectMetadata blobToObjectMetadata) {
|
||||
this.blobMetadataParser = blobMetadataParser;
|
||||
this.blobToObjectMetadata = blobToObjectMetadata;
|
||||
}
|
||||
|
||||
/**
|
||||
* parses the http response headers to create a new
|
||||
* {@link org.jclouds.aws.s3.domain.ObjectMetadata} object.
|
||||
* {@link org.jclouds.aws.s3.domain.internal.MutableObjectMetadata} object.
|
||||
*/
|
||||
@Override
|
||||
public ObjectMetadata apply(HttpResponse from) {
|
||||
ObjectMetadata to = super.apply(from);
|
||||
public MutableObjectMetadata apply(HttpResponse from) {
|
||||
BlobMetadata base = blobMetadataParser.apply(from);
|
||||
MutableObjectMetadata to = blobToObjectMetadata.apply(base);
|
||||
addETagTo(from, to);
|
||||
to.setContentMD5(HttpUtils.fromHexString(to.getETag().replaceAll("\"", "")));
|
||||
to.setCacheControl(from.getFirstHeaderOrNull(HttpHeaders.CACHE_CONTROL));
|
||||
to.setContentDisposition(from.getFirstHeaderOrNull("Content-Disposition"));
|
||||
to.setContentEncoding(from.getFirstHeaderOrNull(HttpHeaders.CONTENT_ENCODING));
|
||||
|
@ -72,15 +77,17 @@ public class ParseObjectMetadataFromHeaders extends
|
|||
* ETag == Content-MD5
|
||||
*/
|
||||
@VisibleForTesting
|
||||
protected void addETagTo(HttpResponse from, ObjectMetadata metadata) {
|
||||
super.addETagTo(from, metadata);
|
||||
protected void addETagTo(HttpResponse from, MutableObjectMetadata metadata) {
|
||||
if (metadata.getETag() == null) {
|
||||
String eTagHeader = from.getFirstHeaderOrNull(S3Headers.AMZ_MD5);
|
||||
if (eTagHeader != null) {
|
||||
metadata.setETag(eTagHeader);
|
||||
}
|
||||
}
|
||||
metadata.setContentMD5(HttpUtils.fromHexString(metadata.getETag().replaceAll("\"", "")));
|
||||
}
|
||||
|
||||
public void setContext(GeneratedHttpRequest<?> request) {
|
||||
blobMetadataParser.setContext(request);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
|
@ -23,6 +23,8 @@
|
|||
*/
|
||||
package org.jclouds.aws.s3.functions;
|
||||
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.aws.AWSResponseException;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
|
@ -31,6 +33,7 @@ import com.google.common.base.Function;
|
|||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Singleton
|
||||
public class ReturnTrueIfBucketAlreadyOwnedByYou implements Function<Exception, Boolean> {
|
||||
|
||||
public Boolean apply(Exception from) {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
|
@ -23,10 +23,13 @@
|
|||
*/
|
||||
package org.jclouds.aws.s3.functions;
|
||||
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.aws.AWSResponseException;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
|
||||
@Singleton
|
||||
public class ReturnTrueOn404FalseIfNotEmpty implements Function<Exception, Boolean> {
|
||||
|
||||
public Boolean apply(Exception from) {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
|
@ -62,7 +62,7 @@ public class AWSClientErrorRetryHandler implements HttpRetryHandler {
|
|||
if (command.getFailureCount() > retryCountLimit)
|
||||
return false;
|
||||
if (response.getStatusCode() == 400 || response.getStatusCode() == 409) {
|
||||
byte[] content = Utils.closeConnectionButKeepContentStream(response);
|
||||
byte[] content = Utils.closeClientButKeepContentStream(response);
|
||||
command.incrementFailureCount();
|
||||
try {
|
||||
AWSError error = utils.parseAWSErrorFromContent(command, response, new String(content));
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
|
@ -55,7 +55,7 @@ public class AWSRedirectionRetryHandler extends RedirectionRetryHandler {
|
|||
public boolean shouldRetryRequest(HttpCommand command, HttpResponse response) {
|
||||
if (response.getFirstHeaderOrNull(HttpHeaders.LOCATION) == null
|
||||
&& (response.getStatusCode() == 301 || response.getStatusCode() == 307)) {
|
||||
byte[] content = Utils.closeConnectionButKeepContentStream(response);
|
||||
byte[] content = Utils.closeClientButKeepContentStream(response);
|
||||
if (command.getRequest().getMethod() == HttpMethod.HEAD) {
|
||||
command.setMethod(HttpMethod.GET);
|
||||
return true;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
|
@ -53,7 +53,7 @@ import com.google.common.collect.Multimap;
|
|||
* <code>
|
||||
* import static org.jclouds.aws.s3.commands.options.CopyObjectOptions.Builder.*
|
||||
* <p/>
|
||||
* S3Connection connection = // get connection
|
||||
* S3Client connection = // get connection
|
||||
* <p/>
|
||||
* Multimap<String,String> metadata = HashMultimap.create();
|
||||
* metadata.put("x-amz-meta-adrian", "foo");
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
|
@ -37,7 +37,7 @@ import org.jclouds.http.options.BaseHttpRequestOptions;
|
|||
* <code>
|
||||
* import static org.jclouds.aws.s3.commands.options.GetBucketOptions.Builder.*
|
||||
* <p/>
|
||||
* S3Connection connection = // get connection
|
||||
* S3Client connection = // get connection
|
||||
* Future<S3Bucket> bucket = connection.listBucket("bucketName",withPrefix("home/users").maxKeys(1000));
|
||||
* <code>
|
||||
*
|
||||
|
@ -60,6 +60,10 @@ public class ListBucketOptions extends BaseHttpRequestOptions {
|
|||
return this;
|
||||
}
|
||||
|
||||
public String getPrefix() {
|
||||
return getFirstQueryOrNull("prefix");
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates where in the bucket to begin listing. The list will only include keys that occur
|
||||
* lexicographically after marker. This is convenient for pagination: To get the next page of
|
||||
|
@ -70,17 +74,25 @@ public class ListBucketOptions extends BaseHttpRequestOptions {
|
|||
return this;
|
||||
}
|
||||
|
||||
public String getMarker() {
|
||||
return getFirstQueryOrNull("marker");
|
||||
}
|
||||
|
||||
/**
|
||||
* The maximum number of keys you'd like to see in the response body. The server might return
|
||||
* fewer than this many keys, but will not return more.
|
||||
*/
|
||||
public ListBucketOptions maxResults(long maxKeys) {
|
||||
public ListBucketOptions maxResults(int maxKeys) {
|
||||
checkState(maxKeys >= 0, "maxKeys must be >= 0");
|
||||
queryParameters.put("max-keys", Long.toString(maxKeys));
|
||||
return this;
|
||||
}
|
||||
|
||||
public Integer getMaxResults() {
|
||||
String returnVal = getFirstQueryOrNull("max-keys");
|
||||
return (returnVal != null) ? new Integer(returnVal) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Causes keys that contain the same string between the prefix and the first occurrence of the
|
||||
* delimiter to be rolled up into a single result element in the CommonPrefixes collection. These
|
||||
|
@ -92,6 +104,10 @@ public class ListBucketOptions extends BaseHttpRequestOptions {
|
|||
return this;
|
||||
}
|
||||
|
||||
public String getDelimiter() {
|
||||
return getFirstQueryOrNull("delimiter");
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
|
||||
/**
|
||||
|
@ -111,9 +127,9 @@ public class ListBucketOptions extends BaseHttpRequestOptions {
|
|||
}
|
||||
|
||||
/**
|
||||
* @see ListBucketOptions#maxResults(long)
|
||||
* @see ListBucketOptions#maxResults(int)
|
||||
*/
|
||||
public static ListBucketOptions maxResults(long maxKeys) {
|
||||
public static ListBucketOptions maxResults(int maxKeys) {
|
||||
ListBucketOptions options = new ListBucketOptions();
|
||||
return options.maxResults(maxKeys);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
|
@ -39,9 +39,9 @@ import org.jclouds.http.options.BaseHttpRequestOptions;
|
|||
* <code>
|
||||
* import static org.jclouds.aws.s3.commands.options.PutBucketOptions.Builder.*
|
||||
* import static org.jclouds.aws.s3.domain.S3Bucket.Metadata.LocationConstraint.*;
|
||||
* import org.jclouds.aws.s3.S3Connection;
|
||||
* import org.jclouds.aws.s3.S3Client;
|
||||
* <p/>
|
||||
* S3Connection connection = // get connection
|
||||
* S3Client connection = // get connection
|
||||
* Future<Boolean> createdInEu = connection.putBucketIfNotExists("bucketName",createIn(EU));
|
||||
* <code>
|
||||
*
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
|
@ -39,9 +39,9 @@ import static com.google.common.base.Preconditions.*;
|
|||
* <p/>
|
||||
* <code>
|
||||
* import static org.jclouds.aws.s3.commands.options.PutObjectOptions.Builder.*
|
||||
* import org.jclouds.aws.s3.S3Connection;
|
||||
* import org.jclouds.aws.s3.S3Client;
|
||||
*
|
||||
* S3Connection connection = // get connection
|
||||
* S3Client connection = // get connection
|
||||
* Future<Boolean> publicly readable = connection.putObject("bucketName",new S3Object("key","value"), withAcl(CannedAccessPolicy.PUBLIC_READ));
|
||||
* <code>
|
||||
*
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
|
@ -24,14 +24,13 @@
|
|||
package org.jclouds.aws.s3.reference;
|
||||
|
||||
import org.jclouds.aws.reference.AWSConstants;
|
||||
import org.jclouds.blobstore.reference.BlobStoreConstants;
|
||||
|
||||
/**
|
||||
* Configuration properties and constants used in S3 connections.
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public interface S3Constants extends AWSConstants, S3Headers, BlobStoreConstants {
|
||||
public interface S3Constants extends AWSConstants, S3Headers {
|
||||
|
||||
/**
|
||||
* S3 service's XML Namespace, as used in XML request and response documents.
|
||||
|
@ -47,5 +46,6 @@ public interface S3Constants extends AWSConstants, S3Headers, BlobStoreConstants
|
|||
* how long do we wait before obtaining a new timestamp for requests.
|
||||
*/
|
||||
public static final String PROPERTY_S3_SESSIONINTERVAL = "jclouds.s3.sessioninterval";
|
||||
public static final String PROPERTY_S3_METADATA_PREFIX = "jclouds.s3.metaprefix";
|
||||
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
|
@ -26,8 +26,10 @@ package org.jclouds.aws.s3.xml;
|
|||
import javax.inject.Inject;
|
||||
|
||||
import org.jclouds.aws.s3.domain.ObjectMetadata;
|
||||
import org.jclouds.aws.s3.domain.internal.CopyObjectResult;
|
||||
import org.jclouds.http.functions.ParseSax;
|
||||
import org.jclouds.util.DateService;
|
||||
import org.joda.time.DateTime;
|
||||
|
||||
/**
|
||||
* Parses the response from Amazon S3 COPY Object command.
|
||||
|
@ -39,10 +41,12 @@ import org.jclouds.util.DateService;
|
|||
*/
|
||||
public class CopyObjectHandler extends ParseSax.HandlerWithResult<ObjectMetadata> {
|
||||
|
||||
private ObjectMetadata metadata = new ObjectMetadata();
|
||||
private CopyObjectResult metadata;
|
||||
private StringBuilder currentText = new StringBuilder();
|
||||
@Inject
|
||||
private DateService dateParser;
|
||||
private DateTime currentLastModified;
|
||||
private String currentETag;
|
||||
|
||||
public ObjectMetadata getResult() {
|
||||
return metadata;
|
||||
|
@ -50,9 +54,11 @@ public class CopyObjectHandler extends ParseSax.HandlerWithResult<ObjectMetadata
|
|||
|
||||
public void endElement(String uri, String name, String qName) {
|
||||
if (qName.equals("ETag")) {
|
||||
metadata.setETag(currentText.toString());
|
||||
this.currentETag = currentText.toString().trim();
|
||||
} else if (qName.equals("LastModified")) {
|
||||
metadata.setLastModified(dateParser.iso8601DateParse(currentText.toString()));
|
||||
this.currentLastModified = dateParser.iso8601DateParse(currentText.toString().trim());
|
||||
} else if (qName.equals("CopyObjectResult")) {
|
||||
metadata = new CopyObjectResult(currentLastModified, currentETag);
|
||||
}
|
||||
currentText = new StringBuilder();
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
|
@ -31,6 +31,7 @@ import org.jclouds.aws.s3.domain.BucketMetadata;
|
|||
import org.jclouds.aws.s3.domain.CanonicalUser;
|
||||
import org.jclouds.http.functions.ParseSax;
|
||||
import org.jclouds.util.DateService;
|
||||
import org.joda.time.DateTime;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
|
@ -47,11 +48,12 @@ import com.google.common.collect.Sets;
|
|||
public class ListAllMyBucketsHandler extends ParseSax.HandlerWithResult<SortedSet<BucketMetadata>> {
|
||||
|
||||
private SortedSet<BucketMetadata> buckets = Sets.newTreeSet();
|
||||
private BucketMetadata currentS3Bucket;
|
||||
private CanonicalUser currentOwner;
|
||||
private StringBuilder currentText = new StringBuilder();
|
||||
|
||||
private final DateService dateParser;
|
||||
private String currentName;
|
||||
private DateTime currentCreationDate;
|
||||
|
||||
@Inject
|
||||
public ListAllMyBucketsHandler(DateService dateParser) {
|
||||
|
@ -64,16 +66,15 @@ public class ListAllMyBucketsHandler extends ParseSax.HandlerWithResult<SortedSe
|
|||
|
||||
public void endElement(String uri, String name, String qName) {
|
||||
if (qName.equals("ID")) { // owner stuff
|
||||
currentOwner = new CanonicalUser(currentText.toString());
|
||||
currentOwner = new CanonicalUser(currentText.toString().trim());
|
||||
} else if (qName.equals("DisplayName")) {
|
||||
currentOwner.setDisplayName(currentText.toString());
|
||||
currentOwner.setDisplayName(currentText.toString().trim());
|
||||
} else if (qName.equals("Bucket")) {
|
||||
currentS3Bucket.setOwner(currentOwner);
|
||||
buckets.add(currentS3Bucket);
|
||||
buckets.add(new BucketMetadata(currentName, currentCreationDate, currentOwner));
|
||||
} else if (qName.equals("Name")) {
|
||||
currentS3Bucket = new BucketMetadata(currentText.toString());
|
||||
currentName = currentText.toString().trim();
|
||||
} else if (qName.equals("CreationDate")) {
|
||||
currentS3Bucket.setCreationDate(dateParser.iso8601DateParse(currentText.toString()));
|
||||
currentCreationDate = dateParser.iso8601DateParse(currentText.toString().trim());
|
||||
}
|
||||
currentText = new StringBuilder();
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
|
@ -30,10 +30,13 @@ import javax.inject.Inject;
|
|||
import org.jclouds.aws.s3.domain.CanonicalUser;
|
||||
import org.jclouds.aws.s3.domain.ListBucketResponse;
|
||||
import org.jclouds.aws.s3.domain.ObjectMetadata;
|
||||
import org.jclouds.aws.s3.domain.TreeSetListBucketResponse;
|
||||
import org.jclouds.aws.s3.domain.ObjectMetadata.StorageClass;
|
||||
import org.jclouds.aws.s3.domain.internal.BucketListObjectMetadata;
|
||||
import org.jclouds.aws.s3.domain.internal.TreeSetListBucketResponse;
|
||||
import org.jclouds.http.HttpUtils;
|
||||
import org.jclouds.http.functions.ParseSax;
|
||||
import org.jclouds.util.DateService;
|
||||
import org.joda.time.DateTime;
|
||||
import org.xml.sax.Attributes;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
|
@ -51,7 +54,6 @@ import com.google.common.collect.Sets;
|
|||
public class ListBucketHandler extends ParseSax.HandlerWithResult<ListBucketResponse> {
|
||||
private SortedSet<ObjectMetadata> contents;
|
||||
private SortedSet<String> commonPrefixes;
|
||||
private ObjectMetadata currentObjectMetadata;
|
||||
private CanonicalUser currentOwner;
|
||||
private StringBuilder currentText = new StringBuilder();
|
||||
|
||||
|
@ -76,6 +78,12 @@ public class ListBucketHandler extends ParseSax.HandlerWithResult<ListBucketResp
|
|||
}
|
||||
|
||||
private boolean inCommonPrefixes;
|
||||
private String currentKey;
|
||||
private DateTime currentLastModified;
|
||||
private String currentETag;
|
||||
private byte[] currentMD5;
|
||||
private long currentSize;
|
||||
private StorageClass currentStorageClass;
|
||||
|
||||
public void startElement(String uri, String name, String qName, Attributes attrs) {
|
||||
if (qName.equals("CommonPrefixes")) {
|
||||
|
@ -85,27 +93,26 @@ public class ListBucketHandler extends ParseSax.HandlerWithResult<ListBucketResp
|
|||
|
||||
public void endElement(String uri, String name, String qName) {
|
||||
if (qName.equals("ID")) {
|
||||
currentOwner = new CanonicalUser(currentText.toString());
|
||||
currentOwner = new CanonicalUser(currentText.toString().trim());
|
||||
} else if (qName.equals("DisplayName")) {
|
||||
currentOwner.setDisplayName(currentText.toString());
|
||||
currentOwner.setDisplayName(currentText.toString().trim());
|
||||
} else if (qName.equals("Key")) { // content stuff
|
||||
currentObjectMetadata = new ObjectMetadata(currentText.toString());
|
||||
currentKey = currentText.toString().trim();
|
||||
} else if (qName.equals("LastModified")) {
|
||||
currentObjectMetadata.setLastModified(dateParser.iso8601DateParse(currentText.toString()));
|
||||
currentLastModified = dateParser.iso8601DateParse(currentText.toString().trim());
|
||||
} else if (qName.equals("ETag")) {
|
||||
currentObjectMetadata.setETag(currentText.toString());
|
||||
currentObjectMetadata.setContentMD5(HttpUtils.fromHexString(currentObjectMetadata
|
||||
.getETag().replaceAll("\"", "")));
|
||||
currentETag = currentText.toString().trim();
|
||||
currentMD5 = HttpUtils.fromHexString(currentETag.replaceAll("\"", ""));
|
||||
} else if (qName.equals("Size")) {
|
||||
currentObjectMetadata.setSize(Long.parseLong(currentText.toString()));
|
||||
currentSize = new Long(currentText.toString().trim());
|
||||
} else if (qName.equals("Owner")) {
|
||||
currentObjectMetadata.setOwner(currentOwner);
|
||||
} else if (qName.equals("StorageClass")) {
|
||||
currentObjectMetadata.setStorageClass(currentText.toString());
|
||||
currentStorageClass = ObjectMetadata.StorageClass.valueOf(currentText.toString().trim());
|
||||
} else if (qName.equals("Contents")) {
|
||||
contents.add(currentObjectMetadata);
|
||||
contents.add(new BucketListObjectMetadata(currentKey, currentLastModified, currentETag,
|
||||
currentMD5, currentSize, currentOwner, currentStorageClass));
|
||||
} else if (qName.equals("Name")) {
|
||||
this.bucketName = currentText.toString();
|
||||
this.bucketName = currentText.toString().trim();
|
||||
} else if (qName.equals("Prefix")) {
|
||||
String prefix = currentText.toString().trim();
|
||||
if (inCommonPrefixes)
|
||||
|
@ -117,11 +124,11 @@ public class ListBucketHandler extends ParseSax.HandlerWithResult<ListBucketResp
|
|||
this.delimiter = currentText.toString().trim();
|
||||
} else if (qName.equals("Marker")) {
|
||||
if (!currentText.toString().equals(""))
|
||||
this.marker = currentText.toString();
|
||||
this.marker = currentText.toString().trim();
|
||||
} else if (qName.equals("MaxKeys")) {
|
||||
this.maxResults = Integer.parseInt(currentText.toString());
|
||||
this.maxResults = Integer.parseInt(currentText.toString().trim());
|
||||
} else if (qName.equals("IsTruncated")) {
|
||||
this.isTruncated = Boolean.parseBoolean(currentText.toString());
|
||||
this.isTruncated = Boolean.parseBoolean(currentText.toString().trim());
|
||||
}
|
||||
currentText = new StringBuilder();
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
|
@ -23,8 +23,8 @@
|
|||
*/
|
||||
package org.jclouds.aws.s3;
|
||||
|
||||
import static org.jclouds.aws.s3.internal.StubS3Connection.TEST_ACL_EMAIL;
|
||||
import static org.jclouds.aws.s3.internal.StubS3Connection.TEST_ACL_ID;
|
||||
import static org.jclouds.aws.s3.internal.StubS3Client.TEST_ACL_EMAIL;
|
||||
import static org.jclouds.aws.s3.internal.StubS3Client.TEST_ACL_ID;
|
||||
import static org.jclouds.aws.s3.options.CopyObjectOptions.Builder.ifSourceETagDoesntMatch;
|
||||
import static org.jclouds.aws.s3.options.CopyObjectOptions.Builder.ifSourceETagMatches;
|
||||
import static org.jclouds.aws.s3.options.CopyObjectOptions.Builder.ifSourceModifiedSince;
|
||||
|
@ -43,6 +43,7 @@ import static org.testng.Assert.assertFalse;
|
|||
import static org.testng.Assert.assertTrue;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URL;
|
||||
import java.util.Map;
|
||||
|
@ -76,9 +77,8 @@ import com.google.common.collect.Maps;
|
|||
* @author James Murty
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = { "integration", "live" }, testName = "s3.S3ConnectionLiveTest")
|
||||
public class S3ConnectionLiveTest extends
|
||||
BaseBlobStoreIntegrationTest<S3Connection, BucketMetadata, ObjectMetadata, S3Object> {
|
||||
@Test(groups = { "integration", "live" }, testName = "s3.S3ClientLiveTest")
|
||||
public class S3ClientLiveTest extends BaseBlobStoreIntegrationTest<S3Client> {
|
||||
|
||||
/**
|
||||
* this method overrides containerName to ensure it isn't found
|
||||
|
@ -103,8 +103,10 @@ public class S3ConnectionLiveTest extends
|
|||
String containerName = getContainerName();
|
||||
try {
|
||||
String key = "hello";
|
||||
|
||||
context.getApi().putObject(containerName, new S3Object(key, TEST_STRING),
|
||||
S3Object object = context.getApi().newS3Object();
|
||||
object.getMetadata().setKey(key);
|
||||
object.setData(TEST_STRING);
|
||||
context.getApi().putObject(containerName, object,
|
||||
|
||||
withAcl(CannedAccessPolicy.PUBLIC_READ)).get(10, TimeUnit.SECONDS);
|
||||
|
||||
|
@ -147,12 +149,15 @@ public class S3ConnectionLiveTest extends
|
|||
final String publicReadWriteObjectKey = "public-read-write-acl";
|
||||
final String containerName = getContainerName();
|
||||
try {
|
||||
S3Object object = context.getApi().newS3Object();
|
||||
object.getMetadata().setKey(publicReadWriteObjectKey);
|
||||
object.setData("");
|
||||
// Public Read-Write object
|
||||
context.getApi().putObject(containerName, new S3Object(publicReadWriteObjectKey, ""),
|
||||
context.getApi().putObject(containerName, object,
|
||||
new PutObjectOptions().withAcl(CannedAccessPolicy.PUBLIC_READ_WRITE)).get(10,
|
||||
TimeUnit.SECONDS);
|
||||
|
||||
assertEventually(new Runnable() {
|
||||
assertConsistencyAware(new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
AccessControlList acl = context.getApi().getObjectACL(containerName,
|
||||
|
@ -252,11 +257,14 @@ public class S3ConnectionLiveTest extends
|
|||
final String publicReadObjectKey = "public-read-acl";
|
||||
final String containerName = getContainerName();
|
||||
try {
|
||||
context.getApi().putObject(containerName, new S3Object(publicReadObjectKey, ""),
|
||||
S3Object object = context.getApi().newS3Object();
|
||||
object.getMetadata().setKey(publicReadObjectKey);
|
||||
object.setData("");
|
||||
context.getApi().putObject(containerName, object,
|
||||
new PutObjectOptions().withAcl(CannedAccessPolicy.PUBLIC_READ)).get(10,
|
||||
TimeUnit.SECONDS);
|
||||
|
||||
assertEventually(new Runnable() {
|
||||
assertConsistencyAware(new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
AccessControlList acl = context.getApi().getObjectACL(containerName,
|
||||
|
@ -280,17 +288,38 @@ public class S3ConnectionLiveTest extends
|
|||
|
||||
}
|
||||
|
||||
protected String addBlobToContainer(String sourceContainer, String key)
|
||||
throws InterruptedException, ExecutionException, TimeoutException, IOException {
|
||||
S3Object sourceObject = context.getApi().newS3Object();
|
||||
sourceObject.getMetadata().setKey(key);
|
||||
sourceObject.getMetadata().setContentType("text/xml");
|
||||
sourceObject.setData(TEST_STRING);
|
||||
return context.getApi().putObject(sourceContainer, sourceObject).get(10, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
protected S3Object validateObject(String sourceContainer, String key)
|
||||
throws InterruptedException, ExecutionException, TimeoutException, IOException {
|
||||
assertConsistencyAwareContainerSize(sourceContainer, 1);
|
||||
S3Object newObject = context.getApi().getObject(sourceContainer, key).get(30,
|
||||
TimeUnit.SECONDS);
|
||||
assert newObject != null;
|
||||
assertEquals(Utils.toStringAndClose((InputStream) newObject.getData()), TEST_STRING);
|
||||
return newObject;
|
||||
}
|
||||
|
||||
public void testMetadataWithCacheControlAndContentDisposition() throws Exception {
|
||||
String key = "hello";
|
||||
|
||||
S3Object object = context.newBlob(key);
|
||||
S3Object object = context.getApi().newS3Object();
|
||||
object.getMetadata().setKey(key);
|
||||
object.setData(TEST_STRING);
|
||||
object.getMetadata().setCacheControl("no-cache");
|
||||
object.getMetadata().setContentDisposition("attachment; filename=hello.txt");
|
||||
String containerName = getContainerName();
|
||||
try {
|
||||
addBlobToContainer(containerName, object);
|
||||
S3Object newObject = validateContent(containerName, key);
|
||||
context.getApi().putObject(containerName, object).get(10, TimeUnit.SECONDS);
|
||||
|
||||
S3Object newObject = validateObject(containerName, key);
|
||||
|
||||
assertEquals(newObject.getMetadata().getCacheControl(), "no-cache");
|
||||
assertEquals(newObject.getMetadata().getContentDisposition(),
|
||||
|
@ -304,13 +333,14 @@ public class S3ConnectionLiveTest extends
|
|||
public void testMetadataContentEncoding() throws Exception {
|
||||
String key = "hello";
|
||||
|
||||
S3Object object = context.newBlob(key);
|
||||
S3Object object = context.getApi().newS3Object();
|
||||
object.getMetadata().setKey(key);
|
||||
object.setData(TEST_STRING);
|
||||
object.getMetadata().setContentEncoding("x-compress");
|
||||
String containerName = getContainerName();
|
||||
try {
|
||||
addBlobToContainer(containerName, object);
|
||||
S3Object newObject = validateContent(containerName, key);
|
||||
context.getApi().putObject(containerName, object).get(10, TimeUnit.SECONDS);
|
||||
S3Object newObject = validateObject(containerName, key);
|
||||
|
||||
assertEquals(newObject.getMetadata().getContentEncoding(), "x-compress");
|
||||
} finally {
|
||||
|
@ -478,44 +508,6 @@ public class S3ConnectionLiveTest extends
|
|||
}
|
||||
}
|
||||
|
||||
public void testListContainerDelimiter() throws InterruptedException, ExecutionException,
|
||||
TimeoutException, UnsupportedEncodingException {
|
||||
String containerName = getContainerName();
|
||||
try {
|
||||
String prefix = "apps";
|
||||
addTenObjectsUnderPrefix(containerName, prefix);
|
||||
add15UnderRoot(containerName);
|
||||
ListBucketResponse container = context.getApi().listBucket(containerName, delimiter("/"))
|
||||
.get(10, TimeUnit.SECONDS);
|
||||
assertEquals(container.getDelimiter(), "/");
|
||||
assert !container.isTruncated();
|
||||
assertEquals(container.size(), 15);
|
||||
assertEquals(container.getCommonPrefixes().size(), 1);
|
||||
} finally {
|
||||
returnContainer(containerName);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void testListContainerPrefix() throws InterruptedException, ExecutionException,
|
||||
TimeoutException, UnsupportedEncodingException {
|
||||
String containerName = getContainerName();
|
||||
try {
|
||||
String prefix = "apps";
|
||||
addTenObjectsUnderPrefix(containerName, prefix);
|
||||
add15UnderRoot(containerName);
|
||||
|
||||
ListBucketResponse container = context.getApi().listBucket(containerName,
|
||||
withPrefix("apps/")).get(10, TimeUnit.SECONDS);
|
||||
assert !container.isTruncated();
|
||||
assertEquals(container.size(), 10);
|
||||
assertEquals(container.getPrefix(), "apps/");
|
||||
} finally {
|
||||
returnContainer(containerName);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void testPrivateAclIsDefaultForContainer() throws InterruptedException,
|
||||
ExecutionException, TimeoutException, IOException {
|
||||
String containerName = getContainerName();
|
||||
|
@ -575,36 +567,6 @@ public class S3ConnectionLiveTest extends
|
|||
acl.addPermission(new CanonicalUserGrantee(ownerId), Permission.WRITE_ACP);
|
||||
}
|
||||
|
||||
public void testListContainerMarker() throws InterruptedException, ExecutionException,
|
||||
TimeoutException, UnsupportedEncodingException {
|
||||
String containerName = getContainerName();
|
||||
try {
|
||||
addAlphabetUnderRoot(containerName);
|
||||
ListBucketResponse container = context.getApi()
|
||||
.listBucket(containerName, afterMarker("y")).get(10, TimeUnit.SECONDS);
|
||||
assertEquals(container.getMarker(), "y");
|
||||
assert !container.isTruncated();
|
||||
assertEquals(container.size(), 1);
|
||||
} finally {
|
||||
returnContainer(containerName);
|
||||
}
|
||||
}
|
||||
|
||||
public void testListContainerMaxResults() throws InterruptedException, ExecutionException,
|
||||
TimeoutException, UnsupportedEncodingException {
|
||||
String containerName = getContainerName();
|
||||
try {
|
||||
addAlphabetUnderRoot(containerName);
|
||||
ListBucketResponse container = context.getApi().listBucket(containerName, maxResults(5))
|
||||
.get(10, TimeUnit.SECONDS);
|
||||
assertEquals(container.getMaxResults(), 5);
|
||||
assert container.isTruncated();
|
||||
assertEquals(container.size(), 5);
|
||||
} finally {
|
||||
returnContainer(containerName);
|
||||
}
|
||||
}
|
||||
|
||||
public void testPublicReadAccessPolicy() throws Exception {
|
||||
String containerName = getScratchContainerName();
|
||||
try {
|
||||
|
@ -643,7 +605,7 @@ public class S3ConnectionLiveTest extends
|
|||
context.getApi().putBucketIfNotExists(containerName + "eu",
|
||||
createIn(LocationConstraint.EU).withBucketAcl(CannedAccessPolicy.PUBLIC_READ))
|
||||
.get(30, TimeUnit.SECONDS);
|
||||
assertEventually(new Runnable() {
|
||||
assertConsistencyAware(new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
AccessControlList acl = context.getApi().getBucketACL(containerName + "eu").get(
|
||||
|
@ -667,10 +629,11 @@ public class S3ConnectionLiveTest extends
|
|||
void containerExists() throws Exception {
|
||||
String containerName = getContainerName();
|
||||
try {
|
||||
SortedSet<BucketMetadata> list = context.getApi().listOwnedBuckets();
|
||||
SortedSet<BucketMetadata> list = context.getApi().listOwnedBuckets().get(10,
|
||||
TimeUnit.SECONDS);
|
||||
BucketMetadata firstContainer = list.first();
|
||||
BucketMetadata toMatch = new BucketMetadata(containerName);
|
||||
toMatch.setOwner(firstContainer.getOwner());
|
||||
BucketMetadata toMatch = new BucketMetadata(containerName, new DateTime(), firstContainer
|
||||
.getOwner());
|
||||
assert list.contains(toMatch);
|
||||
} finally {
|
||||
returnContainer(containerName);
|
||||
|
@ -680,16 +643,86 @@ public class S3ConnectionLiveTest extends
|
|||
protected void addAlphabetUnderRoot(String containerName) throws InterruptedException,
|
||||
ExecutionException, TimeoutException {
|
||||
for (char letter = 'a'; letter <= 'z'; letter++) {
|
||||
S3Object blob = context.newBlob(letter + "");
|
||||
S3Object blob = context.getApi().newS3Object();
|
||||
blob.getMetadata().setKey(letter + "");
|
||||
blob.setData(letter + "content");
|
||||
context.getApi().putObject(containerName, blob).get(10, TimeUnit.SECONDS);
|
||||
}
|
||||
}
|
||||
|
||||
public void testListContainerMarker() throws InterruptedException, ExecutionException,
|
||||
TimeoutException, UnsupportedEncodingException {
|
||||
String containerName = getContainerName();
|
||||
try {
|
||||
addAlphabetUnderRoot(containerName);
|
||||
ListBucketResponse container = context.getApi()
|
||||
.listBucket(containerName, afterMarker("y")).get(10, TimeUnit.SECONDS);
|
||||
assertEquals(container.getMarker(), "y");
|
||||
assert !container.isTruncated();
|
||||
assertEquals(container.size(), 1);
|
||||
} finally {
|
||||
returnContainer(containerName);
|
||||
}
|
||||
}
|
||||
|
||||
public void testListContainerDelimiter() throws InterruptedException, ExecutionException,
|
||||
TimeoutException, UnsupportedEncodingException {
|
||||
String containerName = getContainerName();
|
||||
try {
|
||||
String prefix = "apps";
|
||||
addTenObjectsUnderPrefix(containerName, prefix);
|
||||
add15UnderRoot(containerName);
|
||||
ListBucketResponse container = context.getApi().listBucket(containerName, delimiter("/"))
|
||||
.get(10, TimeUnit.SECONDS);
|
||||
assertEquals(container.getDelimiter(), "/");
|
||||
assert !container.isTruncated();
|
||||
assertEquals(container.size(), 15);
|
||||
assertEquals(container.getCommonPrefixes().size(), 1);
|
||||
} finally {
|
||||
returnContainer(containerName);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void testListContainerPrefix() throws InterruptedException, ExecutionException,
|
||||
TimeoutException, UnsupportedEncodingException {
|
||||
String containerName = getContainerName();
|
||||
try {
|
||||
String prefix = "apps";
|
||||
addTenObjectsUnderPrefix(containerName, prefix);
|
||||
add15UnderRoot(containerName);
|
||||
|
||||
ListBucketResponse container = context.getApi().listBucket(containerName,
|
||||
withPrefix("apps/")).get(10, TimeUnit.SECONDS);
|
||||
assert !container.isTruncated();
|
||||
assertEquals(container.size(), 10);
|
||||
assertEquals(container.getPrefix(), "apps/");
|
||||
} finally {
|
||||
returnContainer(containerName);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void testListContainerMaxResults() throws InterruptedException, ExecutionException,
|
||||
TimeoutException, UnsupportedEncodingException {
|
||||
String containerName = getContainerName();
|
||||
try {
|
||||
addAlphabetUnderRoot(containerName);
|
||||
ListBucketResponse container = context.getApi().listBucket(containerName, maxResults(5))
|
||||
.get(10, TimeUnit.SECONDS);
|
||||
assertEquals(container.getMaxKeys(), 5);
|
||||
assert container.isTruncated();
|
||||
assertEquals(container.size(), 5);
|
||||
} finally {
|
||||
returnContainer(containerName);
|
||||
}
|
||||
}
|
||||
|
||||
protected void add15UnderRoot(String containerName) throws InterruptedException,
|
||||
ExecutionException, TimeoutException {
|
||||
for (int i = 0; i < 15; i++) {
|
||||
S3Object blob = context.newBlob(i + "");
|
||||
S3Object blob = context.getApi().newS3Object();
|
||||
blob.getMetadata().setKey(i + "");
|
||||
blob.setData(i + "content");
|
||||
context.getApi().putObject(containerName, blob).get(10, TimeUnit.SECONDS);
|
||||
}
|
||||
|
@ -698,7 +731,8 @@ public class S3ConnectionLiveTest extends
|
|||
protected void addTenObjectsUnderPrefix(String containerName, String prefix)
|
||||
throws InterruptedException, ExecutionException, TimeoutException {
|
||||
for (int i = 0; i < 10; i++) {
|
||||
S3Object blob = context.newBlob(prefix + "/" + i);
|
||||
S3Object blob = context.getApi().newS3Object();
|
||||
blob.getMetadata().setKey(prefix + "/" + i);
|
||||
blob.setData(i + "content");
|
||||
context.getApi().putObject(containerName, blob).get(10, TimeUnit.SECONDS);
|
||||
}
|
|
@ -0,0 +1,382 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
package org.jclouds.aws.s3;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Array;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.URI;
|
||||
|
||||
import org.jclouds.aws.s3.blobstore.functions.BlobToObject;
|
||||
import org.jclouds.aws.s3.config.S3ObjectModule;
|
||||
import org.jclouds.aws.s3.domain.AccessControlList;
|
||||
import org.jclouds.aws.s3.domain.CannedAccessPolicy;
|
||||
import org.jclouds.aws.s3.domain.S3Object;
|
||||
import org.jclouds.aws.s3.filters.RequestAuthorizeSignature;
|
||||
import org.jclouds.aws.s3.functions.ParseObjectFromHeadersAndHttpContent;
|
||||
import org.jclouds.aws.s3.functions.ParseObjectMetadataFromHeaders;
|
||||
import org.jclouds.aws.s3.functions.ReturnTrueIfBucketAlreadyOwnedByYou;
|
||||
import org.jclouds.aws.s3.functions.ReturnTrueOn404FalseIfNotEmpty;
|
||||
import org.jclouds.aws.s3.options.CopyObjectOptions;
|
||||
import org.jclouds.aws.s3.options.ListBucketOptions;
|
||||
import org.jclouds.aws.s3.options.PutBucketOptions;
|
||||
import org.jclouds.aws.s3.options.PutObjectOptions;
|
||||
import org.jclouds.aws.s3.reference.S3Constants;
|
||||
import org.jclouds.aws.s3.xml.AccessControlListHandler;
|
||||
import org.jclouds.aws.s3.xml.CopyObjectHandler;
|
||||
import org.jclouds.aws.s3.xml.ListAllMyBucketsHandler;
|
||||
import org.jclouds.aws.s3.xml.ListBucketHandler;
|
||||
import org.jclouds.blobstore.binders.BindBlobToMultipartFormTest;
|
||||
import org.jclouds.blobstore.config.BlobStoreObjectModule;
|
||||
import org.jclouds.blobstore.functions.ReturnVoidOnNotFoundOr404;
|
||||
import org.jclouds.blobstore.functions.ThrowContainerNotFoundOn404;
|
||||
import org.jclouds.blobstore.functions.ThrowKeyNotFoundOn404;
|
||||
import org.jclouds.blobstore.reference.BlobStoreConstants;
|
||||
import org.jclouds.http.functions.ParseETagHeader;
|
||||
import org.jclouds.http.functions.ParseSax;
|
||||
import org.jclouds.http.functions.ReturnFalseOn404;
|
||||
import org.jclouds.http.functions.ReturnTrueIf2xx;
|
||||
import org.jclouds.http.functions.ReturnVoidIf2xx;
|
||||
import org.jclouds.http.options.GetOptions;
|
||||
import org.jclouds.logging.Logger;
|
||||
import org.jclouds.logging.Logger.LoggerFactory;
|
||||
import org.jclouds.rest.RestClientTest;
|
||||
import org.jclouds.rest.internal.GeneratedHttpRequest;
|
||||
import org.jclouds.rest.internal.RestAnnotationProcessor;
|
||||
import org.jclouds.util.Jsr330;
|
||||
import org.jclouds.util.TimeStamp;
|
||||
import org.testng.annotations.BeforeClass;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Module;
|
||||
import com.google.inject.TypeLiteral;
|
||||
|
||||
/**
|
||||
* Tests behavior of {@code S3Client}
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "unit", testName = "s3.S3ClientTest")
|
||||
public class S3ClientTest extends RestClientTest<S3Client> {
|
||||
|
||||
public void testListBucket() throws SecurityException, NoSuchMethodException, IOException {
|
||||
Method method = S3Client.class.getMethod("listBucket", String.class, Array.newInstance(
|
||||
ListBucketOptions.class, 0).getClass());
|
||||
GeneratedHttpRequest<S3Client> httpMethod = processor.createRequest(method, "bucket");
|
||||
|
||||
assertRequestLineEquals(httpMethod, "GET http://bucket.stub:8080/ HTTP/1.1");
|
||||
assertHeadersEqual(httpMethod, "Host: bucket.stub\n");
|
||||
assertEntityEquals(httpMethod, null);
|
||||
|
||||
assertResponseParserClassEquals(method, httpMethod, ParseSax.class);
|
||||
assertSaxResponseParserClassEquals(method, ListBucketHandler.class);
|
||||
assertExceptionParserClassEquals(method, null);
|
||||
|
||||
checkFilters(httpMethod);
|
||||
}
|
||||
|
||||
public void testBucketExists() throws SecurityException, NoSuchMethodException, IOException {
|
||||
Method method = S3Client.class.getMethod("bucketExists", String.class);
|
||||
GeneratedHttpRequest<S3Client> httpMethod = processor.createRequest(method, "bucket");
|
||||
|
||||
assertRequestLineEquals(httpMethod, "HEAD http://bucket.stub:8080/?max-keys=0 HTTP/1.1");
|
||||
assertHeadersEqual(httpMethod, "Host: bucket.stub\n");
|
||||
assertEntityEquals(httpMethod, null);
|
||||
|
||||
assertResponseParserClassEquals(method, httpMethod, ReturnTrueIf2xx.class);
|
||||
assertSaxResponseParserClassEquals(method, null);
|
||||
assertExceptionParserClassEquals(method, ReturnFalseOn404.class);
|
||||
|
||||
checkFilters(httpMethod);
|
||||
}
|
||||
|
||||
public void testCopyObject() throws ArrayIndexOutOfBoundsException, SecurityException,
|
||||
IllegalArgumentException, NoSuchMethodException, IOException {
|
||||
Method method = S3Client.class
|
||||
.getMethod("copyObject", String.class, String.class, String.class, String.class,
|
||||
Array.newInstance(CopyObjectOptions.class, 0).getClass());
|
||||
GeneratedHttpRequest<S3Client> httpMethod = processor.createRequest(method,
|
||||
"sourceBucket", "sourceObject", "destinationBucket", "destinationObject");
|
||||
|
||||
assertRequestLineEquals(httpMethod,
|
||||
"PUT http://destinationBucket.stub:8080/destinationObject HTTP/1.1");
|
||||
assertHeadersEqual(httpMethod,
|
||||
"Content-Length: 0\nHost: destinationBucket.stub\nx-amz-copy-source: /sourceBucket/sourceObject\n");
|
||||
assertEntityEquals(httpMethod, null);
|
||||
|
||||
assertResponseParserClassEquals(method, httpMethod, ParseSax.class);
|
||||
assertSaxResponseParserClassEquals(method, CopyObjectHandler.class);
|
||||
assertExceptionParserClassEquals(method, null);
|
||||
|
||||
checkFilters(httpMethod);
|
||||
}
|
||||
|
||||
public void testDeleteBucketIfEmpty() throws SecurityException, NoSuchMethodException,
|
||||
IOException {
|
||||
Method method = S3Client.class.getMethod("deleteBucketIfEmpty", String.class);
|
||||
GeneratedHttpRequest<S3Client> httpMethod = processor.createRequest(method, "bucket");
|
||||
|
||||
assertRequestLineEquals(httpMethod, "DELETE http://bucket.stub:8080/ HTTP/1.1");
|
||||
assertHeadersEqual(httpMethod, "Host: bucket.stub\n");
|
||||
assertEntityEquals(httpMethod, null);
|
||||
|
||||
assertResponseParserClassEquals(method, httpMethod, ReturnTrueIf2xx.class);
|
||||
assertSaxResponseParserClassEquals(method, null);
|
||||
assertExceptionParserClassEquals(method, ReturnTrueOn404FalseIfNotEmpty.class);
|
||||
|
||||
checkFilters(httpMethod);
|
||||
}
|
||||
|
||||
public void testDeleteObject() throws SecurityException, NoSuchMethodException, IOException {
|
||||
Method method = S3Client.class.getMethod("deleteObject", String.class, String.class);
|
||||
GeneratedHttpRequest<S3Client> httpMethod = processor.createRequest(method, "bucket",
|
||||
"object");
|
||||
|
||||
assertRequestLineEquals(httpMethod, "DELETE http://bucket.stub:8080/object HTTP/1.1");
|
||||
assertHeadersEqual(httpMethod, "Host: bucket.stub\n");
|
||||
assertEntityEquals(httpMethod, null);
|
||||
|
||||
assertResponseParserClassEquals(method, httpMethod, ReturnVoidIf2xx.class);
|
||||
assertSaxResponseParserClassEquals(method, null);
|
||||
assertExceptionParserClassEquals(method, ReturnVoidOnNotFoundOr404.class);
|
||||
|
||||
checkFilters(httpMethod);
|
||||
}
|
||||
|
||||
public void testGetBucketACL() throws SecurityException, NoSuchMethodException, IOException {
|
||||
|
||||
Method method = S3Client.class.getMethod("getBucketACL", String.class);
|
||||
GeneratedHttpRequest<S3Client> httpMethod = processor.createRequest(method, "bucket");
|
||||
|
||||
assertRequestLineEquals(httpMethod, "GET http://bucket.stub:8080/?acl HTTP/1.1");
|
||||
assertHeadersEqual(httpMethod, "Host: bucket.stub\n");
|
||||
assertEntityEquals(httpMethod, null);
|
||||
|
||||
assertResponseParserClassEquals(method, httpMethod, ParseSax.class);
|
||||
assertSaxResponseParserClassEquals(method, AccessControlListHandler.class);
|
||||
assertExceptionParserClassEquals(method, ThrowContainerNotFoundOn404.class);
|
||||
|
||||
checkFilters(httpMethod);
|
||||
}
|
||||
|
||||
public void testGetObject() throws ArrayIndexOutOfBoundsException, SecurityException,
|
||||
IllegalArgumentException, NoSuchMethodException, IOException {
|
||||
Method method = S3Client.class.getMethod("getObject", String.class, String.class, Array
|
||||
.newInstance(GetOptions.class, 0).getClass());
|
||||
GeneratedHttpRequest<S3Client> httpMethod = processor.createRequest(method, "bucket",
|
||||
"object");
|
||||
|
||||
assertRequestLineEquals(httpMethod, "GET http://bucket.stub:8080/object HTTP/1.1");
|
||||
assertHeadersEqual(httpMethod, "Host: bucket.stub\n");
|
||||
assertEntityEquals(httpMethod, null);
|
||||
|
||||
assertResponseParserClassEquals(method, httpMethod,
|
||||
ParseObjectFromHeadersAndHttpContent.class);
|
||||
assertSaxResponseParserClassEquals(method, null);
|
||||
assertExceptionParserClassEquals(method, ThrowKeyNotFoundOn404.class);
|
||||
|
||||
checkFilters(httpMethod);
|
||||
}
|
||||
|
||||
public void testGetObjectACL() throws SecurityException, NoSuchMethodException, IOException {
|
||||
|
||||
Method method = S3Client.class.getMethod("getObjectACL", String.class, String.class);
|
||||
GeneratedHttpRequest<S3Client> httpMethod = processor.createRequest(method, "bucket",
|
||||
"object");
|
||||
|
||||
assertRequestLineEquals(httpMethod, "GET http://bucket.stub:8080/object?acl HTTP/1.1");
|
||||
assertHeadersEqual(httpMethod, "Host: bucket.stub\n");
|
||||
assertEntityEquals(httpMethod, null);
|
||||
|
||||
assertResponseParserClassEquals(method, httpMethod, ParseSax.class);
|
||||
assertSaxResponseParserClassEquals(method, AccessControlListHandler.class);
|
||||
assertExceptionParserClassEquals(method, ThrowKeyNotFoundOn404.class);
|
||||
|
||||
checkFilters(httpMethod);
|
||||
}
|
||||
|
||||
public void testHeadObject() throws SecurityException, NoSuchMethodException, IOException {
|
||||
|
||||
Method method = S3Client.class.getMethod("headObject", String.class, String.class);
|
||||
GeneratedHttpRequest<S3Client> httpMethod = processor.createRequest(method, "bucket",
|
||||
"object");
|
||||
|
||||
assertRequestLineEquals(httpMethod, "HEAD http://bucket.stub:8080/object HTTP/1.1");
|
||||
assertHeadersEqual(httpMethod, "Host: bucket.stub\n");
|
||||
assertEntityEquals(httpMethod, null);
|
||||
|
||||
assertResponseParserClassEquals(method, httpMethod, ParseObjectMetadataFromHeaders.class);
|
||||
assertSaxResponseParserClassEquals(method, null);
|
||||
assertExceptionParserClassEquals(method, ThrowKeyNotFoundOn404.class);
|
||||
|
||||
checkFilters(httpMethod);
|
||||
}
|
||||
|
||||
public void testListOwnedBuckets() throws SecurityException, NoSuchMethodException, IOException {
|
||||
Method method = S3Client.class.getMethod("listOwnedBuckets");
|
||||
GeneratedHttpRequest<S3Client> httpMethod = processor.createRequest(method);
|
||||
|
||||
assertRequestLineEquals(httpMethod, "GET http://stub:8080/ HTTP/1.1");
|
||||
assertHeadersEqual(httpMethod, "Host: stub\n");
|
||||
assertEntityEquals(httpMethod, null);
|
||||
|
||||
assertResponseParserClassEquals(method, httpMethod, ParseSax.class);
|
||||
assertSaxResponseParserClassEquals(method, ListAllMyBucketsHandler.class);
|
||||
assertExceptionParserClassEquals(method, null);
|
||||
|
||||
checkFilters(httpMethod);
|
||||
}
|
||||
|
||||
public void testNewS3Object() throws SecurityException, NoSuchMethodException, IOException {
|
||||
Method method = S3Client.class.getMethod("newS3Object");
|
||||
assertEquals(method.getReturnType(), S3Object.class);
|
||||
}
|
||||
|
||||
public void testPutBucketACL() throws SecurityException, NoSuchMethodException, IOException {
|
||||
Method method = S3Client.class.getMethod("putBucketACL", String.class,
|
||||
AccessControlList.class);
|
||||
GeneratedHttpRequest<S3Client> httpMethod = processor.createRequest(method, "bucket",
|
||||
AccessControlList.fromCannedAccessPolicy(CannedAccessPolicy.PRIVATE, "1234"));
|
||||
|
||||
assertRequestLineEquals(httpMethod, "PUT http://bucket.stub:8080/?acl HTTP/1.1");
|
||||
assertHeadersEqual(httpMethod,
|
||||
"Content-Length: 321\nContent-Type: text/xml\nHost: bucket.stub\n");
|
||||
assertEntityEquals(
|
||||
httpMethod,
|
||||
"<AccessControlPolicy xmlns=\"http://s3.amazonaws.com/doc/2006-03-01/\"><Owner><ID>1234</ID></Owner><AccessControlList><Grant><Grantee xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:type=\"CanonicalUser\"><ID>1234</ID></Grantee><Permission>FULL_CONTROL</Permission></Grant></AccessControlList></AccessControlPolicy>");
|
||||
|
||||
assertResponseParserClassEquals(method, httpMethod, ReturnTrueIf2xx.class);
|
||||
assertSaxResponseParserClassEquals(method, null);
|
||||
assertExceptionParserClassEquals(method, null);
|
||||
|
||||
checkFilters(httpMethod);
|
||||
}
|
||||
|
||||
public void testPutBucketIfNotExists() throws ArrayIndexOutOfBoundsException, SecurityException,
|
||||
IllegalArgumentException, NoSuchMethodException, IOException {
|
||||
Method method = S3Client.class.getMethod("putBucketIfNotExists", String.class, Array
|
||||
.newInstance(PutBucketOptions.class, 0).getClass());
|
||||
GeneratedHttpRequest<S3Client> httpMethod = processor.createRequest(method, "bucket");
|
||||
|
||||
assertRequestLineEquals(httpMethod, "PUT http://bucket.stub:8080/ HTTP/1.1");
|
||||
assertHeadersEqual(httpMethod, "Content-Length: 0\nHost: bucket.stub\n");
|
||||
assertEntityEquals(httpMethod, null);
|
||||
|
||||
assertResponseParserClassEquals(method, httpMethod, ReturnTrueIf2xx.class);
|
||||
assertSaxResponseParserClassEquals(method, null);
|
||||
assertExceptionParserClassEquals(method, ReturnTrueIfBucketAlreadyOwnedByYou.class);
|
||||
|
||||
checkFilters(httpMethod);
|
||||
}
|
||||
|
||||
public void testPutObject() throws ArrayIndexOutOfBoundsException, SecurityException,
|
||||
IllegalArgumentException, NoSuchMethodException, IOException {
|
||||
|
||||
Method method = S3Client.class.getMethod("putObject", String.class, S3Object.class, Array
|
||||
.newInstance(PutObjectOptions.class, 0).getClass());
|
||||
GeneratedHttpRequest<S3Client> httpMethod = processor.createRequest(method, "bucket",
|
||||
blobToS3Object.apply(BindBlobToMultipartFormTest.TEST_BLOB));
|
||||
|
||||
assertRequestLineEquals(httpMethod, "PUT http://bucket.stub:8080/hello HTTP/1.1");
|
||||
assertHeadersEqual(httpMethod,
|
||||
"Content-Length: 5\nContent-Type: text/plain\nHost: bucket.stub\n");
|
||||
assertEntityEquals(httpMethod, "hello");
|
||||
|
||||
assertResponseParserClassEquals(method, httpMethod, ParseETagHeader.class);
|
||||
assertSaxResponseParserClassEquals(method, null);
|
||||
assertExceptionParserClassEquals(method, null);
|
||||
|
||||
checkFilters(httpMethod);
|
||||
}
|
||||
|
||||
public void testPutObjectACL() throws SecurityException, NoSuchMethodException, IOException {
|
||||
Method method = S3Client.class.getMethod("putObjectACL", String.class, String.class,
|
||||
AccessControlList.class);
|
||||
GeneratedHttpRequest<S3Client> httpMethod = processor.createRequest(method, "bucket",
|
||||
"key", AccessControlList.fromCannedAccessPolicy(CannedAccessPolicy.PRIVATE, "1234"));
|
||||
|
||||
assertRequestLineEquals(httpMethod, "PUT http://bucket.stub:8080/key?acl HTTP/1.1");
|
||||
assertHeadersEqual(httpMethod,
|
||||
"Content-Length: 321\nContent-Type: text/xml\nHost: bucket.stub\n");
|
||||
assertEntityEquals(
|
||||
httpMethod,
|
||||
"<AccessControlPolicy xmlns=\"http://s3.amazonaws.com/doc/2006-03-01/\"><Owner><ID>1234</ID></Owner><AccessControlList><Grant><Grantee xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:type=\"CanonicalUser\"><ID>1234</ID></Grantee><Permission>FULL_CONTROL</Permission></Grant></AccessControlList></AccessControlPolicy>");
|
||||
|
||||
assertResponseParserClassEquals(method, httpMethod, ReturnTrueIf2xx.class);
|
||||
assertSaxResponseParserClassEquals(method, null);
|
||||
assertExceptionParserClassEquals(method, null);
|
||||
|
||||
checkFilters(httpMethod);
|
||||
}
|
||||
|
||||
BlobToObject blobToS3Object;
|
||||
|
||||
@Override
|
||||
protected void checkFilters(GeneratedHttpRequest<S3Client> httpMethod) {
|
||||
assertEquals(httpMethod.getFilters().size(), 1);
|
||||
assertEquals(httpMethod.getFilters().get(0).getClass(), RequestAuthorizeSignature.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected TypeLiteral<RestAnnotationProcessor<S3Client>> createTypeLiteral() {
|
||||
return new TypeLiteral<RestAnnotationProcessor<S3Client>>() {
|
||||
};
|
||||
}
|
||||
|
||||
@BeforeClass
|
||||
@Override
|
||||
protected void setupFactory() {
|
||||
super.setupFactory();
|
||||
blobToS3Object = injector.getInstance(BlobToObject.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Module createModule() {
|
||||
return new AbstractModule() {
|
||||
@Override
|
||||
protected void configure() {
|
||||
install(new BlobStoreObjectModule());
|
||||
install(new S3ObjectModule());
|
||||
bind(URI.class).annotatedWith(S3.class).toInstance(URI.create("http://stub:8080"));
|
||||
bindConstant().annotatedWith(Jsr330.named(S3Constants.PROPERTY_AWS_ACCESSKEYID)).to(
|
||||
"user");
|
||||
bindConstant().annotatedWith(Jsr330.named(S3Constants.PROPERTY_AWS_SECRETACCESSKEY))
|
||||
.to("key");
|
||||
bindConstant().annotatedWith(
|
||||
Jsr330.named(BlobStoreConstants.PROPERTY_USER_METADATA_PREFIX)).to("prefix");
|
||||
bindConstant().annotatedWith(TimeStamp.class).to("timestamp");
|
||||
bind(Logger.LoggerFactory.class).toInstance(new LoggerFactory() {
|
||||
public Logger getLogger(String category) {
|
||||
return Logger.NULL;
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
|
@ -25,23 +25,28 @@ package org.jclouds.aws.s3;
|
|||
|
||||
import static org.jclouds.aws.reference.AWSConstants.PROPERTY_AWS_ACCESSKEYID;
|
||||
import static org.jclouds.aws.reference.AWSConstants.PROPERTY_AWS_SECRETACCESSKEY;
|
||||
import static org.jclouds.blobstore.reference.BlobStoreConstants.PROPERTY_USER_METADATA_PREFIX;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.jclouds.aws.s3.config.RestS3ConnectionModule;
|
||||
import org.jclouds.aws.s3.config.S3ContextModule;
|
||||
import org.jclouds.aws.s3.config.StubS3BlobStoreModule;
|
||||
import org.jclouds.aws.s3.config.S3ContextModule.S3ContextImpl;
|
||||
import org.jclouds.aws.s3.internal.StubS3Connection;
|
||||
import org.jclouds.blobstore.integration.internal.StubBlobStore;
|
||||
import org.jclouds.aws.s3.config.S3RestClientModule;
|
||||
import org.jclouds.aws.s3.config.S3StubClientModule;
|
||||
import org.jclouds.aws.s3.domain.S3Object;
|
||||
import org.jclouds.aws.s3.domain.internal.S3ObjectImpl;
|
||||
import org.jclouds.aws.s3.internal.StubS3Client;
|
||||
import org.jclouds.aws.s3.reference.S3Constants;
|
||||
import org.jclouds.blobstore.domain.Blob;
|
||||
import org.jclouds.rest.RestContext;
|
||||
import org.jclouds.rest.internal.RestContextImpl;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.inject.Injector;
|
||||
import com.google.inject.Key;
|
||||
import com.google.inject.Module;
|
||||
import com.google.inject.TypeLiteral;
|
||||
|
||||
/**
|
||||
* Tests behavior of modules configured in S3ContextBuilder
|
||||
|
@ -52,43 +57,49 @@ import com.google.inject.Module;
|
|||
public class S3ContextBuilderTest {
|
||||
|
||||
public void testNewBuilder() {
|
||||
S3ContextBuilder builder = new S3ContextBuilder("id", "secret");
|
||||
assertEquals(builder.getProperties().getProperty(PROPERTY_USER_METADATA_PREFIX),
|
||||
S3ContextBuilder builder = new S3ContextBuilder(new S3PropertiesBuilder("id", "secret")
|
||||
.build());
|
||||
assertEquals(builder.getProperties().getProperty(S3Constants.PROPERTY_S3_METADATA_PREFIX),
|
||||
"x-amz-meta-");
|
||||
assertEquals(builder.getProperties().getProperty(PROPERTY_AWS_ACCESSKEYID), "id");
|
||||
assertEquals(builder.getProperties().getProperty(PROPERTY_AWS_SECRETACCESSKEY), "secret");
|
||||
}
|
||||
|
||||
public void testBuildContext() {
|
||||
S3Context context = new S3ContextBuilder("id", "secret").withModules(
|
||||
new StubS3BlobStoreModule()).buildContext();
|
||||
assertEquals(context.getClass(), S3ContextImpl.class);
|
||||
assertEquals(context.getApi().getClass(), StubS3Connection.class);
|
||||
assertEquals(context.getBlobStore().getClass(), StubBlobStore.class);
|
||||
RestContext<S3Client> context = new S3ContextBuilder(new S3PropertiesBuilder("id", "secret")
|
||||
.build()).withModules(new S3StubClientModule()).buildContext();
|
||||
assertEquals(context.getClass(), RestContextImpl.class);
|
||||
assertEquals(context.getApi().getClass(), StubS3Client.class);
|
||||
assertEquals(context.getApi().newS3Object().getClass(), S3ObjectImpl.class);
|
||||
assertEquals(context.getAccount(), "id");
|
||||
assertEquals(context.getEndPoint(), URI.create("https://localhost/s3stub"));
|
||||
}
|
||||
|
||||
public void testBuildInjector() {
|
||||
Injector i = new S3ContextBuilder("id", "secret").withModules(new StubS3BlobStoreModule())
|
||||
.buildInjector();
|
||||
assert i.getInstance(S3Context.class) != null;
|
||||
Injector i = new S3ContextBuilder(new S3PropertiesBuilder("id", "secret").build())
|
||||
.withModules(new S3StubClientModule()).buildInjector();
|
||||
assert i.getInstance(Key.get(new TypeLiteral<RestContext<S3Client>>() {
|
||||
})) != null;
|
||||
assert i.getInstance(S3Object.class) != null;
|
||||
assert i.getInstance(Blob.class) != null;
|
||||
}
|
||||
|
||||
protected void testAddContextModule() {
|
||||
List<Module> modules = new ArrayList<Module>();
|
||||
S3ContextBuilder builder = new S3ContextBuilder("id", "secret");
|
||||
S3ContextBuilder builder = new S3ContextBuilder(new S3PropertiesBuilder("id", "secret")
|
||||
.build());
|
||||
builder.addContextModule(modules);
|
||||
assertEquals(modules.size(), 1);
|
||||
assertEquals(modules.get(0).getClass(), S3ContextModule.class);
|
||||
}
|
||||
|
||||
protected void addConnectionModule() {
|
||||
protected void addClientModule() {
|
||||
List<Module> modules = new ArrayList<Module>();
|
||||
S3ContextBuilder builder = new S3ContextBuilder("id", "secret");
|
||||
builder.addConnectionModule(modules);
|
||||
S3ContextBuilder builder = new S3ContextBuilder(new S3PropertiesBuilder("id", "secret")
|
||||
.build());
|
||||
builder.addClientModule(modules);
|
||||
assertEquals(modules.size(), 1);
|
||||
assertEquals(modules.get(0).getClass(), RestS3ConnectionModule.class);
|
||||
assertEquals(modules.get(0).getClass(), S3RestClientModule.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,110 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
package org.jclouds.aws.s3.blobstore;
|
||||
|
||||
import static org.jclouds.aws.reference.AWSConstants.PROPERTY_AWS_ACCESSKEYID;
|
||||
import static org.jclouds.aws.reference.AWSConstants.PROPERTY_AWS_SECRETACCESSKEY;
|
||||
import static org.jclouds.blobstore.reference.BlobStoreConstants.PROPERTY_USER_METADATA_PREFIX;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.jclouds.aws.s3.S3Client;
|
||||
import org.jclouds.aws.s3.blobstore.config.S3BlobStoreContextModule;
|
||||
import org.jclouds.aws.s3.config.S3RestClientModule;
|
||||
import org.jclouds.aws.s3.config.S3StubClientModule;
|
||||
import org.jclouds.aws.s3.domain.S3Object;
|
||||
import org.jclouds.aws.s3.domain.internal.S3ObjectImpl;
|
||||
import org.jclouds.aws.s3.internal.StubS3Client;
|
||||
import org.jclouds.blobstore.BlobStoreContext;
|
||||
import org.jclouds.blobstore.domain.Blob;
|
||||
import org.jclouds.blobstore.domain.internal.BlobImpl;
|
||||
import org.jclouds.blobstore.internal.BlobStoreContextImpl;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.inject.Injector;
|
||||
import com.google.inject.Key;
|
||||
import com.google.inject.Module;
|
||||
import com.google.inject.TypeLiteral;
|
||||
|
||||
/**
|
||||
* Tests behavior of modules configured in S3ContextBuilder
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "unit", testName = "s3.S3ContextBuilderTest")
|
||||
public class S3BlobStoreContextBuilderTest {
|
||||
|
||||
public void testNewBuilder() {
|
||||
S3BlobStoreContextBuilder builder = new S3BlobStoreContextBuilder(
|
||||
new S3BlobStorePropertiesBuilder("id", "secret").build());
|
||||
assertEquals(builder.getProperties().getProperty(PROPERTY_USER_METADATA_PREFIX),
|
||||
"x-amz-meta-");
|
||||
assertEquals(builder.getProperties().getProperty(PROPERTY_AWS_ACCESSKEYID), "id");
|
||||
assertEquals(builder.getProperties().getProperty(PROPERTY_AWS_SECRETACCESSKEY), "secret");
|
||||
}
|
||||
|
||||
public void testBuildContext() {
|
||||
BlobStoreContext<S3Client> context = new S3BlobStoreContextBuilder(
|
||||
new S3BlobStorePropertiesBuilder("id", "secret").build()).withModules(
|
||||
new S3StubClientModule()).buildContext();
|
||||
assertEquals(context.getClass(), BlobStoreContextImpl.class);
|
||||
assertEquals(context.getApi().getClass(), StubS3Client.class);
|
||||
assertEquals(context.getBlobStore().getClass(), S3BlobStore.class);
|
||||
assertEquals(context.getApi().newS3Object().getClass(), S3ObjectImpl.class);
|
||||
assertEquals(context.getBlobStore().newBlob().getClass(), BlobImpl.class);
|
||||
assertEquals(context.getAccount(), "id");
|
||||
assertEquals(context.getEndPoint(), URI.create("https://localhost/s3stub"));
|
||||
}
|
||||
|
||||
public void testBuildInjector() {
|
||||
Injector i = new S3BlobStoreContextBuilder(new S3BlobStorePropertiesBuilder("id", "secret")
|
||||
.build()).withModules(new S3StubClientModule()).buildInjector();
|
||||
assert i.getInstance(Key.get(new TypeLiteral<BlobStoreContext<S3Client>>() {
|
||||
})) != null;
|
||||
assert i.getInstance(S3Object.class) != null;
|
||||
assert i.getInstance(Blob.class) != null;
|
||||
}
|
||||
|
||||
protected void testAddContextModule() {
|
||||
List<Module> modules = new ArrayList<Module>();
|
||||
S3BlobStoreContextBuilder builder = new S3BlobStoreContextBuilder(
|
||||
new S3BlobStorePropertiesBuilder("id", "secret").build());
|
||||
builder.addContextModule(modules);
|
||||
assertEquals(modules.size(), 1);
|
||||
assertEquals(modules.get(0).getClass(), S3BlobStoreContextModule.class);
|
||||
}
|
||||
|
||||
protected void addClientModule() {
|
||||
List<Module> modules = new ArrayList<Module>();
|
||||
S3BlobStoreContextBuilder builder = new S3BlobStoreContextBuilder(
|
||||
new S3BlobStorePropertiesBuilder("id", "secret").build());
|
||||
builder.addClientModule(modules);
|
||||
assertEquals(modules.size(), 1);
|
||||
assertEquals(modules.get(0).getClass(), S3RestClientModule.class);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
package org.jclouds.aws.s3.blobstore.config;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import org.jclouds.aws.s3.S3Client;
|
||||
import org.jclouds.aws.s3.config.S3StubClientModule;
|
||||
import org.jclouds.aws.s3.reference.S3Constants;
|
||||
import org.jclouds.blobstore.BlobStoreContext;
|
||||
import org.jclouds.blobstore.internal.BlobStoreContextImpl;
|
||||
import org.jclouds.concurrent.WithinThreadExecutorService;
|
||||
import org.jclouds.concurrent.config.ExecutorServiceModule;
|
||||
import org.jclouds.logging.jdk.config.JDKLoggingModule;
|
||||
import org.jclouds.util.Jsr330;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Injector;
|
||||
import com.google.inject.Key;
|
||||
import com.google.inject.TypeLiteral;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "unit", testName = "s3.S3BlobStoreModuleTest")
|
||||
public class S3BlobStoreModuleTest {
|
||||
|
||||
Injector createInjector() {
|
||||
return Guice.createInjector(new ExecutorServiceModule(new WithinThreadExecutorService()),
|
||||
new JDKLoggingModule(), new S3StubClientModule(), new S3BlobStoreContextModule() {
|
||||
@Override
|
||||
protected void configure() {
|
||||
bindConstant().annotatedWith(
|
||||
Jsr330.named(S3Constants.PROPERTY_AWS_ACCESSKEYID)).to("user");
|
||||
bindConstant().annotatedWith(
|
||||
Jsr330.named(S3Constants.PROPERTY_AWS_SECRETACCESSKEY)).to("key");
|
||||
bindConstant().annotatedWith(Jsr330.named(S3Constants.PROPERTY_S3_ENDPOINT))
|
||||
.to("http://localhost");
|
||||
super.configure();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void testContextImpl() {
|
||||
BlobStoreContext<S3Client> context = createInjector().getInstance(
|
||||
Key.get(new TypeLiteral<BlobStoreContext<S3Client>>() {
|
||||
}));
|
||||
assertEquals(context.getClass(), BlobStoreContextImpl.class);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
|
@ -21,12 +21,9 @@
|
|||
* under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
package org.jclouds.aws.s3.integration;
|
||||
package org.jclouds.aws.s3.blobstore.integration;
|
||||
|
||||
import org.jclouds.aws.s3.S3Connection;
|
||||
import org.jclouds.aws.s3.domain.BucketMetadata;
|
||||
import org.jclouds.aws.s3.domain.ObjectMetadata;
|
||||
import org.jclouds.aws.s3.domain.S3Object;
|
||||
import org.jclouds.aws.s3.S3Client;
|
||||
import org.jclouds.blobstore.integration.internal.BaseBlobIntegrationTest;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
|
@ -36,7 +33,6 @@ import org.testng.annotations.Test;
|
|||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = { "integration", "live" }, testName = "s3.S3BlobIntegrationTest")
|
||||
public class S3BlobIntegrationTest extends
|
||||
BaseBlobIntegrationTest<S3Connection, BucketMetadata, ObjectMetadata, S3Object> {
|
||||
public class S3BlobIntegrationTest extends BaseBlobIntegrationTest<S3Client> {
|
||||
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
|
@ -21,12 +21,9 @@
|
|||
* under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
package org.jclouds.aws.s3.integration;
|
||||
package org.jclouds.aws.s3.blobstore.integration;
|
||||
|
||||
import org.jclouds.aws.s3.S3Connection;
|
||||
import org.jclouds.aws.s3.domain.BucketMetadata;
|
||||
import org.jclouds.aws.s3.domain.ObjectMetadata;
|
||||
import org.jclouds.aws.s3.domain.S3Object;
|
||||
import org.jclouds.aws.s3.S3Client;
|
||||
import org.jclouds.blobstore.integration.internal.BaseBlobLiveTest;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
|
@ -36,7 +33,6 @@ import org.testng.annotations.Test;
|
|||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = { "live" }, testName = "s3.S3BlobLiveTest")
|
||||
public class S3BlobLiveTest extends
|
||||
BaseBlobLiveTest<S3Connection, BucketMetadata, ObjectMetadata, S3Object> {
|
||||
public class S3BlobLiveTest extends BaseBlobLiveTest<S3Client> {
|
||||
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
|
@ -21,12 +21,9 @@
|
|||
* under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
package org.jclouds.aws.s3.integration;
|
||||
package org.jclouds.aws.s3.blobstore.integration;
|
||||
|
||||
import org.jclouds.aws.s3.S3Connection;
|
||||
import org.jclouds.aws.s3.domain.BucketMetadata;
|
||||
import org.jclouds.aws.s3.domain.ObjectMetadata;
|
||||
import org.jclouds.aws.s3.domain.S3Object;
|
||||
import org.jclouds.aws.s3.S3Client;
|
||||
import org.jclouds.blobstore.integration.internal.BaseBlobMapIntegrationTest;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
|
@ -34,7 +31,6 @@ import org.testng.annotations.Test;
|
|||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = { "integration", "live" }, testName = "s3.S3BlobMapIntegrationTest")
|
||||
public class S3BlobMapIntegrationTest extends
|
||||
BaseBlobMapIntegrationTest<S3Connection, BucketMetadata, ObjectMetadata, S3Object> {
|
||||
public class S3BlobMapIntegrationTest extends BaseBlobMapIntegrationTest<S3Client> {
|
||||
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
|
@ -21,12 +21,9 @@
|
|||
* under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
package org.jclouds.aws.s3.integration;
|
||||
package org.jclouds.aws.s3.blobstore.integration;
|
||||
|
||||
import org.jclouds.aws.s3.S3Connection;
|
||||
import org.jclouds.aws.s3.domain.BucketMetadata;
|
||||
import org.jclouds.aws.s3.domain.ObjectMetadata;
|
||||
import org.jclouds.aws.s3.domain.S3Object;
|
||||
import org.jclouds.aws.s3.S3Client;
|
||||
import org.jclouds.blobstore.integration.internal.BaseContainerIntegrationTest;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
|
@ -35,7 +32,6 @@ import org.testng.annotations.Test;
|
|||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = { "integration", "live" }, testName = "s3.S3ContainerIntegrationTest")
|
||||
public class S3ContainerIntegrationTest extends
|
||||
BaseContainerIntegrationTest<S3Connection, BucketMetadata, ObjectMetadata, S3Object> {
|
||||
public class S3ContainerIntegrationTest extends BaseContainerIntegrationTest<S3Client> {
|
||||
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
|
@ -21,12 +21,9 @@
|
|||
* under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
package org.jclouds.aws.s3.integration;
|
||||
package org.jclouds.aws.s3.blobstore.integration;
|
||||
|
||||
import org.jclouds.aws.s3.S3Connection;
|
||||
import org.jclouds.aws.s3.domain.BucketMetadata;
|
||||
import org.jclouds.aws.s3.domain.ObjectMetadata;
|
||||
import org.jclouds.aws.s3.domain.S3Object;
|
||||
import org.jclouds.aws.s3.S3Client;
|
||||
import org.jclouds.blobstore.integration.internal.BaseContainerLiveTest;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
|
@ -35,7 +32,6 @@ import org.testng.annotations.Test;
|
|||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = { "live" }, testName = "s3.S3ContainerLiveTest")
|
||||
public class S3ContainerLiveTest extends
|
||||
BaseContainerLiveTest<S3Connection, BucketMetadata, ObjectMetadata, S3Object> {
|
||||
public class S3ContainerLiveTest extends BaseContainerLiveTest<S3Client> {
|
||||
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
|
@ -21,12 +21,9 @@
|
|||
* under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
package org.jclouds.aws.s3.integration;
|
||||
package org.jclouds.aws.s3.blobstore.integration;
|
||||
|
||||
import org.jclouds.aws.s3.S3Connection;
|
||||
import org.jclouds.aws.s3.domain.BucketMetadata;
|
||||
import org.jclouds.aws.s3.domain.ObjectMetadata;
|
||||
import org.jclouds.aws.s3.domain.S3Object;
|
||||
import org.jclouds.aws.s3.S3Client;
|
||||
import org.jclouds.blobstore.integration.internal.BaseInputStreamMapIntegrationTest;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
|
@ -35,6 +32,6 @@ import org.testng.annotations.Test;
|
|||
*/
|
||||
@Test(groups = { "integration", "live" }, testName = "s3.S3InputStreamMapIntegrationTest")
|
||||
public class S3InputStreamMapIntegrationTest extends
|
||||
BaseInputStreamMapIntegrationTest<S3Connection, BucketMetadata, ObjectMetadata, S3Object> {
|
||||
BaseInputStreamMapIntegrationTest<S3Client> {
|
||||
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue