Issue 116: rolled s3 into aws

git-svn-id: http://jclouds.googlecode.com/svn/trunk@2235 3d8758e0-26b5-11de-8745-db77d3ebf521
This commit is contained in:
adrian.f.cole 2009-11-09 03:35:53 +00:00
parent 99ba4498ec
commit 870becd3f1
166 changed files with 169 additions and 496 deletions

View File

@ -34,7 +34,7 @@
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.jclouds</groupId>
<artifactId>jclouds-aws-core</artifactId>
<artifactId>jclouds-aws</artifactId>
<name>jclouds Amazon AWS Components Core</name>
<packaging>jar</packaging>
<description>jclouds Core components to access Amazon AWS</description>

View File

@ -44,7 +44,7 @@ public class AWSResponseException extends HttpResponseException {
private AWSError error = new AWSError();
public AWSResponseException(HttpCommand command, HttpResponse response, AWSError error) {
super(String.format("command %s failed with code %s, error: %s", command.toString(), response
super(String.format("request %s failed with code %s, error: %s", command.getRequest().getRequestLine(), response
.getStatusCode(), error.toString()), command, response);
this.setError(error);
@ -52,7 +52,7 @@ public class AWSResponseException extends HttpResponseException {
public AWSResponseException(HttpCommand command, HttpResponse response, AWSError error,
Throwable cause) {
super(String.format("command %1$s failed with error: %2$s", command.toString(), error
super(String.format("request %1$s failed with error: %2$s", command.getRequest().getRequestLine(), error
.toString()), command, response, cause);
this.setError(error);

View File

@ -32,7 +32,7 @@ import org.jclouds.http.pool.PoolConstants;
* @author Adrian Cole
*/
public interface AWSConstants extends HttpConstants, PoolConstants {
public static final String ENDPOINT = "Endpoint";
public static final String PROPERTY_AWS_SECRETACCESSKEY = "jclouds.aws.secretaccesskey";
public static final String PROPERTY_AWS_ACCESSKEYID = "jclouds.aws.accesskeyid";

View File

@ -29,13 +29,14 @@ import java.util.concurrent.TimeUnit;
import javax.inject.Named;
import javax.inject.Singleton;
import org.jclouds.aws.handlers.AWSClientErrorRetryHandler;
import org.jclouds.aws.handlers.AWSRedirectionRetryHandler;
import org.jclouds.aws.handlers.ParseAWSErrorFromXmlContent;
import org.jclouds.aws.s3.S3;
import org.jclouds.aws.s3.S3Client;
import org.jclouds.aws.s3.filters.RequestAuthorizeSignature;
import org.jclouds.aws.s3.handlers.AWSClientErrorRetryHandler;
import org.jclouds.aws.s3.handlers.AWSRedirectionRetryHandler;
import org.jclouds.aws.s3.handlers.ParseAWSErrorFromXmlContent;
import org.jclouds.aws.s3.reference.S3Constants;
import org.jclouds.aws.util.RequestSigner;
import org.jclouds.concurrent.ExpirableSupplier;
import org.jclouds.http.HttpErrorHandler;
import org.jclouds.http.HttpRetryHandler;
@ -67,6 +68,13 @@ public class S3RestClientModule extends AbstractModule {
protected String provideTimeStamp(@TimeStamp Supplier<String> cache) {
return cache.get();
}
@Provides
@Singleton
RequestSigner provideRequestSigner(RequestAuthorizeSignature in){
return in;
}
/**
* borrowing concurrency code to ensure that caching takes place properly

View File

@ -38,7 +38,7 @@ 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.LinkedHashMultimap;
import com.google.common.collect.Multimap;
/**
@ -52,7 +52,7 @@ public class S3ObjectImpl implements S3Object, Comparable<S3Object> {
private final CalculateSize calculateSize;
private final MutableObjectMetadata metadata;
private Object data;
private Multimap<String, String> allHeaders = HashMultimap.create();
private Multimap<String, String> allHeaders = LinkedHashMultimap.create();
private Long contentLength;
@Inject

View File

@ -39,6 +39,7 @@ import javax.ws.rs.core.HttpHeaders;
import org.apache.commons.io.IOUtils;
import org.jclouds.aws.s3.reference.S3Constants;
import org.jclouds.aws.util.RequestSigner;
import org.jclouds.http.HttpConstants;
import org.jclouds.http.HttpException;
import org.jclouds.http.HttpRequest;
@ -58,7 +59,7 @@ import com.google.common.annotations.VisibleForTesting;
*
*/
@Singleton
public class RequestAuthorizeSignature implements HttpRequestFilter {
public class RequestAuthorizeSignature implements HttpRequestFilter, RequestSigner {
private final String[] firstHeadersToSign = new String[] { "Content-MD5",
HttpHeaders.CONTENT_TYPE, HttpHeaders.DATE };

View File

@ -40,7 +40,7 @@ import org.jclouds.util.DateService;
import org.joda.time.DateTime;
import com.google.common.base.Preconditions;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.LinkedHashMultimap;
import com.google.common.collect.Multimap;
/**
@ -55,7 +55,7 @@ import com.google.common.collect.Multimap;
* <p/>
* S3Client connection = // get connection
* <p/>
* Multimap<String,String> metadata = HashMultimap.create();
* Multimap<String,String> metadata = LinkedHashMultimap.create();
* metadata.put("x-amz-meta-adrian", "foo");
* <p/>
* // this will copy the object, provided it wasn't modified since yesterday.
@ -256,7 +256,7 @@ public class CopyObjectOptions extends BaseHttpRequestOptions {
@Override
public Multimap<String, String> buildRequestHeaders() {
checkState(metadataPrefix != null, "metadataPrefix should have been injected!");
Multimap<String, String> returnVal = HashMultimap.create();
Multimap<String, String> returnVal = LinkedHashMultimap.create();
returnVal.putAll(headers);
if (metadata != null) {
for (String key : metadata.keySet()) {

View File

@ -36,7 +36,6 @@ public interface S3Constants extends AWSConstants, S3Headers {
* S3 service's XML Namespace, as used in XML request and response documents.
*/
public static final String S3_REST_API_XML_NAMESPACE = "http://s3.amazonaws.com/doc/2006-03-01/";
public static final String ENDPOINT = "Endpoint";
public static final String PREFIX = "prefix";
public static final String MARKER = "marker";
public static final String MAX_KEYS = "max-keys";

View File

@ -30,18 +30,15 @@ import java.io.ByteArrayInputStream;
import java.io.InputStream;
import javax.inject.Inject;
import javax.inject.Provider;
import org.jclouds.aws.domain.AWSError;
import org.jclouds.aws.s3.filters.RequestAuthorizeSignature;
import org.jclouds.aws.s3.reference.S3Headers;
import org.jclouds.aws.xml.ErrorHandler;
import org.jclouds.aws.util.AWSUtils;
import org.jclouds.blobstore.util.BlobStoreUtils;
import org.jclouds.http.HttpCommand;
import org.jclouds.http.HttpException;
import org.jclouds.http.HttpResponse;
import org.jclouds.http.HttpUtils;
import org.jclouds.http.functions.ParseSax;
/**
* Encryption, Hashing, and IO Utilities needed to sign and verify S3 requests and responses.
@ -51,24 +48,14 @@ import org.jclouds.http.functions.ParseSax;
public class S3Utils extends BlobStoreUtils {
@Inject
RequestAuthorizeSignature signer;
@Inject
ParseSax.Factory factory;
@Inject
Provider<ErrorHandler> errorHandlerProvider;
AWSUtils util;
public AWSError parseAWSErrorFromContent(HttpCommand command, HttpResponse response,
InputStream content) throws HttpException {
AWSError error = (AWSError) factory.create(errorHandlerProvider.get()).parse(content);
AWSError error = util.parseAWSErrorFromContent(command, response, content);
if (error.getRequestId() == null)
error.setRequestId(response.getFirstHeaderOrNull(S3Headers.REQUEST_ID));
error.setRequestToken(response.getFirstHeaderOrNull(S3Headers.REQUEST_TOKEN));
if ("SignatureDoesNotMatch".equals(error.getCode())) {
error.setStringSigned(signer.createStringToSign(command.getRequest()));
error.setSignature(signer.signString(error.getStringSigned()));
}
return error;
}

View File

@ -0,0 +1,47 @@
package org.jclouds.aws.util;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import javax.inject.Inject;
import javax.inject.Provider;
import org.jclouds.aws.domain.AWSError;
import org.jclouds.aws.xml.ErrorHandler;
import org.jclouds.http.HttpCommand;
import org.jclouds.http.HttpException;
import org.jclouds.http.HttpResponse;
import org.jclouds.http.functions.ParseSax;
/**
* Needed to sign and verify requests and responses.
*
* @author Adrian Cole
*/
public class AWSUtils {
@Inject
RequestSigner signer;
@Inject
ParseSax.Factory factory;
@Inject
Provider<ErrorHandler> errorHandlerProvider;
public AWSError parseAWSErrorFromContent(HttpCommand command, HttpResponse response,
InputStream content) throws HttpException {
AWSError error = (AWSError) factory.create(errorHandlerProvider.get()).parse(content);
if ("SignatureDoesNotMatch".equals(error.getCode())) {
error.setStringSigned(signer.createStringToSign(command.getRequest()));
error.setSignature(signer.signString(error.getStringSigned()));
}
return error;
}
public AWSError parseAWSErrorFromContent(HttpCommand command, HttpResponse response,
String content) throws HttpException {
return parseAWSErrorFromContent(command, response, new ByteArrayInputStream(content
.getBytes()));
}
}

View File

@ -0,0 +1,15 @@
package org.jclouds.aws.util;
import org.jclouds.http.HttpRequest;
/**
*
* @author Adrian Cole
*/
public interface RequestSigner {
String createStringToSign(HttpRequest input);
String signString(String toSign);
}

View File

@ -73,6 +73,7 @@ import org.testng.annotations.Test;
import com.google.inject.AbstractModule;
import com.google.inject.Module;
import com.google.inject.Provides;
import com.google.inject.TypeLiteral;
/**
@ -119,8 +120,8 @@ public class S3ClientTest extends RestClientTest<S3Client> {
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");
GeneratedHttpRequest<S3Client> httpMethod = processor.createRequest(method, "sourceBucket",
"sourceObject", "destinationBucket", "destinationObject");
assertRequestLineEquals(httpMethod,
"PUT http://destinationBucket.stub:8080/destinationObject HTTP/1.1");
@ -316,8 +317,8 @@ public class S3ClientTest extends RestClientTest<S3Client> {
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"));
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,
@ -368,15 +369,19 @@ public class S3ClientTest extends RestClientTest<S3Client> {
.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;
}
});
}
@SuppressWarnings("unused")
@Provides
@TimeStamp
String provide() {
return "timestamp";
}
};
}
}

View File

@ -26,9 +26,9 @@ package org.jclouds.aws.s3.config;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import org.jclouds.aws.s3.handlers.AWSClientErrorRetryHandler;
import org.jclouds.aws.s3.handlers.AWSRedirectionRetryHandler;
import org.jclouds.aws.s3.handlers.ParseAWSErrorFromXmlContent;
import org.jclouds.aws.handlers.AWSClientErrorRetryHandler;
import org.jclouds.aws.handlers.AWSRedirectionRetryHandler;
import org.jclouds.aws.handlers.ParseAWSErrorFromXmlContent;
import org.jclouds.aws.s3.reference.S3Constants;
import org.jclouds.concurrent.WithinThreadExecutorService;
import org.jclouds.concurrent.config.ExecutorServiceModule;

View File

@ -53,7 +53,7 @@ public class CopyObjectHandlerTest extends BaseHandlerTest {
}
public void testApplyInputStream() {
InputStream is = getClass().getResourceAsStream("/copy_object.xml");
InputStream is = getClass().getResourceAsStream("/s3/copy_object.xml");
ObjectMetadata expected = new CopyObjectResult(new DateService()
.iso8601DateParse("2009-03-19T13:23:27.000Z"), "\"92836a3ea45a6984d1b4d23a747d46bb\"");

View File

@ -60,7 +60,7 @@ public class ListBucketHandlerTest extends BaseHandlerTest {
}
public void testApplyInputStream() {
InputStream is = getClass().getResourceAsStream("/list_bucket.xml");
InputStream is = getClass().getResourceAsStream("/s3/list_bucket.xml");
CanonicalUser owner = new CanonicalUser(
"e1a5f66a480ca99a4fdfe8e318c3020446c9989d7004e7778029fbcc5d990fa0", "ferncam");
ListBucketResponse expected = new TreeSetListBucketResponse(

Some files were not shown because too many files have changed in this diff Show More