Repository: jclouds Updated Branches: refs/heads/master 0c1de23a9 -> 4829bbbd2
JCLOUDS-964: S3 multipart copy Project: http://git-wip-us.apache.org/repos/asf/jclouds/repo Commit: http://git-wip-us.apache.org/repos/asf/jclouds/commit/4829bbbd Tree: http://git-wip-us.apache.org/repos/asf/jclouds/tree/4829bbbd Diff: http://git-wip-us.apache.org/repos/asf/jclouds/diff/4829bbbd Branch: refs/heads/master Commit: 4829bbbd2c7f6c7b25c1794eeacc16e9c710929a Parents: 0c1de23 Author: Andrew Gaul <[email protected]> Authored: Wed Oct 14 21:38:32 2015 -0700 Committer: Andrew Gaul <[email protected]> Committed: Wed Oct 14 23:17:40 2015 -0700 ---------------------------------------------------------------------- .../src/main/java/org/jclouds/s3/S3Client.java | 12 ++++++++++ .../java/org/jclouds/s3/S3ClientLiveTest.java | 25 ++++++++++++++++++++ .../test/java/org/jclouds/s3/S3ClientTest.java | 19 +++++++++++++++ 3 files changed, 56 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/jclouds/blob/4829bbbd/apis/s3/src/main/java/org/jclouds/s3/S3Client.java ---------------------------------------------------------------------- diff --git a/apis/s3/src/main/java/org/jclouds/s3/S3Client.java b/apis/s3/src/main/java/org/jclouds/s3/S3Client.java index 442cf1b..126b353 100644 --- a/apis/s3/src/main/java/org/jclouds/s3/S3Client.java +++ b/apis/s3/src/main/java/org/jclouds/s3/S3Client.java @@ -678,6 +678,18 @@ public interface S3Client extends Closeable { @PathParam("key") String key, @QueryParam("partNumber") int partNumber, @QueryParam("uploadId") String uploadId, Payload part); + @Named("UploadPartCopy") + @PUT + @Path("/{key}") + @Headers(keys = {"x-amz-copy-source", "x-amz-copy-source-range"}, values = {"/{sourceBucket}/{sourceObject}", "bytes={startOffset}-{endOffset}"}) + @ResponseParser(ETagFromHttpResponseViaRegex.class) + String uploadPartCopy(@Bucket @EndpointParam(parser = AssignCorrectHostnameForBucket.class) @BinderParam( + BindAsHostPrefixIfConfigured.class) @ParamValidators(BucketNameValidator.class) String bucketName, + @PathParam("key") String key, @QueryParam("partNumber") int partNumber, + @QueryParam("uploadId") String uploadId, + @PathParam("sourceBucket") String sourceBucket, @PathParam("sourceObject") String sourceObject, + @PathParam("startOffset") long startOffset, @PathParam("endOffset") long endOffset); + /** * This operation completes a multipart upload by assembling previously uploaded parts. http://git-wip-us.apache.org/repos/asf/jclouds/blob/4829bbbd/apis/s3/src/test/java/org/jclouds/s3/S3ClientLiveTest.java ---------------------------------------------------------------------- diff --git a/apis/s3/src/test/java/org/jclouds/s3/S3ClientLiveTest.java b/apis/s3/src/test/java/org/jclouds/s3/S3ClientLiveTest.java index 0561226..79c2f6b 100644 --- a/apis/s3/src/test/java/org/jclouds/s3/S3ClientLiveTest.java +++ b/apis/s3/src/test/java/org/jclouds/s3/S3ClientLiveTest.java @@ -551,6 +551,31 @@ public class S3ClientLiveTest extends BaseBlobStoreIntegrationTest { } } + public void testMultipartCopy() throws Exception { + String containerName = getContainerName(); + try { + String fromObject = "fromObject"; + S3Object object = getApi().newS3Object(); + object.getMetadata().setKey(fromObject); + object.setPayload(oneHundredOneConstitutions); + object.getMetadata().getContentMetadata().setContentLength(oneHundredOneConstitutions.size()); + getApi().putObject(containerName, object); + + String toObject = "toObject"; + String uploadId = getApi().initiateMultipartUpload(containerName, ObjectMetadataBuilder.create().key(toObject).build()); + + String eTagOf1 = getApi().uploadPartCopy(containerName, toObject, 1, uploadId, containerName, fromObject, 1, oneHundredOneConstitutions.size() - 1); + + String eTag = getApi().completeMultipartUpload(containerName, toObject, uploadId, ImmutableMap.of(1, eTagOf1)); + assertThat(eTag).isNotEqualTo(eTagOf1); + + object = getApi().getObject(containerName, toObject); + assertEquals(ByteStreams2.toByteArrayAndClose(object.getPayload().openStream()), oneHundredOneConstitutions.slice(1, oneHundredOneConstitutions.size() - 1).read()); + } finally { + returnContainer(containerName); + } + } + public void testDeleteMultipleObjects() throws InterruptedException { String container = getContainerName(); try { http://git-wip-us.apache.org/repos/asf/jclouds/blob/4829bbbd/apis/s3/src/test/java/org/jclouds/s3/S3ClientTest.java ---------------------------------------------------------------------- diff --git a/apis/s3/src/test/java/org/jclouds/s3/S3ClientTest.java b/apis/s3/src/test/java/org/jclouds/s3/S3ClientTest.java index 4432efc..8cfa53c 100644 --- a/apis/s3/src/test/java/org/jclouds/s3/S3ClientTest.java +++ b/apis/s3/src/test/java/org/jclouds/s3/S3ClientTest.java @@ -550,6 +550,25 @@ public abstract class S3ClientTest<T extends S3Client> extends BaseS3ClientTest< checkFilters(request); } + public void testUploadPartCopy() throws SecurityException, NegativeArraySizeException, NoSuchMethodException { + Invokable<?, ?> method = method(S3Client.class, "uploadPartCopy", String.class, String.class, int.class, + String.class, String.class, String.class, long.class, long.class); + GeneratedHttpRequest request = processor.createRequest(method, ImmutableList.<Object> of("bucket", "foo", 1, "asdsadasdas", + "anotherBucket", "anotherObject", 2, 10 * 1024 * 1024)); + + assertRequestLineEquals(request, "PUT https://bucket." + url + "/foo?partNumber=1&uploadId=asdsadasdas HTTP/1.1"); + assertNonPayloadHeadersEqual(request, "Host: bucket." + url + "\n" + + "x-amz-copy-source: /anotherBucket/anotherObject\n" + + "x-amz-copy-source-range: bytes=2-10485760\n"); + assertPayloadEquals(request, null, "application/unknown", false); + + assertResponseParserClassEquals(method, request, ETagFromHttpResponseViaRegex.class); + assertSaxResponseParserClassEquals(method, null); + assertFallbackClassEquals(method, MapHttp4xxCodesToExceptions.class); + + checkFilters(request); + } + public void testCompleteMultipartUpload() throws SecurityException, NegativeArraySizeException, NoSuchMethodException { Invokable<?, ?> method = method(S3Client.class, "completeMultipartUpload", String.class, String.class,
