mirror of https://github.com/apache/jclouds.git
finished copyobject tests
git-svn-id: http://jclouds.googlecode.com/svn/trunk@573 3d8758e0-26b5-11de-8745-db77d3ebf521
This commit is contained in:
parent
d419c8eec3
commit
a6b80c7beb
|
@ -28,6 +28,12 @@ import java.util.Collection;
|
||||||
import com.google.common.collect.HashMultimap;
|
import com.google.common.collect.HashMultimap;
|
||||||
import com.google.common.collect.Multimap;
|
import com.google.common.collect.Multimap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides base functionality of HTTP requests and responses.
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*
|
||||||
|
*/
|
||||||
public class HttpMessage {
|
public class HttpMessage {
|
||||||
|
|
||||||
protected Multimap<String, String> headers = HashMultimap.create();
|
protected Multimap<String, String> headers = HashMultimap.create();
|
||||||
|
|
|
@ -235,8 +235,10 @@ public class CopyObjectOptions extends BaseHttpRequestOptions {
|
||||||
public Multimap<String, String> buildRequestHeaders() {
|
public Multimap<String, String> buildRequestHeaders() {
|
||||||
Multimap<String, String> returnVal = HashMultimap.create();
|
Multimap<String, String> returnVal = HashMultimap.create();
|
||||||
returnVal.putAll(headers);
|
returnVal.putAll(headers);
|
||||||
if (metadata != null)
|
if (metadata != null) {
|
||||||
returnVal.putAll(metadata);
|
returnVal.putAll(metadata);
|
||||||
|
returnVal.put("x-amz-metadata-directive", "REPLACE");
|
||||||
|
}
|
||||||
return returnVal;
|
return returnVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -250,7 +252,6 @@ public class CopyObjectOptions extends BaseHttpRequestOptions {
|
||||||
checkArgument(header.startsWith("x-amz-meta-"),
|
checkArgument(header.startsWith("x-amz-meta-"),
|
||||||
"Metadata keys must start with x-amz-meta-");
|
"Metadata keys must start with x-amz-meta-");
|
||||||
}
|
}
|
||||||
metadata.put("x-amz-copy-source-if-unmodified-since", "REPLACE");
|
|
||||||
this.metadata = metadata;
|
this.metadata = metadata;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,8 @@
|
||||||
package org.jclouds.aws.s3.filters;
|
package org.jclouds.aws.s3.filters;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.TreeSet;
|
||||||
import java.util.concurrent.atomic.AtomicLong;
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
|
||||||
|
@ -130,11 +132,12 @@ public class RequestAuthorizeSignature implements HttpRequestFilter {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void appendAmzHeaders(HttpRequest request, StringBuilder toSign) {
|
private void appendAmzHeaders(HttpRequest request, StringBuilder toSign) {
|
||||||
for (String header : request.getHeaders().keySet()) {
|
Set<String> headers = new TreeSet<String>(request.getHeaders().keySet());
|
||||||
|
for (String header : headers) {
|
||||||
if (header.startsWith("x-amz-")) {
|
if (header.startsWith("x-amz-")) {
|
||||||
toSign.append(header).append(":");
|
toSign.append(header).append(":");
|
||||||
for (String value : request.getHeaders().get(header))
|
for (String value : request.getHeaders().get(header))
|
||||||
toSign.append(value.replaceAll("\r?\n", " ")).append(",");
|
toSign.append(value.replaceAll("\r?\n", "")).append(",");
|
||||||
toSign.deleteCharAt(toSign.lastIndexOf(","));
|
toSign.deleteCharAt(toSign.lastIndexOf(","));
|
||||||
toSign.append("\n");
|
toSign.append("\n");
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,14 +23,29 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.aws.s3.commands;
|
package org.jclouds.aws.s3.commands;
|
||||||
|
|
||||||
|
import static org.jclouds.aws.s3.commands.options.CopyObjectOptions.Builder.ifSourceMd5DoesntMatch;
|
||||||
|
import static org.jclouds.aws.s3.commands.options.CopyObjectOptions.Builder.ifSourceMd5Matches;
|
||||||
|
import static org.jclouds.aws.s3.commands.options.CopyObjectOptions.Builder.ifSourceModifiedSince;
|
||||||
|
import static org.jclouds.aws.s3.commands.options.CopyObjectOptions.Builder.ifSourceUnmodifiedSince;
|
||||||
|
import static org.jclouds.aws.s3.commands.options.CopyObjectOptions.Builder.overrideMetadataWith;
|
||||||
|
import static org.testng.Assert.assertEquals;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.TimeoutException;
|
import java.util.concurrent.TimeoutException;
|
||||||
|
|
||||||
|
import org.jclouds.aws.s3.S3Headers;
|
||||||
import org.jclouds.aws.s3.S3IntegrationTest;
|
import org.jclouds.aws.s3.S3IntegrationTest;
|
||||||
|
import org.jclouds.aws.s3.S3ResponseException;
|
||||||
|
import org.jclouds.aws.s3.S3Utils;
|
||||||
|
import org.jclouds.aws.s3.domain.S3Object;
|
||||||
|
import org.joda.time.DateTime;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import com.google.common.collect.HashMultimap;
|
||||||
|
import com.google.common.collect.Multimap;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests integrated functionality of all copyObject commands.
|
* Tests integrated functionality of all copyObject commands.
|
||||||
* <p/>
|
* <p/>
|
||||||
|
@ -64,33 +79,158 @@ public class CopyObjectIntegrationTest extends S3IntegrationTest {
|
||||||
throws InterruptedException, ExecutionException, TimeoutException,
|
throws InterruptedException, ExecutionException, TimeoutException,
|
||||||
IOException {
|
IOException {
|
||||||
createBucketAndEnsureEmpty(sourceBucket);
|
createBucketAndEnsureEmpty(sourceBucket);
|
||||||
|
addToBucketAndValidate(sourceBucket, sourceKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addToBucketAndValidate(String sourceBucket, String sourceKey)
|
||||||
|
throws InterruptedException, ExecutionException, TimeoutException,
|
||||||
|
IOException {
|
||||||
addObjectToBucket(sourceBucket, sourceKey);
|
addObjectToBucket(sourceBucket, sourceKey);
|
||||||
validateContent(sourceBucket, sourceKey);
|
validateContent(sourceBucket, sourceKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testCopyIfModifiedSince() {
|
void testCopyIfModifiedSince() throws InterruptedException,
|
||||||
// TODO
|
ExecutionException, TimeoutException, IOException {
|
||||||
|
String sourceBucket = bucketPrefix + "testCopyIfModifiedSince";
|
||||||
|
String sourceKey = "apples";
|
||||||
|
String destinationBucket = bucketPrefix
|
||||||
|
+ "testCopyIfModifiedSinceDestination";
|
||||||
|
String destinationKey = "pears";
|
||||||
|
|
||||||
|
DateTime before = new DateTime();
|
||||||
|
setupSourceBucket(sourceBucket, sourceKey);
|
||||||
|
DateTime after = new DateTime().plusSeconds(1);
|
||||||
|
|
||||||
|
createBucketAndEnsureEmpty(destinationBucket);
|
||||||
|
client.copyObject(sourceBucket, sourceKey, destinationBucket,
|
||||||
|
destinationKey, ifSourceModifiedSince(before)).get(10,
|
||||||
|
TimeUnit.SECONDS);
|
||||||
|
validateContent(destinationBucket, destinationKey);
|
||||||
|
|
||||||
|
try {
|
||||||
|
client.copyObject(sourceBucket, sourceKey, destinationBucket,
|
||||||
|
destinationKey, ifSourceModifiedSince(after)).get(10,
|
||||||
|
TimeUnit.SECONDS);
|
||||||
|
} catch (ExecutionException e) {
|
||||||
|
S3ResponseException ex = (S3ResponseException) e.getCause();
|
||||||
|
assertEquals(ex.getResponse().getStatusCode(), 412);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testCopyIfUnmodifiedSince() {
|
void testCopyIfUnmodifiedSince() throws InterruptedException,
|
||||||
// TODO
|
ExecutionException, TimeoutException, IOException {
|
||||||
|
String sourceBucket = bucketPrefix + "testCopyIfUnmodifiedSince";
|
||||||
|
String sourceKey = "apples";
|
||||||
|
String destinationBucket = bucketPrefix
|
||||||
|
+ "testCopyIfUnmodifiedSinceDestination";
|
||||||
|
String destinationKey = "pears";
|
||||||
|
|
||||||
|
DateTime before = new DateTime();
|
||||||
|
setupSourceBucket(sourceBucket, sourceKey);
|
||||||
|
DateTime after = new DateTime().plusSeconds(1);
|
||||||
|
|
||||||
|
createBucketAndEnsureEmpty(destinationBucket);
|
||||||
|
client.copyObject(sourceBucket, sourceKey, destinationBucket,
|
||||||
|
destinationKey, ifSourceUnmodifiedSince(after)).get(10,
|
||||||
|
TimeUnit.SECONDS);
|
||||||
|
validateContent(destinationBucket, destinationKey);
|
||||||
|
|
||||||
|
try {
|
||||||
|
client.copyObject(sourceBucket, sourceKey, destinationBucket,
|
||||||
|
destinationKey, ifSourceModifiedSince(before)).get(10,
|
||||||
|
TimeUnit.SECONDS);
|
||||||
|
} catch (ExecutionException e) {
|
||||||
|
S3ResponseException ex = (S3ResponseException) e.getCause();
|
||||||
|
assertEquals(ex.getResponse().getStatusCode(), 412);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testCopyIfMatch() {
|
void testCopyIfMatch() throws InterruptedException, ExecutionException,
|
||||||
// TODO
|
TimeoutException, IOException {
|
||||||
|
String sourceBucket = bucketPrefix + "testCopyIfMatch";
|
||||||
|
String sourceKey = "apples";
|
||||||
|
byte[] realMd5 = S3Utils.md5(TEST_STRING);
|
||||||
|
byte[] badMd5 = S3Utils.md5("alf");
|
||||||
|
|
||||||
|
String destinationBucket = bucketPrefix + "testCopyIfMatchDestination";
|
||||||
|
String destinationKey = "pears";
|
||||||
|
|
||||||
|
setupSourceBucket(sourceBucket, sourceKey);
|
||||||
|
|
||||||
|
createBucketAndEnsureEmpty(destinationBucket);
|
||||||
|
client.copyObject(sourceBucket, sourceKey, destinationBucket,
|
||||||
|
destinationKey, ifSourceMd5Matches(realMd5)).get(10,
|
||||||
|
TimeUnit.SECONDS);
|
||||||
|
validateContent(destinationBucket, destinationKey);
|
||||||
|
|
||||||
|
try {
|
||||||
|
client.copyObject(sourceBucket, sourceKey, destinationBucket,
|
||||||
|
destinationKey, ifSourceMd5Matches(badMd5)).get(10,
|
||||||
|
TimeUnit.SECONDS);
|
||||||
|
} catch (ExecutionException e) {
|
||||||
|
S3ResponseException ex = (S3ResponseException) e.getCause();
|
||||||
|
assertEquals(ex.getResponse().getStatusCode(), 412);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testCopyIfNoneMatch() {
|
void testCopyIfNoneMatch() throws IOException, InterruptedException,
|
||||||
// TODO
|
ExecutionException, TimeoutException {
|
||||||
|
String sourceBucket = bucketPrefix + "testCopyIfNoneMatch";
|
||||||
|
String sourceKey = "apples";
|
||||||
|
byte[] realMd5 = S3Utils.md5(TEST_STRING);
|
||||||
|
byte[] badMd5 = S3Utils.md5("alf");
|
||||||
|
|
||||||
|
String destinationBucket = bucketPrefix
|
||||||
|
+ "testCopyIfNoneMatchDestination";
|
||||||
|
String destinationKey = "pears";
|
||||||
|
|
||||||
|
setupSourceBucket(sourceBucket, sourceKey);
|
||||||
|
|
||||||
|
createBucketAndEnsureEmpty(destinationBucket);
|
||||||
|
client.copyObject(sourceBucket, sourceKey, destinationBucket,
|
||||||
|
destinationKey, ifSourceMd5DoesntMatch(badMd5)).get(10,
|
||||||
|
TimeUnit.SECONDS);
|
||||||
|
validateContent(destinationBucket, destinationKey);
|
||||||
|
|
||||||
|
try {
|
||||||
|
client.copyObject(sourceBucket, sourceKey, destinationBucket,
|
||||||
|
destinationKey, ifSourceMd5DoesntMatch(realMd5)).get(10,
|
||||||
|
TimeUnit.SECONDS);
|
||||||
|
} catch (ExecutionException e) {
|
||||||
|
S3ResponseException ex = (S3ResponseException) e.getCause();
|
||||||
|
assertEquals(ex.getResponse().getStatusCode(), 412);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testCopyWithMetadata() {
|
void testCopyWithMetadata() throws InterruptedException,
|
||||||
|
ExecutionException, TimeoutException, IOException {
|
||||||
|
String sourceBucket = bucketPrefix + "testCopyWithMetadata";
|
||||||
|
String sourceKey = "apples";
|
||||||
|
String destinationBucket = bucketPrefix
|
||||||
|
+ "testCopyWithMetadataDestination";
|
||||||
|
String destinationKey = "pears";
|
||||||
|
|
||||||
|
setupSourceBucket(sourceBucket, sourceKey);
|
||||||
|
|
||||||
|
Multimap<String, String> metadata = HashMultimap.create();
|
||||||
|
metadata.put(S3Headers.USER_METADATA_PREFIX + "adrian", "cole");
|
||||||
|
|
||||||
|
createBucketAndEnsureEmpty(destinationBucket);
|
||||||
|
client.copyObject(sourceBucket, sourceKey, destinationBucket,
|
||||||
|
destinationKey, overrideMetadataWith(metadata)).get(10,
|
||||||
|
TimeUnit.SECONDS);
|
||||||
|
|
||||||
|
validateContent(destinationBucket, destinationKey);
|
||||||
|
|
||||||
|
S3Object.Metadata objectMeta = client.headObject(destinationBucket,
|
||||||
|
destinationKey).get(10, TimeUnit.SECONDS);
|
||||||
|
|
||||||
|
assertEquals(objectMeta.getUserMetadata(), metadata);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -0,0 +1,124 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright (C) 2009 Adrian Cole <adrian@jclouds.org>
|
||||||
|
*
|
||||||
|
* ====================================================================
|
||||||
|
* 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 static org.testng.Assert.assertEquals;
|
||||||
|
|
||||||
|
import org.jclouds.aws.s3.S3Constants;
|
||||||
|
import org.jclouds.aws.s3.filters.ParseS3ErrorFromXmlContent;
|
||||||
|
import org.jclouds.http.HttpResponseHandler;
|
||||||
|
import org.jclouds.http.annotation.ClientErrorHandler;
|
||||||
|
import org.jclouds.http.annotation.RedirectHandler;
|
||||||
|
import org.jclouds.http.annotation.ServerErrorHandler;
|
||||||
|
import org.jclouds.http.config.JavaUrlHttpFutureCommandClientModule;
|
||||||
|
import org.testng.annotations.AfterMethod;
|
||||||
|
import org.testng.annotations.BeforeMethod;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import com.google.inject.Guice;
|
||||||
|
import com.google.inject.Inject;
|
||||||
|
import com.google.inject.Injector;
|
||||||
|
import com.google.inject.name.Names;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public class S3ContextModuleTest {
|
||||||
|
|
||||||
|
Injector injector = null;
|
||||||
|
|
||||||
|
@BeforeMethod
|
||||||
|
void setUpInjector() {
|
||||||
|
injector = Guice.createInjector(new S3ContextModule() {
|
||||||
|
@Override
|
||||||
|
protected void configure() {
|
||||||
|
bindConstant().annotatedWith(
|
||||||
|
Names.named(S3Constants.PROPERTY_AWS_ACCESSKEYID)).to(
|
||||||
|
"localhost");
|
||||||
|
bindConstant().annotatedWith(
|
||||||
|
Names.named(S3Constants.PROPERTY_AWS_SECRETACCESSKEY))
|
||||||
|
.to("localhost");
|
||||||
|
bindConstant().annotatedWith(
|
||||||
|
Names.named(S3Constants.PROPERTY_HTTP_ADDRESS)).to(
|
||||||
|
"localhost");
|
||||||
|
bindConstant().annotatedWith(
|
||||||
|
Names.named(S3Constants.PROPERTY_HTTP_PORT)).to("1000");
|
||||||
|
bindConstant().annotatedWith(
|
||||||
|
Names.named(S3Constants.PROPERTY_HTTP_SECURE)).to(
|
||||||
|
"false");
|
||||||
|
super.configure();
|
||||||
|
}
|
||||||
|
}, new JavaUrlHttpFutureCommandClientModule());
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterMethod
|
||||||
|
void tearDownInjector() {
|
||||||
|
injector = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class ClientErrorHandlerTest {
|
||||||
|
@Inject
|
||||||
|
@ClientErrorHandler
|
||||||
|
HttpResponseHandler errorHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testClientErrorHandler() {
|
||||||
|
ClientErrorHandlerTest error = injector
|
||||||
|
.getInstance(ClientErrorHandlerTest.class);
|
||||||
|
assertEquals(error.errorHandler.getClass(),
|
||||||
|
ParseS3ErrorFromXmlContent.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class ServerErrorHandlerTest {
|
||||||
|
@Inject
|
||||||
|
@ServerErrorHandler
|
||||||
|
HttpResponseHandler errorHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testServerErrorHandler() {
|
||||||
|
ServerErrorHandlerTest error = injector
|
||||||
|
.getInstance(ServerErrorHandlerTest.class);
|
||||||
|
assertEquals(error.errorHandler.getClass(),
|
||||||
|
ParseS3ErrorFromXmlContent.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class RedirectHandlerTest {
|
||||||
|
@Inject
|
||||||
|
@RedirectHandler
|
||||||
|
HttpResponseHandler errorHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testRedirectHandler() {
|
||||||
|
RedirectHandlerTest error = injector
|
||||||
|
.getInstance(RedirectHandlerTest.class);
|
||||||
|
assertEquals(error.errorHandler.getClass(),
|
||||||
|
ParseS3ErrorFromXmlContent.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue