Repository: jclouds-labs-aws Updated Branches: refs/heads/master 913b8c5b3 -> 8d55706d2
JCLOUDS-457: Added list Multipart operations Added listParts and listMultipartUploads operations to the Glacier client. Project: http://git-wip-us.apache.org/repos/asf/jclouds-labs-aws/repo Commit: http://git-wip-us.apache.org/repos/asf/jclouds-labs-aws/commit/8d55706d Tree: http://git-wip-us.apache.org/repos/asf/jclouds-labs-aws/tree/8d55706d Diff: http://git-wip-us.apache.org/repos/asf/jclouds-labs-aws/diff/8d55706d Branch: refs/heads/master Commit: 8d55706d216cca6c99299a3600c7cf0e9e6cc7cc Parents: 913b8c5 Author: Roman C. Coedo <[email protected]> Authored: Sun Jun 1 23:03:29 2014 +0200 Committer: Andrew Gaul <[email protected]> Committed: Sun Jun 22 17:32:43 2014 -0700 ---------------------------------------------------------------------- .../org/jclouds/glacier/GlacierAsyncClient.java | 48 +++++++ .../java/org/jclouds/glacier/GlacierClient.java | 38 +++++ .../glacier/domain/MultipartUploadMetadata.java | 141 +++++++++++++++++++ .../PaginatedMultipartUploadCollection.java | 60 ++++++++ .../jclouds/glacier/domain/PartMetadata.java | 53 +++++++ ...ParseMultipartUploadListFromHttpContent.java | 35 +++++ ...eMultipartUploadPartListFromHttpContent.java | 35 +++++ .../jclouds/glacier/GlacierClientLiveTest.java | 47 ++++++- .../jclouds/glacier/GlacierClientMockTest.java | 58 ++++++++ .../json/listMultipartUploadsResponseBody.json | 12 ++ ...ltipartUploadsWithEmptyListResponseBody.json | 4 + .../resources/json/listPartsResponseBody.json | 13 ++ 12 files changed, 543 insertions(+), 1 deletion(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/jclouds-labs-aws/blob/8d55706d/glacier/src/main/java/org/jclouds/glacier/GlacierAsyncClient.java ---------------------------------------------------------------------- diff --git a/glacier/src/main/java/org/jclouds/glacier/GlacierAsyncClient.java b/glacier/src/main/java/org/jclouds/glacier/GlacierAsyncClient.java index e492b7c..7517f56 100644 --- a/glacier/src/main/java/org/jclouds/glacier/GlacierAsyncClient.java +++ b/glacier/src/main/java/org/jclouds/glacier/GlacierAsyncClient.java @@ -38,12 +38,16 @@ import org.jclouds.glacier.binders.BindDescriptionToHeaders; import org.jclouds.glacier.binders.BindHashesToHeaders; import org.jclouds.glacier.binders.BindMultipartTreeHashToHeaders; import org.jclouds.glacier.binders.BindPartSizeToHeaders; +import org.jclouds.glacier.domain.MultipartUploadMetadata; +import org.jclouds.glacier.domain.PaginatedMultipartUploadCollection; import org.jclouds.glacier.domain.PaginatedVaultCollection; import org.jclouds.glacier.domain.VaultMetadata; import org.jclouds.glacier.fallbacks.FalseOnIllegalArgumentException; import org.jclouds.glacier.filters.RequestAuthorizeSignature; import org.jclouds.glacier.functions.ParseArchiveIdHeader; import org.jclouds.glacier.functions.ParseMultipartUploadIdHeader; +import org.jclouds.glacier.functions.ParseMultipartUploadListFromHttpContent; +import org.jclouds.glacier.functions.ParseMultipartUploadPartListFromHttpContent; import org.jclouds.glacier.functions.ParseMultipartUploadTreeHashHeader; import org.jclouds.glacier.functions.ParseVaultMetadataFromHttpContent; import org.jclouds.glacier.functions.ParseVaultMetadataListFromHttpContent; @@ -214,4 +218,48 @@ public interface GlacierAsyncClient extends Closeable { ListenableFuture<Boolean> abortMultipartUpload( @ParamValidators(VaultNameValidator.class) @PathParam("vault") String vaultName, @PathParam("uploadId") String uploadId); + + /** + * @see GlacierClient#listParts + */ + @Named("ListParts") + @GET + @Path("/-/vaults/{vault}/multipart-uploads/{uploadId}") + @ResponseParser(ParseMultipartUploadPartListFromHttpContent.class) + ListenableFuture<MultipartUploadMetadata> listParts( + @ParamValidators(VaultNameValidator.class) @PathParam("vault") String vaultName, + @PathParam("uploadId") String uploadId, + PaginationOptions options); + + /** + * @see GlacierClient#listParts + */ + @Named("ListParts") + @GET + @Path("/-/vaults/{vault}/multipart-uploads/{uploadId}") + @ResponseParser(ParseMultipartUploadPartListFromHttpContent.class) + ListenableFuture<MultipartUploadMetadata> listParts( + @ParamValidators(VaultNameValidator.class) @PathParam("vault") String vaultName, + @PathParam("uploadId") String uploadId); + + /** + * @see GlacierClient#listMultipartUploads + */ + @Named("ListMultipartUploads") + @GET + @Path("/-/vaults/{vault}/multipart-uploads") + @ResponseParser(ParseMultipartUploadListFromHttpContent.class) + ListenableFuture<PaginatedMultipartUploadCollection> listMultipartUploads( + @ParamValidators(VaultNameValidator.class) @PathParam("vault") String vaultName, + PaginationOptions options); + + /** + * @see GlacierClient#listMultipartUploads + */ + @Named("ListMultipartUploads") + @GET + @Path("/-/vaults/{vault}/multipart-uploads") + @ResponseParser(ParseMultipartUploadListFromHttpContent.class) + ListenableFuture<PaginatedMultipartUploadCollection> listMultipartUploads( + @ParamValidators(VaultNameValidator.class) @PathParam("vault") String vaultName); } http://git-wip-us.apache.org/repos/asf/jclouds-labs-aws/blob/8d55706d/glacier/src/main/java/org/jclouds/glacier/GlacierClient.java ---------------------------------------------------------------------- diff --git a/glacier/src/main/java/org/jclouds/glacier/GlacierClient.java b/glacier/src/main/java/org/jclouds/glacier/GlacierClient.java index 29f743d..162ec91 100644 --- a/glacier/src/main/java/org/jclouds/glacier/GlacierClient.java +++ b/glacier/src/main/java/org/jclouds/glacier/GlacierClient.java @@ -20,6 +20,8 @@ import java.io.Closeable; import java.net.URI; import java.util.Map; +import org.jclouds.glacier.domain.MultipartUploadMetadata; +import org.jclouds.glacier.domain.PaginatedMultipartUploadCollection; import org.jclouds.glacier.domain.PaginatedVaultCollection; import org.jclouds.glacier.domain.VaultMetadata; import org.jclouds.glacier.options.PaginationOptions; @@ -180,4 +182,40 @@ public interface GlacierClient extends Closeable { * @see <a href="http://docs.aws.amazon.com/amazonglacier/latest/dev/api-multipart-abort-upload.html" /> */ boolean abortMultipartUpload(String vaultName, String uploadId); + + /** + * Lists the multipart upload parts. + * + * @param vaultName + * Name of the Vault where the archive is going to be stored. + * @param uploadId + * Multipart upload identifier. + * @param options + * Options used for pagination. + * @return A MultipartUploadMetadata, containing an iterable part list with a marker. + * @see <a href="http://docs.aws.amazon.com/amazonglacier/latest/dev/api-multipart-list-parts.html" /> + */ + MultipartUploadMetadata listParts(String vaultName, String uploadId, PaginationOptions options); + + /** + * Lists the multipart upload parts. + */ + MultipartUploadMetadata listParts(String vaultName, String uploadId); + + /** + * Lists the multipart uploads in a vault. + * + * @param vaultName + * Name of the Vault where the archive is going to be stored. + * @param options + * Options used for pagination. + * @return A PaginatedMultipartUploadCollection, containing an iterable multipart upload list with a marker. + * @see <a href="http://docs.aws.amazon.com/amazonglacier/latest/dev/api-multipart-list-uploads.html" /> + */ + PaginatedMultipartUploadCollection listMultipartUploads(String vaultName, PaginationOptions options); + + /** + * Lists the multipart uploads in a vault. + */ + PaginatedMultipartUploadCollection listMultipartUploads(String vaultName); } http://git-wip-us.apache.org/repos/asf/jclouds-labs-aws/blob/8d55706d/glacier/src/main/java/org/jclouds/glacier/domain/MultipartUploadMetadata.java ---------------------------------------------------------------------- diff --git a/glacier/src/main/java/org/jclouds/glacier/domain/MultipartUploadMetadata.java b/glacier/src/main/java/org/jclouds/glacier/domain/MultipartUploadMetadata.java new file mode 100644 index 0000000..1f68d07 --- /dev/null +++ b/glacier/src/main/java/org/jclouds/glacier/domain/MultipartUploadMetadata.java @@ -0,0 +1,141 @@ +/* + * 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.glacier.domain; + +import static com.google.common.base.Preconditions.checkNotNull; + +import java.beans.ConstructorProperties; +import java.util.Date; +import java.util.Iterator; + +import org.jclouds.collect.IterableWithMarker; +import org.jclouds.glacier.options.PaginationOptions; +import org.jclouds.javax.annotation.Nullable; + +import com.google.common.base.Objects; +import com.google.common.base.Optional; +import com.google.common.collect.ComparisonChain; +import com.google.gson.annotations.SerializedName; + +/** + * Defines the attributes needed for Multipart uploads. Extends IterableWithMarker to support requesting paginated + * multipart upload parts. + */ +public class MultipartUploadMetadata extends IterableWithMarker<PartMetadata> implements Comparable<MultipartUploadMetadata> { + + @SerializedName("ArchiveDescription") + private final String archiveDescription; + @SerializedName("CreationDate") + private final Date creationDate; + @SerializedName("MultipartUploadId") + private final String multipartUploadId; + @SerializedName("PartSizeInBytes") + private final long partSizeInBytes; + @SerializedName("VaultARN") + private final String vaultARN; + @SerializedName("Parts") + private final Iterable<PartMetadata> parts; + @SerializedName("Marker") + private final String marker; + + @ConstructorProperties({ "ArchiveDescription", "CreationDate", "MultipartUploadId", "PartSizeInBytes", "VaultARN", + "Parts", "Marker" }) + public MultipartUploadMetadata(@Nullable String archiveDescription, Date creationDate, String multipartUploadId, + long partSizeInBytes, String vaultARN, @Nullable Iterable<PartMetadata> parts, @Nullable String marker) { + super(); + this.archiveDescription = archiveDescription; + this.creationDate = (Date) checkNotNull(creationDate, "creationDate").clone(); + this.multipartUploadId = checkNotNull(multipartUploadId, "multipartUploadId"); + this.partSizeInBytes = partSizeInBytes; + this.vaultARN = checkNotNull(vaultARN, "vaultARN"); + this.parts = parts; + this.marker = marker; + } + + public String getArchiveDescription() { + return archiveDescription; + } + + public Date getCreationDate() { + return (Date) creationDate.clone(); + } + + public String getMultipartUploadId() { + return multipartUploadId; + } + + public long getPartSizeInBytes() { + return partSizeInBytes; + } + + public long getPartSizeInMB() { + return partSizeInBytes >> 20; + } + + public String getVaultARN() { + return vaultARN; + } + + @Override + public Iterator<PartMetadata> iterator() { + return parts == null ? null : parts.iterator(); + } + + @Override + public Optional<Object> nextMarker() { + return Optional.<Object>fromNullable(marker); + } + + public PaginationOptions nextPaginationOptions() { + return PaginationOptions.class.cast(nextMarker().get()); + } + + @Override + public int hashCode() { + return Objects.hashCode(this.archiveDescription, this.creationDate, this.multipartUploadId, this.partSizeInBytes, + this.vaultARN, this.marker, this.parts); + } + + @Override + public boolean equals(Object obj) { + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + MultipartUploadMetadata other = (MultipartUploadMetadata) obj; + + return Objects.equal(this.archiveDescription, other.archiveDescription) + && Objects.equal(this.creationDate, other.creationDate) + && Objects.equal(this.multipartUploadId, other.multipartUploadId) + && Objects.equal(this.partSizeInBytes, other.partSizeInBytes) + && Objects.equal(this.vaultARN, other.vaultARN) + && Objects.equal(this.marker, other.marker) + && Objects.equal(this.parts, other.parts); + } + + @Override + public String toString() { + return "MultipartUploadMetadata [archiveDescription=" + archiveDescription + ", creationDate=" + creationDate + + ", multipartUploadId=" + multipartUploadId + ", partSizeInBytes=" + partSizeInBytes + ", vaultARN=" + + vaultARN + ", marker=" + marker + ", parts=" + parts + "]"; + } + + @Override + public int compareTo(MultipartUploadMetadata o) { + return ComparisonChain.start().compare(this.creationDate, o.creationDate).result(); + } +} http://git-wip-us.apache.org/repos/asf/jclouds-labs-aws/blob/8d55706d/glacier/src/main/java/org/jclouds/glacier/domain/PaginatedMultipartUploadCollection.java ---------------------------------------------------------------------- diff --git a/glacier/src/main/java/org/jclouds/glacier/domain/PaginatedMultipartUploadCollection.java b/glacier/src/main/java/org/jclouds/glacier/domain/PaginatedMultipartUploadCollection.java new file mode 100644 index 0000000..9555e41 --- /dev/null +++ b/glacier/src/main/java/org/jclouds/glacier/domain/PaginatedMultipartUploadCollection.java @@ -0,0 +1,60 @@ +/* + * 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.glacier.domain; + +import static com.google.common.base.Preconditions.checkNotNull; + +import java.beans.ConstructorProperties; +import java.util.Iterator; + +import org.jclouds.collect.IterableWithMarker; +import org.jclouds.glacier.options.PaginationOptions; +import org.jclouds.javax.annotation.Nullable; + +import com.google.common.base.Optional; +import com.google.gson.annotations.SerializedName; + +/** + * Paginated collection used to store multipart upload lists. + */ +public class PaginatedMultipartUploadCollection extends IterableWithMarker<MultipartUploadMetadata> { + + @SerializedName("UploadsList") + private final Iterable<MultipartUploadMetadata> uploads; + @SerializedName("Marker") + private final String marker; + + @ConstructorProperties({ "UploadsList", "Marker" }) + public PaginatedMultipartUploadCollection(Iterable<MultipartUploadMetadata> uploads, @Nullable String marker) { + this.uploads = checkNotNull(uploads, "uploads"); + this.marker = marker; + } + + @Override + public Iterator<MultipartUploadMetadata> iterator() { + return uploads.iterator(); + } + + @Override + public Optional<Object> nextMarker() { + return Optional.<Object>fromNullable(marker); + } + + public PaginationOptions nextPaginationOptions() { + return PaginationOptions.class.cast(nextMarker().get()); + } +} http://git-wip-us.apache.org/repos/asf/jclouds-labs-aws/blob/8d55706d/glacier/src/main/java/org/jclouds/glacier/domain/PartMetadata.java ---------------------------------------------------------------------- diff --git a/glacier/src/main/java/org/jclouds/glacier/domain/PartMetadata.java b/glacier/src/main/java/org/jclouds/glacier/domain/PartMetadata.java new file mode 100644 index 0000000..3a08447 --- /dev/null +++ b/glacier/src/main/java/org/jclouds/glacier/domain/PartMetadata.java @@ -0,0 +1,53 @@ +/* + * 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.glacier.domain; + +import static com.google.common.base.Preconditions.checkNotNull; + +import java.beans.ConstructorProperties; + +import org.jclouds.glacier.util.ContentRange; + +import com.google.common.hash.HashCode; +import com.google.gson.annotations.SerializedName; + +/** + * Defines the attributes needed for a multipart upload part. + */ +public class PartMetadata { + + @SerializedName("SHA256TreeHash") + private final HashCode treeHash; + @SerializedName("RangeInBytes") + private final ContentRange range; + + @ConstructorProperties({ "SHA256TreeHash", "RangeInBytes" }) + public PartMetadata(String treeHash, String range) { + super(); + this.treeHash = HashCode.fromString(checkNotNull(treeHash, "treeHash")); + this.range = ContentRange.fromString(checkNotNull(range, "range")); + } + + public ContentRange getRange() { + return range; + } + + public HashCode getTreeHash() { + return treeHash; + } + +} http://git-wip-us.apache.org/repos/asf/jclouds-labs-aws/blob/8d55706d/glacier/src/main/java/org/jclouds/glacier/functions/ParseMultipartUploadListFromHttpContent.java ---------------------------------------------------------------------- diff --git a/glacier/src/main/java/org/jclouds/glacier/functions/ParseMultipartUploadListFromHttpContent.java b/glacier/src/main/java/org/jclouds/glacier/functions/ParseMultipartUploadListFromHttpContent.java new file mode 100644 index 0000000..c2b5c23 --- /dev/null +++ b/glacier/src/main/java/org/jclouds/glacier/functions/ParseMultipartUploadListFromHttpContent.java @@ -0,0 +1,35 @@ +/* + * 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.glacier.functions; + +import org.jclouds.glacier.domain.PaginatedMultipartUploadCollection; +import org.jclouds.http.functions.ParseJson; +import org.jclouds.json.Json; + +import com.google.inject.Inject; +import com.google.inject.TypeLiteral; + +/** + * Parses the JSON multipart upload list from the HttpResponse. + */ +public class ParseMultipartUploadListFromHttpContent extends ParseJson<PaginatedMultipartUploadCollection> { + + @Inject + public ParseMultipartUploadListFromHttpContent(Json json) { + super(json, TypeLiteral.get(PaginatedMultipartUploadCollection.class)); + } +} http://git-wip-us.apache.org/repos/asf/jclouds-labs-aws/blob/8d55706d/glacier/src/main/java/org/jclouds/glacier/functions/ParseMultipartUploadPartListFromHttpContent.java ---------------------------------------------------------------------- diff --git a/glacier/src/main/java/org/jclouds/glacier/functions/ParseMultipartUploadPartListFromHttpContent.java b/glacier/src/main/java/org/jclouds/glacier/functions/ParseMultipartUploadPartListFromHttpContent.java new file mode 100644 index 0000000..684ac7a --- /dev/null +++ b/glacier/src/main/java/org/jclouds/glacier/functions/ParseMultipartUploadPartListFromHttpContent.java @@ -0,0 +1,35 @@ +/* + * 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.glacier.functions; + +import org.jclouds.glacier.domain.MultipartUploadMetadata; +import org.jclouds.http.functions.ParseJson; +import org.jclouds.json.Json; + +import com.google.inject.Inject; +import com.google.inject.TypeLiteral; + +/** + * Parses the JSON multipart upload part list from the HttpResponse. + */ +public class ParseMultipartUploadPartListFromHttpContent extends ParseJson<MultipartUploadMetadata> { + + @Inject + public ParseMultipartUploadPartListFromHttpContent(Json json) { + super(json, TypeLiteral.get(MultipartUploadMetadata.class)); + } +} http://git-wip-us.apache.org/repos/asf/jclouds-labs-aws/blob/8d55706d/glacier/src/test/java/org/jclouds/glacier/GlacierClientLiveTest.java ---------------------------------------------------------------------- diff --git a/glacier/src/test/java/org/jclouds/glacier/GlacierClientLiveTest.java b/glacier/src/test/java/org/jclouds/glacier/GlacierClientLiveTest.java index 100d990..a5142b1 100644 --- a/glacier/src/test/java/org/jclouds/glacier/GlacierClientLiveTest.java +++ b/glacier/src/test/java/org/jclouds/glacier/GlacierClientLiveTest.java @@ -16,16 +16,25 @@ */ package org.jclouds.glacier; +import static org.jclouds.glacier.util.TestUtils.MiB; +import static org.jclouds.glacier.util.TestUtils.buildPayload; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNotNull; import static org.testng.Assert.assertNull; import static org.testng.Assert.assertTrue; import java.util.UUID; import org.jclouds.apis.BaseApiLiveTest; +import org.jclouds.glacier.domain.MultipartUploadMetadata; +import org.jclouds.glacier.domain.PaginatedMultipartUploadCollection; import org.jclouds.glacier.domain.PaginatedVaultCollection; import org.jclouds.glacier.domain.VaultMetadata; +import org.jclouds.glacier.util.ContentRange; import org.testng.annotations.Test; +import com.google.common.collect.ImmutableList; + /** * Live test for Glacier. */ @@ -68,7 +77,43 @@ public class GlacierClientLiveTest extends BaseApiLiveTest<GlacierClient>{ assertTrue(vaults.contains(api.describeVault(VAULT_NAME3))); } - @Test(groups = { "integration", "live" }, dependsOnMethods = { "testListAndDescribeVaults" }) + @Test(groups = { "integration", "live" }, dependsOnMethods = { "testCreateVault" }) + public void testListMultipartUploadsWithEmptyList() throws Exception { + assertEquals(api.listMultipartUploads(VAULT_NAME1).size(), 0); + } + + @Test(groups = { "integration", "live" }, dependsOnMethods = { "testListMultipartUploadsWithEmptyList" }) + public void testInitiateAndAbortMultipartUpload() throws Exception { + String uploadId = api.initiateMultipartUpload(VAULT_NAME1, 8); + try { + assertNotNull(uploadId); + } finally { + api.abortMultipartUpload(VAULT_NAME1, uploadId); + } + } + + @Test(groups = { "integration", "live" }, dependsOnMethods = { "testInitiateAndAbortMultipartUpload" }) + public void testListMultipartUploads() throws Exception { + long partSizeInMb = 1; + String uploadId = api.initiateMultipartUpload(VAULT_NAME1, partSizeInMb); + try { + assertNotNull(api.uploadPart(VAULT_NAME1, uploadId, + ContentRange.fromPartNumber(0, partSizeInMb), buildPayload(partSizeInMb * MiB))); + PaginatedMultipartUploadCollection uploads = api.listMultipartUploads(VAULT_NAME1); + ImmutableList.Builder<String> list = ImmutableList.builder(); + for (MultipartUploadMetadata upload : uploads) { + list.add(upload.getMultipartUploadId()); + } + assertTrue(list.build().contains(uploadId)); + assertTrue(api.abortMultipartUpload(VAULT_NAME1, uploadId)); + } finally { + api.abortMultipartUpload(VAULT_NAME1, uploadId); + } + } + + @Test(groups = { "integration", "live" }, + dependsOnMethods = { "testListAndDescribeVaults", "testListMultipartUploadsWithEmptyList", + "testInitiateAndAbortMultipartUpload", "testListMultipartUploads" }) public void testDeleteVault() throws Exception { assertTrue(api.deleteVault(VAULT_NAME1)); assertTrue(api.deleteVault(VAULT_NAME2)); http://git-wip-us.apache.org/repos/asf/jclouds-labs-aws/blob/8d55706d/glacier/src/test/java/org/jclouds/glacier/GlacierClientMockTest.java ---------------------------------------------------------------------- diff --git a/glacier/src/test/java/org/jclouds/glacier/GlacierClientMockTest.java b/glacier/src/test/java/org/jclouds/glacier/GlacierClientMockTest.java index 6932b25..d996bdf 100644 --- a/glacier/src/test/java/org/jclouds/glacier/GlacierClientMockTest.java +++ b/glacier/src/test/java/org/jclouds/glacier/GlacierClientMockTest.java @@ -37,7 +37,10 @@ import java.util.Set; import org.jclouds.ContextBuilder; import org.jclouds.concurrent.config.ExecutorServiceModule; +import org.jclouds.glacier.domain.MultipartUploadMetadata; +import org.jclouds.glacier.domain.PaginatedMultipartUploadCollection; import org.jclouds.glacier.domain.PaginatedVaultCollection; +import org.jclouds.glacier.domain.PartMetadata; import org.jclouds.glacier.domain.VaultMetadata; import org.jclouds.glacier.options.PaginationOptions; import org.jclouds.glacier.reference.GlacierHeaders; @@ -85,6 +88,7 @@ public class GlacierClientMockTest { private static final String DESCRIPTION = "test description"; private static final String MULTIPART_UPLOAD_LOCATION = VAULT_LOCATION + "/multipart-uploads/" + ARCHIVE_ID; private static final String MULTIPART_UPLOAD_ID = "OW2fM5iVylEpFEMM9_HpKowRapC3vn5sSL39_396UW9zLFUWVrnRHaPjUJddQ5OxSHVXjYtrN47NBZ-khxOjyEXAMPLE"; + private static final String MARKER = "xsQdFIRsfJr20CW2AbZBKpRZAFTZSJIMtL2hYf8mvp8dM0m4RUzlaqoEye6g3h3ecqB_zqwB7zLDMeSWhwo65re4C4Ev"; private static final Set<Module> modules = ImmutableSet.<Module> of(new ExecutorServiceModule(sameThreadExecutor(), sameThreadExecutor())); @@ -305,4 +309,58 @@ public class GlacierClientMockTest { assertEquals(server.takeRequest().getRequestLine(), "DELETE /-/vaults/" + VAULT_NAME + "/multipart-uploads/" + MULTIPART_UPLOAD_ID + " " + HTTP); } + + @Test + public void testListParts() throws IOException, InterruptedException { + MockResponse mr = buildBaseResponse(200); + mr.addHeader(HttpHeaders.CONTENT_TYPE, MediaType.JSON_UTF_8); + mr.setBody(getResponseBody("/json/listPartsResponseBody.json")); + mr.addHeader(HttpHeaders.CONTENT_LENGTH, mr.getBody().length); + server.enqueue(mr); + + MultipartUploadMetadata result = client.listParts(VAULT_NAME, MULTIPART_UPLOAD_ID, + PaginationOptions.Builder.limit(1).marker("1001")); + assertEquals(result.getArchiveDescription(), "archive description 1"); + assertEquals(result.getMultipartUploadId(), MULTIPART_UPLOAD_ID); + assertEquals(result.getPartSizeInBytes(), 4194304); + PartMetadata part = result.iterator().next(); + assertEquals(part.getTreeHash(), HashCode.fromString("01d34dabf7be316472c93b1ef80721f5d4")); + assertEquals("4194304-8388607", part.getRange().getFrom() + "-" + part.getRange().getTo()); + assertEquals(server.takeRequest().getRequestLine(), + "GET /-/vaults/examplevault/multipart-uploads/" + MULTIPART_UPLOAD_ID + "?limit=1&marker=1001 " + HTTP); + } + + @Test + public void testListMultipartUploads() throws IOException, InterruptedException { + MockResponse mr = buildBaseResponse(200); + mr.addHeader(HttpHeaders.CONTENT_TYPE, MediaType.JSON_UTF_8); + mr.setBody(getResponseBody("/json/listMultipartUploadsResponseBody.json")); + mr.addHeader(HttpHeaders.CONTENT_LENGTH, mr.getBody().length); + server.enqueue(mr); + + PaginatedMultipartUploadCollection result = client.listMultipartUploads( + VAULT_NAME, PaginationOptions.Builder.limit(1).marker(MARKER)); + MultipartUploadMetadata mum = result.iterator().next(); + assertEquals(mum.getArchiveDescription(), "archive 2"); + assertEquals(mum.getMultipartUploadId(), + "nPyGOnyFcx67qqX7E-0tSGiRi88hHMOwOxR-_jNyM6RjVMFfV29lFqZ3rNsSaWBugg6OP92pRtufeHdQH7ClIpSF6uJc"); + assertEquals(mum.iterator(), null); + assertEquals(mum.getPartSizeInBytes(), 4194304); + assertEquals(mum.getVaultARN(), VAULT_ARN); + assertEquals(server.takeRequest().getRequestLine(), + "GET /-/vaults/examplevault/multipart-uploads?limit=1&marker=" + MARKER + " " + HTTP); + } + + @Test + public void testListMultipartUploadsWithEmptyList() throws IOException, InterruptedException { + MockResponse mr = buildBaseResponse(200); + mr.addHeader(HttpHeaders.CONTENT_TYPE, MediaType.JSON_UTF_8); + mr.setBody(getResponseBody("/json/listMultipartUploadsWithEmptyListResponseBody.json")); + mr.addHeader(HttpHeaders.CONTENT_LENGTH, mr.getBody().length); + server.enqueue(mr); + + assertEquals(client.listMultipartUploads(VAULT_NAME, PaginationOptions.Builder.limit(1).marker(MARKER)).size(), 0); + assertEquals(server.takeRequest().getRequestLine(), + "GET /-/vaults/examplevault/multipart-uploads?limit=1&marker=" + MARKER + " " + HTTP); + } } http://git-wip-us.apache.org/repos/asf/jclouds-labs-aws/blob/8d55706d/glacier/src/test/resources/json/listMultipartUploadsResponseBody.json ---------------------------------------------------------------------- diff --git a/glacier/src/test/resources/json/listMultipartUploadsResponseBody.json b/glacier/src/test/resources/json/listMultipartUploadsResponseBody.json new file mode 100644 index 0000000..1524578 --- /dev/null +++ b/glacier/src/test/resources/json/listMultipartUploadsResponseBody.json @@ -0,0 +1,12 @@ +{ + "Marker": "qt-RBst_7yO8gVIonIBsAxr2t-db0pE4s8MNeGjKjGdNpuU-cdSAcqG62guwV9r5jh5mLyFPzFEitTpNE7iQfHiu1XoV", + "UploadsList" : [ + { + "ArchiveDescription": "archive 2", + "CreationDate": "2012-04-01T15:00:00.000Z", + "MultipartUploadId": "nPyGOnyFcx67qqX7E-0tSGiRi88hHMOwOxR-_jNyM6RjVMFfV29lFqZ3rNsSaWBugg6OP92pRtufeHdQH7ClIpSF6uJc", + "PartSizeInBytes": 4194304, + "VaultARN": "arn:aws:glacier:us-east-1:012345678901:vaults/examplevault" + } + ] +} http://git-wip-us.apache.org/repos/asf/jclouds-labs-aws/blob/8d55706d/glacier/src/test/resources/json/listMultipartUploadsWithEmptyListResponseBody.json ---------------------------------------------------------------------- diff --git a/glacier/src/test/resources/json/listMultipartUploadsWithEmptyListResponseBody.json b/glacier/src/test/resources/json/listMultipartUploadsWithEmptyListResponseBody.json new file mode 100644 index 0000000..0e98a77 --- /dev/null +++ b/glacier/src/test/resources/json/listMultipartUploadsWithEmptyListResponseBody.json @@ -0,0 +1,4 @@ +{ + "Marker": "qt-RBst_7yO8gVIonIBsAxr2t-db0pE4s8MNeGjKjGdNpuU-cdSAcqG62guwV9r5jh5mLyFPzFEitTpNE7iQfHiu1XoV", + "UploadsList" : [] +} http://git-wip-us.apache.org/repos/asf/jclouds-labs-aws/blob/8d55706d/glacier/src/test/resources/json/listPartsResponseBody.json ---------------------------------------------------------------------- diff --git a/glacier/src/test/resources/json/listPartsResponseBody.json b/glacier/src/test/resources/json/listPartsResponseBody.json new file mode 100644 index 0000000..cab3b85 --- /dev/null +++ b/glacier/src/test/resources/json/listPartsResponseBody.json @@ -0,0 +1,13 @@ +{ + "ArchiveDescription" : "archive description 1", + "CreationDate" : "2012-03-20T17:03:43.221Z", + "Marker": "MfgsKHVjbQ6EldVl72bn3_n5h2TaGZQUO-Qb3B9j3TITf7WajQ", + "MultipartUploadId" : "OW2fM5iVylEpFEMM9_HpKowRapC3vn5sSL39_396UW9zLFUWVrnRHaPjUJddQ5OxSHVXjYtrN47NBZ-khxOjyEXAMPLE", + "PartSizeInBytes" : 4194304, + "Parts" : + [ { + "RangeInBytes" : "4194304-8388607", + "SHA256TreeHash" : "01d34dabf7be316472c93b1ef80721f5d4" + }], + "VaultARN" : "arn:aws:glacier:us-east-1:012345678901:vaults/demo1-vault" +}
