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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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.apache.commons.io.IOUtils;
|
||||||
import org.jclouds.aws.domain.AWSError;
|
import org.jclouds.aws.domain.AWSError;
|
||||||
import org.jclouds.aws.xml.ErrorHandler;
|
|
||||||
import org.jclouds.http.HttpException;
|
import org.jclouds.http.HttpException;
|
||||||
import org.jclouds.http.functions.BaseHandlerTest;
|
import org.jclouds.http.functions.BaseHandlerTest;
|
||||||
import org.jclouds.http.functions.ParseSax;
|
import org.jclouds.http.functions.ParseSax;
|
||||||
|
@ -37,7 +36,6 @@ import org.testng.annotations.Test;
|
||||||
public class ErrorHandlerTest extends BaseHandlerTest {
|
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>";
|
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> createParser() {
|
||||||
ParseSax<AWSError> parser = (ParseSax<AWSError>) factory.create(injector
|
ParseSax<AWSError> parser = (ParseSax<AWSError>) factory.create(injector
|
||||||
.getInstance(ErrorHandler.class));
|
.getInstance(ErrorHandler.class));
|
||||||
|
|
|
@ -1,4 +1,29 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?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>
|
<Error>
|
||||||
<Code>NoSuchKey</Code>
|
<Code>NoSuchKey</Code>
|
||||||
<Message>The resource you requested does not exist</Message>
|
<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
|
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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
@ -23,6 +23,8 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.aws.s3;
|
package org.jclouds.aws.s3;
|
||||||
|
|
||||||
|
import static org.jclouds.blobstore.attr.BlobScopes.CONTAINER;
|
||||||
|
|
||||||
import java.util.SortedSet;
|
import java.util.SortedSet;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.concurrent.Future;
|
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.ObjectMetadata;
|
||||||
import org.jclouds.aws.s3.domain.S3Object;
|
import org.jclouds.aws.s3.domain.S3Object;
|
||||||
import org.jclouds.aws.s3.filters.RequestAuthorizeSignature;
|
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.ParseObjectFromHeadersAndHttpContent;
|
||||||
import org.jclouds.aws.s3.functions.ParseObjectMetadataFromHeaders;
|
import org.jclouds.aws.s3.functions.ParseObjectMetadataFromHeaders;
|
||||||
import org.jclouds.aws.s3.functions.ReturnTrueIfBucketAlreadyOwnedByYou;
|
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.CopyObjectHandler;
|
||||||
import org.jclouds.aws.s3.xml.ListAllMyBucketsHandler;
|
import org.jclouds.aws.s3.xml.ListAllMyBucketsHandler;
|
||||||
import org.jclouds.aws.s3.xml.ListBucketHandler;
|
import org.jclouds.aws.s3.xml.ListBucketHandler;
|
||||||
import org.jclouds.blobstore.domain.Blob;
|
import org.jclouds.blobstore.attr.BlobScope;
|
||||||
import org.jclouds.blobstore.functions.BlobName;
|
|
||||||
import org.jclouds.blobstore.functions.ReturnVoidOnNotFoundOr404;
|
import org.jclouds.blobstore.functions.ReturnVoidOnNotFoundOr404;
|
||||||
import org.jclouds.blobstore.functions.ThrowContainerNotFoundOn404;
|
import org.jclouds.blobstore.functions.ThrowContainerNotFoundOn404;
|
||||||
import org.jclouds.blobstore.functions.ThrowKeyNotFoundOn404;
|
import org.jclouds.blobstore.functions.ThrowKeyNotFoundOn404;
|
||||||
|
@ -89,11 +91,16 @@ import org.jclouds.rest.annotations.XMLResponseParser;
|
||||||
@SkipEncoding('/')
|
@SkipEncoding('/')
|
||||||
@RequestFilters(RequestAuthorizeSignature.class)
|
@RequestFilters(RequestAuthorizeSignature.class)
|
||||||
@Endpoint(S3.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
|
* Creates a default implementation of S3Object
|
||||||
* not available;
|
*/
|
||||||
|
public S3Object newS3Object();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the S3Object associated with the Key or KeyNotFoundException if not available;
|
||||||
*
|
*
|
||||||
* <p/>
|
* <p/>
|
||||||
* To use GET, you must have READ access to the object. If READ access is granted to the
|
* 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);
|
GetOptions... options);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the {@link org.jclouds.aws.s3.domain.ObjectMetadata metadata} of the object
|
* Retrieves the {@link org.jclouds.aws.s3.domain.internal.BucketListObjectMetadata metadata} of
|
||||||
* associated with the key or {@link org.jclouds.aws.s3.domain.ObjectMetadata#NOT_FOUND} if not
|
* the object associated with the key or
|
||||||
|
* {@link org.jclouds.aws.s3.domain.internal.BucketListObjectMetadata#NOT_FOUND} if not
|
||||||
* available.
|
* available.
|
||||||
*
|
*
|
||||||
* <p/>
|
* <p/>
|
||||||
|
@ -144,7 +152,8 @@ public interface S3Connection {
|
||||||
* @param key
|
* @param key
|
||||||
* unique key in the s3Bucket identifying the object
|
* unique key in the s3Bucket identifying the object
|
||||||
* @return metadata associated with the key or
|
* @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 #getObject(String, String)
|
||||||
* @see <a
|
* @see <a
|
||||||
* href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?RESTObjectHEAD.html"
|
* href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?RESTObjectHEAD.html"
|
||||||
|
@ -206,7 +215,7 @@ public interface S3Connection {
|
||||||
@ResponseParser(ParseETagHeader.class)
|
@ResponseParser(ParseETagHeader.class)
|
||||||
Future<String> putObject(
|
Future<String> putObject(
|
||||||
@HostPrefixParam String bucketName,
|
@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);
|
PutObjectOptions... options);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -303,7 +312,7 @@ public interface S3Connection {
|
||||||
@GET
|
@GET
|
||||||
@XMLResponseParser(ListAllMyBucketsHandler.class)
|
@XMLResponseParser(ListAllMyBucketsHandler.class)
|
||||||
@Path("/")
|
@Path("/")
|
||||||
SortedSet<BucketMetadata> listOwnedBuckets();
|
Future<? extends SortedSet<BucketMetadata>> listOwnedBuckets();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copies one object to another bucket, retaining UserMetadata from the source. The destination
|
* 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
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
@ -23,26 +23,15 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.aws.s3;
|
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.List;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
|
|
||||||
import org.jclouds.aws.s3.config.RestS3ConnectionModule;
|
|
||||||
import org.jclouds.aws.s3.config.S3ContextModule;
|
import org.jclouds.aws.s3.config.S3ContextModule;
|
||||||
import org.jclouds.aws.s3.domain.BucketMetadata;
|
import org.jclouds.aws.s3.config.S3RestClientModule;
|
||||||
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.http.config.JavaUrlHttpCommandExecutorServiceModule;
|
import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule;
|
||||||
import org.jclouds.logging.jdk.config.JDKLoggingModule;
|
import org.jclouds.logging.jdk.config.JDKLoggingModule;
|
||||||
|
import org.jclouds.rest.RestContextBuilder;
|
||||||
|
|
||||||
import com.google.inject.Injector;
|
import com.google.inject.Injector;
|
||||||
import com.google.inject.Module;
|
import com.google.inject.Module;
|
||||||
|
@ -61,98 +50,12 @@ import com.google.inject.TypeLiteral;
|
||||||
* @author Adrian Cole, Andrew Newdigate
|
* @author Adrian Cole, Andrew Newdigate
|
||||||
* @see S3Context
|
* @see S3Context
|
||||||
*/
|
*/
|
||||||
public class S3ContextBuilder extends
|
public class S3ContextBuilder extends RestContextBuilder<S3Client> {
|
||||||
BlobStoreContextBuilder<S3Connection, BucketMetadata, ObjectMetadata, S3Object> {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public S3Context buildContext() {
|
|
||||||
return this.buildInjector().getInstance(S3Context.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
public S3ContextBuilder(Properties props) {
|
public S3ContextBuilder(Properties props) {
|
||||||
super(new TypeLiteral<S3Connection>() {
|
super(new TypeLiteral<S3Client>() {
|
||||||
}, new TypeLiteral<BucketMetadata>() {
|
|
||||||
}, new TypeLiteral<ObjectMetadata>() {
|
|
||||||
}, new TypeLiteral<S3Object>() {
|
|
||||||
}, props);
|
}, 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
|
@Override
|
||||||
|
@ -161,12 +64,18 @@ public class S3ContextBuilder extends
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void addConnectionModule(List<Module> modules) {
|
protected void addClientModule(List<Module> modules) {
|
||||||
modules.add(new RestS3ConnectionModule());
|
modules.add(new S3RestClientModule());
|
||||||
}
|
}
|
||||||
|
|
||||||
public S3ContextBuilder withTimeStampExpiration(long seconds) {
|
@Override
|
||||||
getProperties().setProperty(PROPERTY_S3_SESSIONINTERVAL, seconds + "");
|
public S3ContextBuilder withExecutorService(ExecutorService service) {
|
||||||
return this;
|
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
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
@ -24,9 +24,11 @@
|
||||||
package org.jclouds.aws.s3;
|
package org.jclouds.aws.s3;
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule;
|
import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule;
|
||||||
import org.jclouds.logging.jdk.config.JDKLoggingModule;
|
import org.jclouds.logging.jdk.config.JDKLoggingModule;
|
||||||
|
import org.jclouds.rest.RestContext;
|
||||||
|
|
||||||
import com.google.inject.Module;
|
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
|
* If no <code>Module</code>s are specified, the default {@link JDKLoggingModule logging} and
|
||||||
* {@link JavaUrlHttpCommandExecutorServiceModule http transports} will be installed.
|
* {@link JavaUrlHttpCommandExecutorServiceModule http transports} will be installed.
|
||||||
*
|
*
|
||||||
* @author Adrian Cole, Andrew Newdigate
|
* @author Adrian Cole
|
||||||
* @see S3Context
|
* @see S3Client
|
||||||
*/
|
*/
|
||||||
public class S3ContextFactory {
|
public class S3ContextFactory {
|
||||||
|
|
||||||
public static S3Context createContext(
|
public static RestContext<S3Client> createContext(Properties properties, Module... modules) {
|
||||||
String awsAccessKeyId, String awsSecretAccessKey, Module... modules) {
|
return new S3ContextBuilder(new S3PropertiesBuilder(properties).build()).withModules(modules)
|
||||||
return new S3ContextBuilder(awsAccessKeyId, awsSecretAccessKey).withModules(modules)
|
|
||||||
.buildContext();
|
.buildContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static S3Context createContext(
|
public static RestContext<S3Client> createContext(String awsAccessKeyId,
|
||||||
URI endpoint, String awsAccessKeyId, String awsSecretAccessKey, Module... modules) {
|
String awsSecretAccessKey, Module... modules) {
|
||||||
return new S3ContextBuilder(awsAccessKeyId, awsSecretAccessKey).withEndpoint(endpoint)
|
return new S3ContextBuilder(new S3PropertiesBuilder(awsAccessKeyId, awsSecretAccessKey)
|
||||||
.withModules(modules).buildContext();
|
.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
|
* 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
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
@ -24,30 +24,35 @@
|
||||||
package org.jclouds.aws.s3.binders;
|
package org.jclouds.aws.s3.binders;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkArgument;
|
import static com.google.common.base.Preconditions.checkArgument;
|
||||||
import static org.jclouds.blobstore.reference.BlobStoreConstants.PROPERTY_USER_METADATA_PREFIX;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Named;
|
|
||||||
import javax.ws.rs.core.HttpHeaders;
|
import javax.ws.rs.core.HttpHeaders;
|
||||||
|
|
||||||
|
import org.jclouds.aws.s3.blobstore.functions.ObjectToBlob;
|
||||||
import org.jclouds.aws.s3.domain.S3Object;
|
import org.jclouds.aws.s3.domain.S3Object;
|
||||||
import org.jclouds.blobstore.binders.BindBlobToEntityAndUserMetadataToHeadersWithPrefix;
|
import org.jclouds.blobstore.binders.BindBlobToEntityAndUserMetadataToHeadersWithPrefix;
|
||||||
import org.jclouds.blobstore.domain.Blob;
|
|
||||||
import org.jclouds.http.HttpRequest;
|
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
|
@Inject
|
||||||
public BindS3ObjectToEntity(@Named(PROPERTY_USER_METADATA_PREFIX) String metadataPrefix) {
|
public BindS3ObjectToEntity(ObjectToBlob object2Blob,
|
||||||
super(metadataPrefix);
|
BindBlobToEntityAndUserMetadataToHeadersWithPrefix blobBinder) {
|
||||||
|
this.blobBinder = blobBinder;
|
||||||
|
this.object2Blob = object2Blob;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void bindToRequest(HttpRequest request, Object entity) {
|
public void bindToRequest(HttpRequest request, Object entity) {
|
||||||
Blob<?> object = (Blob<?>) entity;
|
S3Object s3Object = (S3Object) entity;
|
||||||
checkArgument(object.getMetadata().getSize() >= 0, "size must be set");
|
checkNotNull(s3Object.getContentLength(), "contentLength");
|
||||||
checkArgument(object.getContentLength() <= 5 * 1024 * 1024 * 1024,
|
checkArgument(s3Object.getContentLength() <= 5 * 1024 * 1024 * 1024,
|
||||||
"maximum size for put object is 5GB");
|
"maximum size for put object is 5GB");
|
||||||
if (object instanceof S3Object) {
|
blobBinder.bindToRequest(request, object2Blob.apply(s3Object));
|
||||||
S3Object s3Object = (S3Object) object;
|
|
||||||
if (s3Object.getMetadata().getCacheControl() != null) {
|
if (s3Object.getMetadata().getCacheControl() != null) {
|
||||||
request.getHeaders().put(HttpHeaders.CACHE_CONTROL,
|
request.getHeaders().put(HttpHeaders.CACHE_CONTROL,
|
||||||
s3Object.getMetadata().getCacheControl());
|
s3Object.getMetadata().getCacheControl());
|
||||||
|
@ -62,7 +67,6 @@ public class BindS3ObjectToEntity extends BindBlobToEntityAndUserMetadataToHeade
|
||||||
request.getHeaders().put(HttpHeaders.CONTENT_ENCODING,
|
request.getHeaders().put(HttpHeaders.CONTENT_ENCODING,
|
||||||
s3Object.getMetadata().getContentEncoding());
|
s3Object.getMetadata().getContentEncoding());
|
||||||
}
|
}
|
||||||
}
|
|
||||||
super.bindToRequest(request, entity);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
@ -21,43 +21,36 @@
|
||||||
* under the License.
|
* under the License.
|
||||||
* ====================================================================
|
* ====================================================================
|
||||||
*/
|
*/
|
||||||
package org.jclouds.mezeo.pcs2.functions;
|
package org.jclouds.aws.s3.blobstore.functions;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
|
||||||
|
|
||||||
import java.util.concurrent.ConcurrentMap;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
import org.jclouds.blobstore.ContainerNotFoundException;
|
import org.jclouds.aws.s3.domain.S3Object;
|
||||||
import org.jclouds.util.Utils;
|
import org.jclouds.blobstore.domain.Blob;
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
import com.google.common.collect.ComputationException;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
@Singleton
|
@Singleton
|
||||||
public class ContainerNameToResourceId implements Function<Object, String> {
|
public class BlobToObject implements Function<Blob, S3Object> {
|
||||||
|
private final BlobToObjectMetadata blob2ObjectMd;
|
||||||
private final ConcurrentMap<String, String> finder;
|
private final S3Object.Factory objectProvider;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public ContainerNameToResourceId(ConcurrentMap<String, String> finder) {
|
BlobToObject(BlobToObjectMetadata blob2ObjectMd, S3Object.Factory objectProvider) {
|
||||||
this.finder = finder;
|
this.blob2ObjectMd = blob2ObjectMd;
|
||||||
|
this.objectProvider = objectProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String apply(Object from) {
|
public S3Object apply(Blob from) {
|
||||||
String toFind = checkNotNull(from, "name").toString();
|
S3Object object = objectProvider.create(blob2ObjectMd.apply(from.getMetadata()));
|
||||||
try {
|
if (from.getContentLength() != null)
|
||||||
return finder.get(toFind);
|
object.setContentLength(from.getContentLength());
|
||||||
} catch (ComputationException e) {
|
object.setData(from.getData());
|
||||||
Utils.<ContainerNotFoundException> rethrowIfRuntimeOrSameType(e);
|
object.setAllHeaders(from.getAllHeaders());
|
||||||
throw e;
|
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
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
@ -21,25 +21,33 @@
|
||||||
* under the License.
|
* under the License.
|
||||||
* ====================================================================
|
* ====================================================================
|
||||||
*/
|
*/
|
||||||
package org.jclouds.rackspace.cloudfiles;
|
package org.jclouds.aws.s3.blobstore.functions;
|
||||||
|
|
||||||
import org.jclouds.blobstore.BlobStoreContext;
|
import javax.inject.Singleton;
|
||||||
import org.jclouds.blobstore.domain.Blob;
|
|
||||||
|
import org.jclouds.aws.s3.domain.MutableObjectMetadata;
|
||||||
|
import org.jclouds.aws.s3.domain.internal.MutableObjectMetadataImpl;
|
||||||
import org.jclouds.blobstore.domain.BlobMetadata;
|
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
|
* @author Adrian Cole
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public interface CloudFilesContext
|
@Singleton
|
||||||
extends
|
public class BlobToObjectMetadata implements Function<BlobMetadata, MutableObjectMetadata> {
|
||||||
BlobStoreContext<CloudFilesConnection, ContainerMetadata, BlobMetadata, Blob<BlobMetadata>> {
|
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
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
@ -21,26 +21,27 @@
|
||||||
* under the License.
|
* 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.BucketMetadata;
|
||||||
import org.jclouds.aws.s3.domain.ObjectMetadata;
|
import org.jclouds.blobstore.domain.MutableResourceMetadata;
|
||||||
import org.jclouds.aws.s3.domain.S3Object;
|
import org.jclouds.blobstore.domain.ResourceMetadata;
|
||||||
import org.jclouds.blobstore.BlobStoreContext;
|
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
|
* @author Adrian Cole
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public interface S3Context extends
|
@Singleton
|
||||||
BlobStoreContext<S3Connection, BucketMetadata, ObjectMetadata, S3Object> {
|
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
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
@ -25,28 +25,22 @@ package org.jclouds.aws.s3.config;
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
|
||||||
import javax.inject.Named;
|
import javax.inject.Named;
|
||||||
import javax.inject.Provider;
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
import org.jclouds.aws.reference.AWSConstants;
|
import org.jclouds.aws.reference.AWSConstants;
|
||||||
import org.jclouds.aws.s3.S3;
|
import org.jclouds.aws.s3.S3;
|
||||||
import org.jclouds.aws.s3.S3BlobStore;
|
import org.jclouds.aws.s3.S3Client;
|
||||||
import org.jclouds.aws.s3.S3Connection;
|
import org.jclouds.blobstore.config.BlobStoreObjectModule;
|
||||||
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.lifecycle.Closer;
|
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.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
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
|
@ -54,23 +48,16 @@ public class S3ContextModule extends AbstractModule {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void configure() {
|
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
|
@Provides
|
||||||
BlobStoreContextImpl<S3Connection, BucketMetadata, ObjectMetadata, S3Object> implements
|
@Singleton
|
||||||
S3Context {
|
RestContext<S3Client> provideContext(Closer closer, S3Client defaultApi, @S3 URI endPoint,
|
||||||
@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) {
|
@Named(AWSConstants.PROPERTY_AWS_ACCESSKEYID) String account) {
|
||||||
super(blobMapFactory, inputStreamMapFactory, closer, blobProvider, blobStore, defaultApi,
|
return new RestContextImpl<S3Client>(closer, defaultApi, endPoint, account);
|
||||||
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
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
@ -31,24 +31,19 @@ import javax.inject.Named;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
import org.jclouds.aws.s3.S3;
|
import org.jclouds.aws.s3.S3;
|
||||||
import org.jclouds.aws.s3.S3BlobStore;
|
import org.jclouds.aws.s3.S3Client;
|
||||||
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.filters.RequestAuthorizeSignature;
|
import org.jclouds.aws.s3.filters.RequestAuthorizeSignature;
|
||||||
import org.jclouds.aws.s3.handlers.AWSClientErrorRetryHandler;
|
import org.jclouds.aws.s3.handlers.AWSClientErrorRetryHandler;
|
||||||
import org.jclouds.aws.s3.handlers.AWSRedirectionRetryHandler;
|
import org.jclouds.aws.s3.handlers.AWSRedirectionRetryHandler;
|
||||||
import org.jclouds.aws.s3.handlers.ParseAWSErrorFromXmlContent;
|
import org.jclouds.aws.s3.handlers.ParseAWSErrorFromXmlContent;
|
||||||
import org.jclouds.aws.s3.reference.S3Constants;
|
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.HttpErrorHandler;
|
||||||
import org.jclouds.http.HttpRetryHandler;
|
import org.jclouds.http.HttpRetryHandler;
|
||||||
import org.jclouds.http.RequiresHttp;
|
import org.jclouds.http.RequiresHttp;
|
||||||
import org.jclouds.http.annotation.ClientError;
|
import org.jclouds.http.annotation.ClientError;
|
||||||
import org.jclouds.http.annotation.Redirection;
|
import org.jclouds.http.annotation.Redirection;
|
||||||
import org.jclouds.http.annotation.ServerError;
|
import org.jclouds.http.annotation.ServerError;
|
||||||
|
import org.jclouds.rest.ConfiguresRestClient;
|
||||||
import org.jclouds.rest.RestClientFactory;
|
import org.jclouds.rest.RestClientFactory;
|
||||||
import org.jclouds.util.DateService;
|
import org.jclouds.util.DateService;
|
||||||
import org.jclouds.util.TimeStamp;
|
import org.jclouds.util.TimeStamp;
|
||||||
|
@ -64,9 +59,9 @@ import com.google.inject.Scopes;
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
@ConfiguresCloudConnection
|
@ConfiguresRestClient
|
||||||
@RequiresHttp
|
@RequiresHttp
|
||||||
public class RestS3ConnectionModule extends AbstractModule {
|
public class S3RestClientModule extends AbstractModule {
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@TimeStamp
|
@TimeStamp
|
||||||
|
@ -106,15 +101,8 @@ public class RestS3ConnectionModule extends AbstractModule {
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
protected BlobStore<BucketMetadata, ObjectMetadata, S3Object> provideS3BlobStore(
|
protected S3Client provideS3Client(RestClientFactory factory) {
|
||||||
RestClientFactory factory) {
|
return factory.create(S3Client.class);
|
||||||
return factory.create(S3BlobStore.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Provides
|
|
||||||
@Singleton
|
|
||||||
protected S3Connection provideS3Connection(RestClientFactory factory) {
|
|
||||||
return factory.create(S3Connection.class);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void bindErrorHandlers() {
|
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
|
* 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
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
package org.jclouds.aws.s3.config;
|
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
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
@ -410,4 +410,35 @@ public class AccessControlList {
|
||||||
sb.append('}');
|
sb.append('}');
|
||||||
return sb.toString();
|
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
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
@ -23,7 +23,6 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.aws.s3.domain;
|
package org.jclouds.aws.s3.domain;
|
||||||
|
|
||||||
import org.jclouds.blobstore.internal.ContainerMetadataImpl;
|
|
||||||
import org.joda.time.DateTime;
|
import org.joda.time.DateTime;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -31,36 +30,41 @@ import org.joda.time.DateTime;
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
public class BucketMetadata extends ContainerMetadataImpl {
|
public class BucketMetadata implements Comparable<BucketMetadata> {
|
||||||
protected DateTime creationDate;
|
/** The serialVersionUID */
|
||||||
|
private static final long serialVersionUID = -6965068835316857535L;
|
||||||
public DateTime getCreationDate() {
|
private final DateTime creationDate;
|
||||||
return creationDate;
|
private final CanonicalUser owner;
|
||||||
}
|
private final String name;
|
||||||
|
|
||||||
public void setCreationDate(DateTime creationDate) {
|
|
||||||
this.creationDate = creationDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Location constraint of the bucket.
|
* Location constraint of the bucket.
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
* @see <a href=
|
* @see <a href= "http://docs.amazonwebservices.com/AmazonS3/latest/RESTBucketLocationGET.html"
|
||||||
* "http://docs.amazonwebservices.com/AmazonS3/latest/RESTBucketLocationGET.html" />
|
* />
|
||||||
*/
|
*/
|
||||||
public static enum LocationConstraint {
|
public static enum LocationConstraint {
|
||||||
EU
|
EU
|
||||||
}
|
}
|
||||||
|
|
||||||
private CanonicalUser canonicalUser;
|
public BucketMetadata(String name, DateTime creationDate, CanonicalUser owner) {
|
||||||
|
this.name = name;
|
||||||
public BucketMetadata(String name) {
|
this.creationDate = creationDate;
|
||||||
super(name);
|
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/>
|
* <p/>
|
||||||
* Not be in an IP address style (e.g., "192.168.5.4")
|
* 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() {
|
public String getName() {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public int compareTo(BucketMetadata o) {
|
||||||
public String toString() {
|
return (this == o) ? 0 : getName().compareTo(o.getName());
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
final int prime = 31;
|
final int prime = 31;
|
||||||
int result = super.hashCode();
|
int result = 1;
|
||||||
result = prime * result + ((canonicalUser == null) ? 0 : canonicalUser.hashCode());
|
result = prime * result + ((name == null) ? 0 : name.hashCode());
|
||||||
|
result = prime * result + ((owner == null) ? 0 : owner.hashCode());
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,17 +99,21 @@ public class BucketMetadata extends ContainerMetadataImpl {
|
||||||
public boolean equals(Object obj) {
|
public boolean equals(Object obj) {
|
||||||
if (this == obj)
|
if (this == obj)
|
||||||
return true;
|
return true;
|
||||||
if (!super.equals(obj))
|
if (obj == null)
|
||||||
return false;
|
return false;
|
||||||
if (getClass() != obj.getClass())
|
if (getClass() != obj.getClass())
|
||||||
return false;
|
return false;
|
||||||
BucketMetadata other = (BucketMetadata) obj;
|
BucketMetadata other = (BucketMetadata) obj;
|
||||||
if (canonicalUser == null) {
|
if (name == null) {
|
||||||
if (other.canonicalUser != null)
|
if (other.name != null)
|
||||||
return false;
|
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 false;
|
||||||
return true;
|
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
|
* 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
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
@ -24,10 +24,9 @@
|
||||||
package org.jclouds.aws.s3.domain;
|
package org.jclouds.aws.s3.domain;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Every bucket and object in Amazon S3 has an owner, the user that created the
|
* Every bucket and object in Amazon S3 has an owner, the user that created the bucket or object.
|
||||||
* bucket or object. The owner of a bucket or object cannot be changed. However,
|
* The owner of a bucket or object cannot be changed. However, if the object is overwritten by
|
||||||
* if the object is overwritten by another user (deleted and rewritten), the new
|
* another user (deleted and rewritten), the new object will have a new owner.
|
||||||
* object will have a new owner.
|
|
||||||
* <p/>
|
* <p/>
|
||||||
*
|
*
|
||||||
* @see <a href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?
|
* @see <a href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?
|
||||||
|
@ -42,19 +41,14 @@ public class CanonicalUser {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public CanonicalUser(String id, String displayName) {
|
||||||
public String toString() {
|
this(id);
|
||||||
final StringBuilder sb = new StringBuilder();
|
this.displayName = displayName;
|
||||||
sb.append("S3Owner");
|
|
||||||
sb.append("{id='").append(id).append('\'');
|
|
||||||
sb.append(", displayName='").append(displayName).append('\'');
|
|
||||||
sb.append('}');
|
|
||||||
return sb.toString();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* To locate the CanonicalUser ID for a user, the user must perform the
|
* To locate the CanonicalUser ID for a user, the user must perform the
|
||||||
* {@link org.jclouds.aws.s3.S3BlobStore#listBlobs(String)} and retrieve
|
* {@link org.jclouds.aws.s3.blobstore.S3BlobStore#list(String)} and retrieve
|
||||||
* {@link BucketMetadata#getOwner()}
|
* {@link BucketMetadata#getOwner()}
|
||||||
*/
|
*/
|
||||||
public String getId() {
|
public String getId() {
|
||||||
|
@ -73,28 +67,28 @@ public class CanonicalUser {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object o) {
|
public int hashCode() {
|
||||||
if (this == o)
|
final int prime = 31;
|
||||||
return true;
|
int result = 1;
|
||||||
if (!(o instanceof CanonicalUser))
|
result = prime * result + ((id == null) ? 0 : id.hashCode());
|
||||||
return false;
|
return result;
|
||||||
|
|
||||||
CanonicalUser s3Owner = (CanonicalUser) o;
|
|
||||||
|
|
||||||
if (displayName != null ? !displayName.equals(s3Owner.displayName)
|
|
||||||
: s3Owner.displayName != null)
|
|
||||||
return false;
|
|
||||||
if (!id.equals(s3Owner.id))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public boolean equals(Object obj) {
|
||||||
int result = id.hashCode();
|
if (this == obj)
|
||||||
result = 31 * result
|
return true;
|
||||||
+ (displayName != null ? displayName.hashCode() : 0);
|
if (obj == null)
|
||||||
return result;
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
@ -48,7 +48,40 @@ import java.util.SortedSet;
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
* @see <a href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html" />
|
* @see <a href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html" />
|
||||||
*/
|
*/
|
||||||
public interface ListBucketResponse extends org.jclouds.rest.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:
|
* Example:
|
||||||
|
@ -65,12 +98,12 @@ public interface ListBucketResponse extends org.jclouds.rest.internal.BoundedSor
|
||||||
*
|
*
|
||||||
* @see org.jclouds.aws.s3.options.ListBucketOptions#getPrefix()
|
* @see org.jclouds.aws.s3.options.ListBucketOptions#getPrefix()
|
||||||
*/
|
*/
|
||||||
public SortedSet<String> getCommonPrefixes();
|
SortedSet<String> getCommonPrefixes();
|
||||||
|
|
||||||
public String getBucketName();
|
|
||||||
|
|
||||||
public String getDelimiter();
|
|
||||||
|
|
||||||
public boolean isTruncated();
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
@ -23,9 +23,9 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.aws.s3.domain;
|
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}
|
* /** 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" />
|
* @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 */
|
public enum StorageClass {
|
||||||
private static final long serialVersionUID = -4415449798024051115L;
|
STANDARD
|
||||||
|
|
||||||
@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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param key
|
* The key is the handle that you assign to an object that allows you retrieve it later. A key is
|
||||||
* @see #getKey()
|
* 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) {
|
String getKey();
|
||||||
super(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setOwner(CanonicalUser owner) {
|
|
||||||
this.owner = owner;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Every bucket and object in Amazon S3 has an owner, the user that created the bucket or object.
|
* 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
|
* 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.
|
* another user (deleted and rewritten), the new object will have a new owner.
|
||||||
*/
|
*/
|
||||||
public CanonicalUser getOwner() {
|
CanonicalUser getOwner();
|
||||||
return owner;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setStorageClass(String storageClass) {
|
|
||||||
this.storageClass = storageClass;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Currently defaults to 'STANDARD' and not used.
|
* Currently defaults to 'STANDARD' and not used.
|
||||||
*/
|
*/
|
||||||
public String getStorageClass() {
|
StorageClass getStorageClass();
|
||||||
return storageClass;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCacheControl(String cacheControl) {
|
|
||||||
this.cacheControl = cacheControl;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Can be used to specify caching behavior along the request/reply chain.
|
* Can be used to specify caching behavior along the request/reply chain.
|
||||||
*
|
*
|
||||||
* @link http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html?sec14.9.
|
* @link http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html?sec14.9.
|
||||||
*/
|
*/
|
||||||
public String getCacheControl() {
|
String getCacheControl();
|
||||||
return cacheControl;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setContentDisposition(String dataDisposition) {
|
|
||||||
this.dataDisposition = dataDisposition;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specifies presentational information for the object.
|
* Specifies presentational information for the object.
|
||||||
*
|
*
|
||||||
* @see <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec19.html?sec19.5.1."/>
|
* @see <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec19.html?sec19.5.1."/>
|
||||||
*/
|
*/
|
||||||
public String getContentDisposition() {
|
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specifies what content encodings have been applied to the object and thus what decoding
|
* 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" />
|
* @see <a href= "http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html?sec14.11" />
|
||||||
*/
|
*/
|
||||||
public String getContentEncoding() {
|
String getContentEncoding();
|
||||||
return dataEncoding;
|
|
||||||
}
|
/**
|
||||||
|
*
|
||||||
|
* 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
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
@ -23,41 +23,76 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.aws.s3.domain;
|
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
|
* Amazon S3 is designed to store objects. Objects are stored in buckets and consist of a
|
||||||
* consist of a {@link org.jclouds.aws.s3.domain.S3Object#getData() value}, a
|
* {@link ObjectMetadataS3Object#getData() value}, a {@link ObjectMetadata#getKey key},
|
||||||
* {@link S3Object#getKey key}, {@link S3Object.Metadata#getUserMetadata() metadata}, and an access
|
* {@link ObjectMetadata#getUserMetadata() metadata}, and an access control policy.
|
||||||
* control policy.
|
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @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/index.html?UsingObjects.html"
|
||||||
* />
|
* />
|
||||||
*/
|
*/
|
||||||
public class S3Object extends BlobImpl<ObjectMetadata> {
|
public interface S3Object extends Comparable<S3Object> {
|
||||||
|
public interface Factory {
|
||||||
public S3Object(ObjectMetadata metadata, Object data) {
|
S3Object create(@Nullable MutableObjectMetadata metadata);
|
||||||
super(metadata, data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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() {
|
* generate an MD5 Hash for the current data.
|
||||||
this(new ObjectMetadata());
|
* <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) {
|
void setContentLength(long contentLength);
|
||||||
this(new ObjectMetadata(key));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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
|
* 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
|
* 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
|
* 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
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
@ -24,11 +24,17 @@
|
||||||
package org.jclouds.aws.s3.functions;
|
package org.jclouds.aws.s3.functions;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
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.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.
|
* 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
|
* @see ParseMetadataFromHeaders
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
public class ParseObjectFromHeadersAndHttpContent extends
|
public class ParseObjectFromHeadersAndHttpContent implements Function<HttpResponse, S3Object>,
|
||||||
ParseBlobFromHeadersAndHttpContent<ObjectMetadata, S3Object> {
|
InvocationContext {
|
||||||
|
|
||||||
|
private final ParseObjectMetadataFromHeaders metadataParser;
|
||||||
|
private final S3Object.Factory objectProvider;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public ParseObjectFromHeadersAndHttpContent(ParseObjectMetadataFromHeaders metadataParser,
|
public ParseObjectFromHeadersAndHttpContent(ParseObjectMetadataFromHeaders metadataParser,
|
||||||
Provider<S3Object> blobFactory) {
|
S3Object.Factory objectProvider) {
|
||||||
super(metadataParser, blobFactory);
|
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
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
@ -23,45 +23,50 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.aws.s3.functions;
|
package org.jclouds.aws.s3.functions;
|
||||||
|
|
||||||
import static org.jclouds.blobstore.reference.BlobStoreConstants.PROPERTY_USER_METADATA_PREFIX;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Named;
|
|
||||||
import javax.inject.Provider;
|
|
||||||
import javax.ws.rs.core.HttpHeaders;
|
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.aws.s3.reference.S3Headers;
|
||||||
|
import org.jclouds.blobstore.domain.BlobMetadata;
|
||||||
import org.jclouds.blobstore.functions.ParseSystemAndUserMetadataFromHeaders;
|
import org.jclouds.blobstore.functions.ParseSystemAndUserMetadataFromHeaders;
|
||||||
import org.jclouds.http.HttpResponse;
|
import org.jclouds.http.HttpResponse;
|
||||||
import org.jclouds.http.HttpUtils;
|
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.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" />
|
* @see <a href="http://docs.amazonwebservices.com/AmazonS3/latest/RESTObjectGET.html" />
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
public class ParseObjectMetadataFromHeaders extends
|
public class ParseObjectMetadataFromHeaders implements
|
||||||
ParseSystemAndUserMetadataFromHeaders<ObjectMetadata> {
|
Function<HttpResponse, MutableObjectMetadata>, InvocationContext {
|
||||||
|
private final ParseSystemAndUserMetadataFromHeaders blobMetadataParser;
|
||||||
|
private final BlobToObjectMetadata blobToObjectMetadata;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public ParseObjectMetadataFromHeaders(DateService dateParser,
|
public ParseObjectMetadataFromHeaders(ParseSystemAndUserMetadataFromHeaders blobMetadataParser,
|
||||||
@Named(PROPERTY_USER_METADATA_PREFIX) String metadataPrefix,
|
BlobToObjectMetadata blobToObjectMetadata) {
|
||||||
Provider<ObjectMetadata> metadataFactory) {
|
this.blobMetadataParser = blobMetadataParser;
|
||||||
super(dateParser, metadataPrefix, metadataFactory);
|
this.blobToObjectMetadata = blobToObjectMetadata;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* parses the http response headers to create a new
|
* 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 MutableObjectMetadata apply(HttpResponse from) {
|
||||||
public ObjectMetadata apply(HttpResponse from) {
|
BlobMetadata base = blobMetadataParser.apply(from);
|
||||||
ObjectMetadata to = super.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.setCacheControl(from.getFirstHeaderOrNull(HttpHeaders.CACHE_CONTROL));
|
||||||
to.setContentDisposition(from.getFirstHeaderOrNull("Content-Disposition"));
|
to.setContentDisposition(from.getFirstHeaderOrNull("Content-Disposition"));
|
||||||
to.setContentEncoding(from.getFirstHeaderOrNull(HttpHeaders.CONTENT_ENCODING));
|
to.setContentEncoding(from.getFirstHeaderOrNull(HttpHeaders.CONTENT_ENCODING));
|
||||||
|
@ -72,15 +77,17 @@ public class ParseObjectMetadataFromHeaders extends
|
||||||
* ETag == Content-MD5
|
* ETag == Content-MD5
|
||||||
*/
|
*/
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
protected void addETagTo(HttpResponse from, ObjectMetadata metadata) {
|
protected void addETagTo(HttpResponse from, MutableObjectMetadata metadata) {
|
||||||
super.addETagTo(from, metadata);
|
|
||||||
if (metadata.getETag() == null) {
|
if (metadata.getETag() == null) {
|
||||||
String eTagHeader = from.getFirstHeaderOrNull(S3Headers.AMZ_MD5);
|
String eTagHeader = from.getFirstHeaderOrNull(S3Headers.AMZ_MD5);
|
||||||
if (eTagHeader != null) {
|
if (eTagHeader != null) {
|
||||||
metadata.setETag(eTagHeader);
|
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
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
@ -23,6 +23,8 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.aws.s3.functions;
|
package org.jclouds.aws.s3.functions;
|
||||||
|
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
import org.jclouds.aws.AWSResponseException;
|
import org.jclouds.aws.AWSResponseException;
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
|
@ -31,6 +33,7 @@ import com.google.common.base.Function;
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
|
@Singleton
|
||||||
public class ReturnTrueIfBucketAlreadyOwnedByYou implements Function<Exception, Boolean> {
|
public class ReturnTrueIfBucketAlreadyOwnedByYou implements Function<Exception, Boolean> {
|
||||||
|
|
||||||
public Boolean apply(Exception from) {
|
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
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
@ -23,10 +23,13 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.aws.s3.functions;
|
package org.jclouds.aws.s3.functions;
|
||||||
|
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
import org.jclouds.aws.AWSResponseException;
|
import org.jclouds.aws.AWSResponseException;
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
|
|
||||||
|
@Singleton
|
||||||
public class ReturnTrueOn404FalseIfNotEmpty implements Function<Exception, Boolean> {
|
public class ReturnTrueOn404FalseIfNotEmpty implements Function<Exception, Boolean> {
|
||||||
|
|
||||||
public Boolean apply(Exception from) {
|
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
|
* 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
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
@ -62,7 +62,7 @@ public class AWSClientErrorRetryHandler implements HttpRetryHandler {
|
||||||
if (command.getFailureCount() > retryCountLimit)
|
if (command.getFailureCount() > retryCountLimit)
|
||||||
return false;
|
return false;
|
||||||
if (response.getStatusCode() == 400 || response.getStatusCode() == 409) {
|
if (response.getStatusCode() == 400 || response.getStatusCode() == 409) {
|
||||||
byte[] content = Utils.closeConnectionButKeepContentStream(response);
|
byte[] content = Utils.closeClientButKeepContentStream(response);
|
||||||
command.incrementFailureCount();
|
command.incrementFailureCount();
|
||||||
try {
|
try {
|
||||||
AWSError error = utils.parseAWSErrorFromContent(command, response, new String(content));
|
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
|
* 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) {
|
public boolean shouldRetryRequest(HttpCommand command, HttpResponse response) {
|
||||||
if (response.getFirstHeaderOrNull(HttpHeaders.LOCATION) == null
|
if (response.getFirstHeaderOrNull(HttpHeaders.LOCATION) == null
|
||||||
&& (response.getStatusCode() == 301 || response.getStatusCode() == 307)) {
|
&& (response.getStatusCode() == 301 || response.getStatusCode() == 307)) {
|
||||||
byte[] content = Utils.closeConnectionButKeepContentStream(response);
|
byte[] content = Utils.closeClientButKeepContentStream(response);
|
||||||
if (command.getRequest().getMethod() == HttpMethod.HEAD) {
|
if (command.getRequest().getMethod() == HttpMethod.HEAD) {
|
||||||
command.setMethod(HttpMethod.GET);
|
command.setMethod(HttpMethod.GET);
|
||||||
return true;
|
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
|
* 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
|
* 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
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
@ -53,7 +53,7 @@ import com.google.common.collect.Multimap;
|
||||||
* <code>
|
* <code>
|
||||||
* import static org.jclouds.aws.s3.commands.options.CopyObjectOptions.Builder.*
|
* import static org.jclouds.aws.s3.commands.options.CopyObjectOptions.Builder.*
|
||||||
* <p/>
|
* <p/>
|
||||||
* S3Connection connection = // get connection
|
* S3Client connection = // get connection
|
||||||
* <p/>
|
* <p/>
|
||||||
* Multimap<String,String> metadata = HashMultimap.create();
|
* Multimap<String,String> metadata = HashMultimap.create();
|
||||||
* metadata.put("x-amz-meta-adrian", "foo");
|
* 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
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
@ -37,7 +37,7 @@ import org.jclouds.http.options.BaseHttpRequestOptions;
|
||||||
* <code>
|
* <code>
|
||||||
* import static org.jclouds.aws.s3.commands.options.GetBucketOptions.Builder.*
|
* import static org.jclouds.aws.s3.commands.options.GetBucketOptions.Builder.*
|
||||||
* <p/>
|
* <p/>
|
||||||
* S3Connection connection = // get connection
|
* S3Client connection = // get connection
|
||||||
* Future<S3Bucket> bucket = connection.listBucket("bucketName",withPrefix("home/users").maxKeys(1000));
|
* Future<S3Bucket> bucket = connection.listBucket("bucketName",withPrefix("home/users").maxKeys(1000));
|
||||||
* <code>
|
* <code>
|
||||||
*
|
*
|
||||||
|
@ -60,6 +60,10 @@ public class ListBucketOptions extends BaseHttpRequestOptions {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getPrefix() {
|
||||||
|
return getFirstQueryOrNull("prefix");
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicates where in the bucket to begin listing. The list will only include keys that occur
|
* 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
|
* 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;
|
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
|
* 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.
|
* 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");
|
checkState(maxKeys >= 0, "maxKeys must be >= 0");
|
||||||
queryParameters.put("max-keys", Long.toString(maxKeys));
|
queryParameters.put("max-keys", Long.toString(maxKeys));
|
||||||
return this;
|
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
|
* 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
|
* 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;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getDelimiter() {
|
||||||
|
return getFirstQueryOrNull("delimiter");
|
||||||
|
}
|
||||||
|
|
||||||
public static class Builder {
|
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();
|
ListBucketOptions options = new ListBucketOptions();
|
||||||
return options.maxResults(maxKeys);
|
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
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
@ -39,9 +39,9 @@ import org.jclouds.http.options.BaseHttpRequestOptions;
|
||||||
* <code>
|
* <code>
|
||||||
* import static org.jclouds.aws.s3.commands.options.PutBucketOptions.Builder.*
|
* import static org.jclouds.aws.s3.commands.options.PutBucketOptions.Builder.*
|
||||||
* import static org.jclouds.aws.s3.domain.S3Bucket.Metadata.LocationConstraint.*;
|
* import static org.jclouds.aws.s3.domain.S3Bucket.Metadata.LocationConstraint.*;
|
||||||
* import org.jclouds.aws.s3.S3Connection;
|
* import org.jclouds.aws.s3.S3Client;
|
||||||
* <p/>
|
* <p/>
|
||||||
* S3Connection connection = // get connection
|
* S3Client connection = // get connection
|
||||||
* Future<Boolean> createdInEu = connection.putBucketIfNotExists("bucketName",createIn(EU));
|
* Future<Boolean> createdInEu = connection.putBucketIfNotExists("bucketName",createIn(EU));
|
||||||
* <code>
|
* <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
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
@ -39,9 +39,9 @@ import static com.google.common.base.Preconditions.*;
|
||||||
* <p/>
|
* <p/>
|
||||||
* <code>
|
* <code>
|
||||||
* import static org.jclouds.aws.s3.commands.options.PutObjectOptions.Builder.*
|
* 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));
|
* Future<Boolean> publicly readable = connection.putObject("bucketName",new S3Object("key","value"), withAcl(CannedAccessPolicy.PUBLIC_READ));
|
||||||
* <code>
|
* <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
|
* 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
|
* 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
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
@ -24,14 +24,13 @@
|
||||||
package org.jclouds.aws.s3.reference;
|
package org.jclouds.aws.s3.reference;
|
||||||
|
|
||||||
import org.jclouds.aws.reference.AWSConstants;
|
import org.jclouds.aws.reference.AWSConstants;
|
||||||
import org.jclouds.blobstore.reference.BlobStoreConstants;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configuration properties and constants used in S3 connections.
|
* Configuration properties and constants used in S3 connections.
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @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.
|
* 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.
|
* 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_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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
@ -26,8 +26,10 @@ package org.jclouds.aws.s3.xml;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
import org.jclouds.aws.s3.domain.ObjectMetadata;
|
import org.jclouds.aws.s3.domain.ObjectMetadata;
|
||||||
|
import org.jclouds.aws.s3.domain.internal.CopyObjectResult;
|
||||||
import org.jclouds.http.functions.ParseSax;
|
import org.jclouds.http.functions.ParseSax;
|
||||||
import org.jclouds.util.DateService;
|
import org.jclouds.util.DateService;
|
||||||
|
import org.joda.time.DateTime;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses the response from Amazon S3 COPY Object command.
|
* 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> {
|
public class CopyObjectHandler extends ParseSax.HandlerWithResult<ObjectMetadata> {
|
||||||
|
|
||||||
private ObjectMetadata metadata = new ObjectMetadata();
|
private CopyObjectResult metadata;
|
||||||
private StringBuilder currentText = new StringBuilder();
|
private StringBuilder currentText = new StringBuilder();
|
||||||
@Inject
|
@Inject
|
||||||
private DateService dateParser;
|
private DateService dateParser;
|
||||||
|
private DateTime currentLastModified;
|
||||||
|
private String currentETag;
|
||||||
|
|
||||||
public ObjectMetadata getResult() {
|
public ObjectMetadata getResult() {
|
||||||
return metadata;
|
return metadata;
|
||||||
|
@ -50,9 +54,11 @@ public class CopyObjectHandler extends ParseSax.HandlerWithResult<ObjectMetadata
|
||||||
|
|
||||||
public void endElement(String uri, String name, String qName) {
|
public void endElement(String uri, String name, String qName) {
|
||||||
if (qName.equals("ETag")) {
|
if (qName.equals("ETag")) {
|
||||||
metadata.setETag(currentText.toString());
|
this.currentETag = currentText.toString().trim();
|
||||||
} else if (qName.equals("LastModified")) {
|
} 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();
|
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
|
* 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.aws.s3.domain.CanonicalUser;
|
||||||
import org.jclouds.http.functions.ParseSax;
|
import org.jclouds.http.functions.ParseSax;
|
||||||
import org.jclouds.util.DateService;
|
import org.jclouds.util.DateService;
|
||||||
|
import org.joda.time.DateTime;
|
||||||
|
|
||||||
import com.google.common.collect.Sets;
|
import com.google.common.collect.Sets;
|
||||||
|
|
||||||
|
@ -47,11 +48,12 @@ import com.google.common.collect.Sets;
|
||||||
public class ListAllMyBucketsHandler extends ParseSax.HandlerWithResult<SortedSet<BucketMetadata>> {
|
public class ListAllMyBucketsHandler extends ParseSax.HandlerWithResult<SortedSet<BucketMetadata>> {
|
||||||
|
|
||||||
private SortedSet<BucketMetadata> buckets = Sets.newTreeSet();
|
private SortedSet<BucketMetadata> buckets = Sets.newTreeSet();
|
||||||
private BucketMetadata currentS3Bucket;
|
|
||||||
private CanonicalUser currentOwner;
|
private CanonicalUser currentOwner;
|
||||||
private StringBuilder currentText = new StringBuilder();
|
private StringBuilder currentText = new StringBuilder();
|
||||||
|
|
||||||
private final DateService dateParser;
|
private final DateService dateParser;
|
||||||
|
private String currentName;
|
||||||
|
private DateTime currentCreationDate;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public ListAllMyBucketsHandler(DateService dateParser) {
|
public ListAllMyBucketsHandler(DateService dateParser) {
|
||||||
|
@ -64,16 +66,15 @@ public class ListAllMyBucketsHandler extends ParseSax.HandlerWithResult<SortedSe
|
||||||
|
|
||||||
public void endElement(String uri, String name, String qName) {
|
public void endElement(String uri, String name, String qName) {
|
||||||
if (qName.equals("ID")) { // owner stuff
|
if (qName.equals("ID")) { // owner stuff
|
||||||
currentOwner = new CanonicalUser(currentText.toString());
|
currentOwner = new CanonicalUser(currentText.toString().trim());
|
||||||
} else if (qName.equals("DisplayName")) {
|
} else if (qName.equals("DisplayName")) {
|
||||||
currentOwner.setDisplayName(currentText.toString());
|
currentOwner.setDisplayName(currentText.toString().trim());
|
||||||
} else if (qName.equals("Bucket")) {
|
} else if (qName.equals("Bucket")) {
|
||||||
currentS3Bucket.setOwner(currentOwner);
|
buckets.add(new BucketMetadata(currentName, currentCreationDate, currentOwner));
|
||||||
buckets.add(currentS3Bucket);
|
|
||||||
} else if (qName.equals("Name")) {
|
} else if (qName.equals("Name")) {
|
||||||
currentS3Bucket = new BucketMetadata(currentText.toString());
|
currentName = currentText.toString().trim();
|
||||||
} else if (qName.equals("CreationDate")) {
|
} else if (qName.equals("CreationDate")) {
|
||||||
currentS3Bucket.setCreationDate(dateParser.iso8601DateParse(currentText.toString()));
|
currentCreationDate = dateParser.iso8601DateParse(currentText.toString().trim());
|
||||||
}
|
}
|
||||||
currentText = new StringBuilder();
|
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
|
* 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.CanonicalUser;
|
||||||
import org.jclouds.aws.s3.domain.ListBucketResponse;
|
import org.jclouds.aws.s3.domain.ListBucketResponse;
|
||||||
import org.jclouds.aws.s3.domain.ObjectMetadata;
|
import org.jclouds.aws.s3.domain.ObjectMetadata;
|
||||||
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.HttpUtils;
|
||||||
import org.jclouds.http.functions.ParseSax;
|
import org.jclouds.http.functions.ParseSax;
|
||||||
import org.jclouds.util.DateService;
|
import org.jclouds.util.DateService;
|
||||||
|
import org.joda.time.DateTime;
|
||||||
import org.xml.sax.Attributes;
|
import org.xml.sax.Attributes;
|
||||||
|
|
||||||
import com.google.common.collect.Sets;
|
import com.google.common.collect.Sets;
|
||||||
|
@ -51,7 +54,6 @@ import com.google.common.collect.Sets;
|
||||||
public class ListBucketHandler extends ParseSax.HandlerWithResult<ListBucketResponse> {
|
public class ListBucketHandler extends ParseSax.HandlerWithResult<ListBucketResponse> {
|
||||||
private SortedSet<ObjectMetadata> contents;
|
private SortedSet<ObjectMetadata> contents;
|
||||||
private SortedSet<String> commonPrefixes;
|
private SortedSet<String> commonPrefixes;
|
||||||
private ObjectMetadata currentObjectMetadata;
|
|
||||||
private CanonicalUser currentOwner;
|
private CanonicalUser currentOwner;
|
||||||
private StringBuilder currentText = new StringBuilder();
|
private StringBuilder currentText = new StringBuilder();
|
||||||
|
|
||||||
|
@ -76,6 +78,12 @@ public class ListBucketHandler extends ParseSax.HandlerWithResult<ListBucketResp
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean inCommonPrefixes;
|
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) {
|
public void startElement(String uri, String name, String qName, Attributes attrs) {
|
||||||
if (qName.equals("CommonPrefixes")) {
|
if (qName.equals("CommonPrefixes")) {
|
||||||
|
@ -85,27 +93,26 @@ public class ListBucketHandler extends ParseSax.HandlerWithResult<ListBucketResp
|
||||||
|
|
||||||
public void endElement(String uri, String name, String qName) {
|
public void endElement(String uri, String name, String qName) {
|
||||||
if (qName.equals("ID")) {
|
if (qName.equals("ID")) {
|
||||||
currentOwner = new CanonicalUser(currentText.toString());
|
currentOwner = new CanonicalUser(currentText.toString().trim());
|
||||||
} else if (qName.equals("DisplayName")) {
|
} else if (qName.equals("DisplayName")) {
|
||||||
currentOwner.setDisplayName(currentText.toString());
|
currentOwner.setDisplayName(currentText.toString().trim());
|
||||||
} else if (qName.equals("Key")) { // content stuff
|
} else if (qName.equals("Key")) { // content stuff
|
||||||
currentObjectMetadata = new ObjectMetadata(currentText.toString());
|
currentKey = currentText.toString().trim();
|
||||||
} else if (qName.equals("LastModified")) {
|
} else if (qName.equals("LastModified")) {
|
||||||
currentObjectMetadata.setLastModified(dateParser.iso8601DateParse(currentText.toString()));
|
currentLastModified = dateParser.iso8601DateParse(currentText.toString().trim());
|
||||||
} else if (qName.equals("ETag")) {
|
} else if (qName.equals("ETag")) {
|
||||||
currentObjectMetadata.setETag(currentText.toString());
|
currentETag = currentText.toString().trim();
|
||||||
currentObjectMetadata.setContentMD5(HttpUtils.fromHexString(currentObjectMetadata
|
currentMD5 = HttpUtils.fromHexString(currentETag.replaceAll("\"", ""));
|
||||||
.getETag().replaceAll("\"", "")));
|
|
||||||
} else if (qName.equals("Size")) {
|
} else if (qName.equals("Size")) {
|
||||||
currentObjectMetadata.setSize(Long.parseLong(currentText.toString()));
|
currentSize = new Long(currentText.toString().trim());
|
||||||
} else if (qName.equals("Owner")) {
|
} else if (qName.equals("Owner")) {
|
||||||
currentObjectMetadata.setOwner(currentOwner);
|
|
||||||
} else if (qName.equals("StorageClass")) {
|
} else if (qName.equals("StorageClass")) {
|
||||||
currentObjectMetadata.setStorageClass(currentText.toString());
|
currentStorageClass = ObjectMetadata.StorageClass.valueOf(currentText.toString().trim());
|
||||||
} else if (qName.equals("Contents")) {
|
} else if (qName.equals("Contents")) {
|
||||||
contents.add(currentObjectMetadata);
|
contents.add(new BucketListObjectMetadata(currentKey, currentLastModified, currentETag,
|
||||||
|
currentMD5, currentSize, currentOwner, currentStorageClass));
|
||||||
} else if (qName.equals("Name")) {
|
} else if (qName.equals("Name")) {
|
||||||
this.bucketName = currentText.toString();
|
this.bucketName = currentText.toString().trim();
|
||||||
} else if (qName.equals("Prefix")) {
|
} else if (qName.equals("Prefix")) {
|
||||||
String prefix = currentText.toString().trim();
|
String prefix = currentText.toString().trim();
|
||||||
if (inCommonPrefixes)
|
if (inCommonPrefixes)
|
||||||
|
@ -117,11 +124,11 @@ public class ListBucketHandler extends ParseSax.HandlerWithResult<ListBucketResp
|
||||||
this.delimiter = currentText.toString().trim();
|
this.delimiter = currentText.toString().trim();
|
||||||
} else if (qName.equals("Marker")) {
|
} else if (qName.equals("Marker")) {
|
||||||
if (!currentText.toString().equals(""))
|
if (!currentText.toString().equals(""))
|
||||||
this.marker = currentText.toString();
|
this.marker = currentText.toString().trim();
|
||||||
} else if (qName.equals("MaxKeys")) {
|
} else if (qName.equals("MaxKeys")) {
|
||||||
this.maxResults = Integer.parseInt(currentText.toString());
|
this.maxResults = Integer.parseInt(currentText.toString().trim());
|
||||||
} else if (qName.equals("IsTruncated")) {
|
} else if (qName.equals("IsTruncated")) {
|
||||||
this.isTruncated = Boolean.parseBoolean(currentText.toString());
|
this.isTruncated = Boolean.parseBoolean(currentText.toString().trim());
|
||||||
}
|
}
|
||||||
currentText = new StringBuilder();
|
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
|
* 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
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
@ -23,8 +23,8 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.aws.s3;
|
package org.jclouds.aws.s3;
|
||||||
|
|
||||||
import static org.jclouds.aws.s3.internal.StubS3Connection.TEST_ACL_EMAIL;
|
import static org.jclouds.aws.s3.internal.StubS3Client.TEST_ACL_EMAIL;
|
||||||
import static org.jclouds.aws.s3.internal.StubS3Connection.TEST_ACL_ID;
|
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.ifSourceETagDoesntMatch;
|
||||||
import static org.jclouds.aws.s3.options.CopyObjectOptions.Builder.ifSourceETagMatches;
|
import static org.jclouds.aws.s3.options.CopyObjectOptions.Builder.ifSourceETagMatches;
|
||||||
import static org.jclouds.aws.s3.options.CopyObjectOptions.Builder.ifSourceModifiedSince;
|
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 static org.testng.Assert.assertTrue;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -76,9 +77,8 @@ import com.google.common.collect.Maps;
|
||||||
* @author James Murty
|
* @author James Murty
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
@Test(groups = { "integration", "live" }, testName = "s3.S3ConnectionLiveTest")
|
@Test(groups = { "integration", "live" }, testName = "s3.S3ClientLiveTest")
|
||||||
public class S3ConnectionLiveTest extends
|
public class S3ClientLiveTest extends BaseBlobStoreIntegrationTest<S3Client> {
|
||||||
BaseBlobStoreIntegrationTest<S3Connection, BucketMetadata, ObjectMetadata, S3Object> {
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* this method overrides containerName to ensure it isn't found
|
* this method overrides containerName to ensure it isn't found
|
||||||
|
@ -103,8 +103,10 @@ public class S3ConnectionLiveTest extends
|
||||||
String containerName = getContainerName();
|
String containerName = getContainerName();
|
||||||
try {
|
try {
|
||||||
String key = "hello";
|
String key = "hello";
|
||||||
|
S3Object object = context.getApi().newS3Object();
|
||||||
context.getApi().putObject(containerName, new S3Object(key, TEST_STRING),
|
object.getMetadata().setKey(key);
|
||||||
|
object.setData(TEST_STRING);
|
||||||
|
context.getApi().putObject(containerName, object,
|
||||||
|
|
||||||
withAcl(CannedAccessPolicy.PUBLIC_READ)).get(10, TimeUnit.SECONDS);
|
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 publicReadWriteObjectKey = "public-read-write-acl";
|
||||||
final String containerName = getContainerName();
|
final String containerName = getContainerName();
|
||||||
try {
|
try {
|
||||||
|
S3Object object = context.getApi().newS3Object();
|
||||||
|
object.getMetadata().setKey(publicReadWriteObjectKey);
|
||||||
|
object.setData("");
|
||||||
// Public Read-Write object
|
// 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,
|
new PutObjectOptions().withAcl(CannedAccessPolicy.PUBLIC_READ_WRITE)).get(10,
|
||||||
TimeUnit.SECONDS);
|
TimeUnit.SECONDS);
|
||||||
|
|
||||||
assertEventually(new Runnable() {
|
assertConsistencyAware(new Runnable() {
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
AccessControlList acl = context.getApi().getObjectACL(containerName,
|
AccessControlList acl = context.getApi().getObjectACL(containerName,
|
||||||
|
@ -252,11 +257,14 @@ public class S3ConnectionLiveTest extends
|
||||||
final String publicReadObjectKey = "public-read-acl";
|
final String publicReadObjectKey = "public-read-acl";
|
||||||
final String containerName = getContainerName();
|
final String containerName = getContainerName();
|
||||||
try {
|
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,
|
new PutObjectOptions().withAcl(CannedAccessPolicy.PUBLIC_READ)).get(10,
|
||||||
TimeUnit.SECONDS);
|
TimeUnit.SECONDS);
|
||||||
|
|
||||||
assertEventually(new Runnable() {
|
assertConsistencyAware(new Runnable() {
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
AccessControlList acl = context.getApi().getObjectACL(containerName,
|
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 {
|
public void testMetadataWithCacheControlAndContentDisposition() throws Exception {
|
||||||
String key = "hello";
|
String key = "hello";
|
||||||
|
|
||||||
S3Object object = context.newBlob(key);
|
S3Object object = context.getApi().newS3Object();
|
||||||
|
object.getMetadata().setKey(key);
|
||||||
object.setData(TEST_STRING);
|
object.setData(TEST_STRING);
|
||||||
object.getMetadata().setCacheControl("no-cache");
|
object.getMetadata().setCacheControl("no-cache");
|
||||||
object.getMetadata().setContentDisposition("attachment; filename=hello.txt");
|
object.getMetadata().setContentDisposition("attachment; filename=hello.txt");
|
||||||
String containerName = getContainerName();
|
String containerName = getContainerName();
|
||||||
try {
|
try {
|
||||||
addBlobToContainer(containerName, object);
|
context.getApi().putObject(containerName, object).get(10, TimeUnit.SECONDS);
|
||||||
S3Object newObject = validateContent(containerName, key);
|
|
||||||
|
S3Object newObject = validateObject(containerName, key);
|
||||||
|
|
||||||
assertEquals(newObject.getMetadata().getCacheControl(), "no-cache");
|
assertEquals(newObject.getMetadata().getCacheControl(), "no-cache");
|
||||||
assertEquals(newObject.getMetadata().getContentDisposition(),
|
assertEquals(newObject.getMetadata().getContentDisposition(),
|
||||||
|
@ -304,13 +333,14 @@ public class S3ConnectionLiveTest extends
|
||||||
public void testMetadataContentEncoding() throws Exception {
|
public void testMetadataContentEncoding() throws Exception {
|
||||||
String key = "hello";
|
String key = "hello";
|
||||||
|
|
||||||
S3Object object = context.newBlob(key);
|
S3Object object = context.getApi().newS3Object();
|
||||||
|
object.getMetadata().setKey(key);
|
||||||
object.setData(TEST_STRING);
|
object.setData(TEST_STRING);
|
||||||
object.getMetadata().setContentEncoding("x-compress");
|
object.getMetadata().setContentEncoding("x-compress");
|
||||||
String containerName = getContainerName();
|
String containerName = getContainerName();
|
||||||
try {
|
try {
|
||||||
addBlobToContainer(containerName, object);
|
context.getApi().putObject(containerName, object).get(10, TimeUnit.SECONDS);
|
||||||
S3Object newObject = validateContent(containerName, key);
|
S3Object newObject = validateObject(containerName, key);
|
||||||
|
|
||||||
assertEquals(newObject.getMetadata().getContentEncoding(), "x-compress");
|
assertEquals(newObject.getMetadata().getContentEncoding(), "x-compress");
|
||||||
} finally {
|
} 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,
|
public void testPrivateAclIsDefaultForContainer() throws InterruptedException,
|
||||||
ExecutionException, TimeoutException, IOException {
|
ExecutionException, TimeoutException, IOException {
|
||||||
String containerName = getContainerName();
|
String containerName = getContainerName();
|
||||||
|
@ -575,36 +567,6 @@ public class S3ConnectionLiveTest extends
|
||||||
acl.addPermission(new CanonicalUserGrantee(ownerId), Permission.WRITE_ACP);
|
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 {
|
public void testPublicReadAccessPolicy() throws Exception {
|
||||||
String containerName = getScratchContainerName();
|
String containerName = getScratchContainerName();
|
||||||
try {
|
try {
|
||||||
|
@ -643,7 +605,7 @@ public class S3ConnectionLiveTest extends
|
||||||
context.getApi().putBucketIfNotExists(containerName + "eu",
|
context.getApi().putBucketIfNotExists(containerName + "eu",
|
||||||
createIn(LocationConstraint.EU).withBucketAcl(CannedAccessPolicy.PUBLIC_READ))
|
createIn(LocationConstraint.EU).withBucketAcl(CannedAccessPolicy.PUBLIC_READ))
|
||||||
.get(30, TimeUnit.SECONDS);
|
.get(30, TimeUnit.SECONDS);
|
||||||
assertEventually(new Runnable() {
|
assertConsistencyAware(new Runnable() {
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
AccessControlList acl = context.getApi().getBucketACL(containerName + "eu").get(
|
AccessControlList acl = context.getApi().getBucketACL(containerName + "eu").get(
|
||||||
|
@ -667,10 +629,11 @@ public class S3ConnectionLiveTest extends
|
||||||
void containerExists() throws Exception {
|
void containerExists() throws Exception {
|
||||||
String containerName = getContainerName();
|
String containerName = getContainerName();
|
||||||
try {
|
try {
|
||||||
SortedSet<BucketMetadata> list = context.getApi().listOwnedBuckets();
|
SortedSet<BucketMetadata> list = context.getApi().listOwnedBuckets().get(10,
|
||||||
|
TimeUnit.SECONDS);
|
||||||
BucketMetadata firstContainer = list.first();
|
BucketMetadata firstContainer = list.first();
|
||||||
BucketMetadata toMatch = new BucketMetadata(containerName);
|
BucketMetadata toMatch = new BucketMetadata(containerName, new DateTime(), firstContainer
|
||||||
toMatch.setOwner(firstContainer.getOwner());
|
.getOwner());
|
||||||
assert list.contains(toMatch);
|
assert list.contains(toMatch);
|
||||||
} finally {
|
} finally {
|
||||||
returnContainer(containerName);
|
returnContainer(containerName);
|
||||||
|
@ -680,16 +643,86 @@ public class S3ConnectionLiveTest extends
|
||||||
protected void addAlphabetUnderRoot(String containerName) throws InterruptedException,
|
protected void addAlphabetUnderRoot(String containerName) throws InterruptedException,
|
||||||
ExecutionException, TimeoutException {
|
ExecutionException, TimeoutException {
|
||||||
for (char letter = 'a'; letter <= 'z'; letter++) {
|
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");
|
blob.setData(letter + "content");
|
||||||
context.getApi().putObject(containerName, blob).get(10, TimeUnit.SECONDS);
|
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,
|
protected void add15UnderRoot(String containerName) throws InterruptedException,
|
||||||
ExecutionException, TimeoutException {
|
ExecutionException, TimeoutException {
|
||||||
for (int i = 0; i < 15; i++) {
|
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");
|
blob.setData(i + "content");
|
||||||
context.getApi().putObject(containerName, blob).get(10, TimeUnit.SECONDS);
|
context.getApi().putObject(containerName, blob).get(10, TimeUnit.SECONDS);
|
||||||
}
|
}
|
||||||
|
@ -698,7 +731,8 @@ public class S3ConnectionLiveTest extends
|
||||||
protected void addTenObjectsUnderPrefix(String containerName, String prefix)
|
protected void addTenObjectsUnderPrefix(String containerName, String prefix)
|
||||||
throws InterruptedException, ExecutionException, TimeoutException {
|
throws InterruptedException, ExecutionException, TimeoutException {
|
||||||
for (int i = 0; i < 10; i++) {
|
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");
|
blob.setData(i + "content");
|
||||||
context.getApi().putObject(containerName, blob).get(10, TimeUnit.SECONDS);
|
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
|
* 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_ACCESSKEYID;
|
||||||
import static org.jclouds.aws.reference.AWSConstants.PROPERTY_AWS_SECRETACCESSKEY;
|
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 static org.testng.Assert.assertEquals;
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.jclouds.aws.s3.config.RestS3ConnectionModule;
|
|
||||||
import org.jclouds.aws.s3.config.S3ContextModule;
|
import org.jclouds.aws.s3.config.S3ContextModule;
|
||||||
import org.jclouds.aws.s3.config.StubS3BlobStoreModule;
|
import org.jclouds.aws.s3.config.S3RestClientModule;
|
||||||
import org.jclouds.aws.s3.config.S3ContextModule.S3ContextImpl;
|
import org.jclouds.aws.s3.config.S3StubClientModule;
|
||||||
import org.jclouds.aws.s3.internal.StubS3Connection;
|
import org.jclouds.aws.s3.domain.S3Object;
|
||||||
import org.jclouds.blobstore.integration.internal.StubBlobStore;
|
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 org.testng.annotations.Test;
|
||||||
|
|
||||||
import com.google.inject.Injector;
|
import com.google.inject.Injector;
|
||||||
|
import com.google.inject.Key;
|
||||||
import com.google.inject.Module;
|
import com.google.inject.Module;
|
||||||
|
import com.google.inject.TypeLiteral;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests behavior of modules configured in S3ContextBuilder
|
* Tests behavior of modules configured in S3ContextBuilder
|
||||||
|
@ -52,43 +57,49 @@ import com.google.inject.Module;
|
||||||
public class S3ContextBuilderTest {
|
public class S3ContextBuilderTest {
|
||||||
|
|
||||||
public void testNewBuilder() {
|
public void testNewBuilder() {
|
||||||
S3ContextBuilder builder = new S3ContextBuilder("id", "secret");
|
S3ContextBuilder builder = new S3ContextBuilder(new S3PropertiesBuilder("id", "secret")
|
||||||
assertEquals(builder.getProperties().getProperty(PROPERTY_USER_METADATA_PREFIX),
|
.build());
|
||||||
|
assertEquals(builder.getProperties().getProperty(S3Constants.PROPERTY_S3_METADATA_PREFIX),
|
||||||
"x-amz-meta-");
|
"x-amz-meta-");
|
||||||
assertEquals(builder.getProperties().getProperty(PROPERTY_AWS_ACCESSKEYID), "id");
|
assertEquals(builder.getProperties().getProperty(PROPERTY_AWS_ACCESSKEYID), "id");
|
||||||
assertEquals(builder.getProperties().getProperty(PROPERTY_AWS_SECRETACCESSKEY), "secret");
|
assertEquals(builder.getProperties().getProperty(PROPERTY_AWS_SECRETACCESSKEY), "secret");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testBuildContext() {
|
public void testBuildContext() {
|
||||||
S3Context context = new S3ContextBuilder("id", "secret").withModules(
|
RestContext<S3Client> context = new S3ContextBuilder(new S3PropertiesBuilder("id", "secret")
|
||||||
new StubS3BlobStoreModule()).buildContext();
|
.build()).withModules(new S3StubClientModule()).buildContext();
|
||||||
assertEquals(context.getClass(), S3ContextImpl.class);
|
assertEquals(context.getClass(), RestContextImpl.class);
|
||||||
assertEquals(context.getApi().getClass(), StubS3Connection.class);
|
assertEquals(context.getApi().getClass(), StubS3Client.class);
|
||||||
assertEquals(context.getBlobStore().getClass(), StubBlobStore.class);
|
assertEquals(context.getApi().newS3Object().getClass(), S3ObjectImpl.class);
|
||||||
assertEquals(context.getAccount(), "id");
|
assertEquals(context.getAccount(), "id");
|
||||||
assertEquals(context.getEndPoint(), URI.create("https://localhost/s3stub"));
|
assertEquals(context.getEndPoint(), URI.create("https://localhost/s3stub"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testBuildInjector() {
|
public void testBuildInjector() {
|
||||||
Injector i = new S3ContextBuilder("id", "secret").withModules(new StubS3BlobStoreModule())
|
Injector i = new S3ContextBuilder(new S3PropertiesBuilder("id", "secret").build())
|
||||||
.buildInjector();
|
.withModules(new S3StubClientModule()).buildInjector();
|
||||||
assert i.getInstance(S3Context.class) != null;
|
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() {
|
protected void testAddContextModule() {
|
||||||
List<Module> modules = new ArrayList<Module>();
|
List<Module> modules = new ArrayList<Module>();
|
||||||
S3ContextBuilder builder = new S3ContextBuilder("id", "secret");
|
S3ContextBuilder builder = new S3ContextBuilder(new S3PropertiesBuilder("id", "secret")
|
||||||
|
.build());
|
||||||
builder.addContextModule(modules);
|
builder.addContextModule(modules);
|
||||||
assertEquals(modules.size(), 1);
|
assertEquals(modules.size(), 1);
|
||||||
assertEquals(modules.get(0).getClass(), S3ContextModule.class);
|
assertEquals(modules.get(0).getClass(), S3ContextModule.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void addConnectionModule() {
|
protected void addClientModule() {
|
||||||
List<Module> modules = new ArrayList<Module>();
|
List<Module> modules = new ArrayList<Module>();
|
||||||
S3ContextBuilder builder = new S3ContextBuilder("id", "secret");
|
S3ContextBuilder builder = new S3ContextBuilder(new S3PropertiesBuilder("id", "secret")
|
||||||
builder.addConnectionModule(modules);
|
.build());
|
||||||
|
builder.addClientModule(modules);
|
||||||
assertEquals(modules.size(), 1);
|
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
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
@ -21,12 +21,9 @@
|
||||||
* under the License.
|
* 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.S3Client;
|
||||||
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.integration.internal.BaseBlobIntegrationTest;
|
import org.jclouds.blobstore.integration.internal.BaseBlobIntegrationTest;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
@ -36,7 +33,6 @@ import org.testng.annotations.Test;
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
@Test(groups = { "integration", "live" }, testName = "s3.S3BlobIntegrationTest")
|
@Test(groups = { "integration", "live" }, testName = "s3.S3BlobIntegrationTest")
|
||||||
public class S3BlobIntegrationTest extends
|
public class S3BlobIntegrationTest extends BaseBlobIntegrationTest<S3Client> {
|
||||||
BaseBlobIntegrationTest<S3Connection, BucketMetadata, ObjectMetadata, S3Object> {
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -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
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
@ -21,12 +21,9 @@
|
||||||
* under the License.
|
* 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.S3Client;
|
||||||
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.integration.internal.BaseBlobLiveTest;
|
import org.jclouds.blobstore.integration.internal.BaseBlobLiveTest;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
@ -36,7 +33,6 @@ import org.testng.annotations.Test;
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
@Test(groups = { "live" }, testName = "s3.S3BlobLiveTest")
|
@Test(groups = { "live" }, testName = "s3.S3BlobLiveTest")
|
||||||
public class S3BlobLiveTest extends
|
public class S3BlobLiveTest extends BaseBlobLiveTest<S3Client> {
|
||||||
BaseBlobLiveTest<S3Connection, BucketMetadata, ObjectMetadata, S3Object> {
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -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
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
@ -21,12 +21,9 @@
|
||||||
* under the License.
|
* 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.S3Client;
|
||||||
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.integration.internal.BaseBlobMapIntegrationTest;
|
import org.jclouds.blobstore.integration.internal.BaseBlobMapIntegrationTest;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
@ -34,7 +31,6 @@ import org.testng.annotations.Test;
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
@Test(groups = { "integration", "live" }, testName = "s3.S3BlobMapIntegrationTest")
|
@Test(groups = { "integration", "live" }, testName = "s3.S3BlobMapIntegrationTest")
|
||||||
public class S3BlobMapIntegrationTest extends
|
public class S3BlobMapIntegrationTest extends BaseBlobMapIntegrationTest<S3Client> {
|
||||||
BaseBlobMapIntegrationTest<S3Connection, BucketMetadata, ObjectMetadata, S3Object> {
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -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
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
@ -21,12 +21,9 @@
|
||||||
* under the License.
|
* 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.S3Client;
|
||||||
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.integration.internal.BaseContainerIntegrationTest;
|
import org.jclouds.blobstore.integration.internal.BaseContainerIntegrationTest;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
@ -35,7 +32,6 @@ import org.testng.annotations.Test;
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
@Test(groups = { "integration", "live" }, testName = "s3.S3ContainerIntegrationTest")
|
@Test(groups = { "integration", "live" }, testName = "s3.S3ContainerIntegrationTest")
|
||||||
public class S3ContainerIntegrationTest extends
|
public class S3ContainerIntegrationTest extends BaseContainerIntegrationTest<S3Client> {
|
||||||
BaseContainerIntegrationTest<S3Connection, BucketMetadata, ObjectMetadata, S3Object> {
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -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
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
@ -21,12 +21,9 @@
|
||||||
* under the License.
|
* 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.S3Client;
|
||||||
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.integration.internal.BaseContainerLiveTest;
|
import org.jclouds.blobstore.integration.internal.BaseContainerLiveTest;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
@ -35,7 +32,6 @@ import org.testng.annotations.Test;
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
@Test(groups = { "live" }, testName = "s3.S3ContainerLiveTest")
|
@Test(groups = { "live" }, testName = "s3.S3ContainerLiveTest")
|
||||||
public class S3ContainerLiveTest extends
|
public class S3ContainerLiveTest extends BaseContainerLiveTest<S3Client> {
|
||||||
BaseContainerLiveTest<S3Connection, BucketMetadata, ObjectMetadata, S3Object> {
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -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
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
@ -21,12 +21,9 @@
|
||||||
* under the License.
|
* 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.S3Client;
|
||||||
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.integration.internal.BaseInputStreamMapIntegrationTest;
|
import org.jclouds.blobstore.integration.internal.BaseInputStreamMapIntegrationTest;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
@ -35,6 +32,6 @@ import org.testng.annotations.Test;
|
||||||
*/
|
*/
|
||||||
@Test(groups = { "integration", "live" }, testName = "s3.S3InputStreamMapIntegrationTest")
|
@Test(groups = { "integration", "live" }, testName = "s3.S3InputStreamMapIntegrationTest")
|
||||||
public class S3InputStreamMapIntegrationTest extends
|
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