You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jclouds.apache.org by ga...@apache.org on 2015/05/01 22:36:42 UTC
[9/9] jclouds git commit: JCLOUDS-894: Expose Swift multipart
operations
JCLOUDS-894: Expose Swift multipart operations
Project: http://git-wip-us.apache.org/repos/asf/jclouds/repo
Commit: http://git-wip-us.apache.org/repos/asf/jclouds/commit/deeebe46
Tree: http://git-wip-us.apache.org/repos/asf/jclouds/tree/deeebe46
Diff: http://git-wip-us.apache.org/repos/asf/jclouds/diff/deeebe46
Branch: refs/heads/master
Commit: deeebe46f75dc223b0fe1e217979e4beaf42f2cf
Parents: 9128ae5
Author: Andrew Gaul <ga...@apache.org>
Authored: Sat Apr 25 11:21:09 2015 -0700
Committer: Andrew Gaul <ga...@apache.org>
Committed: Fri May 1 13:32:36 2015 -0700
----------------------------------------------------------------------
.../blobstore/RegionScopedSwiftBlobStore.java | 71 ++++++++++++++++++++
.../v1/functions/ParseObjectFromResponse.java | 3 +
.../SwiftBlobIntegrationLiveTest.java | 10 +++
3 files changed, 84 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/jclouds/blob/deeebe46/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/blobstore/RegionScopedSwiftBlobStore.java
----------------------------------------------------------------------
diff --git a/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/blobstore/RegionScopedSwiftBlobStore.java b/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/blobstore/RegionScopedSwiftBlobStore.java
index 7962bbd..62177f1 100644
--- a/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/blobstore/RegionScopedSwiftBlobStore.java
+++ b/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/blobstore/RegionScopedSwiftBlobStore.java
@@ -27,6 +27,7 @@ import static org.jclouds.openstack.swift.v1.options.PutOptions.Builder.metadata
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.UUID;
import javax.inject.Inject;
@@ -37,6 +38,8 @@ import org.jclouds.blobstore.domain.BlobAccess;
import org.jclouds.blobstore.domain.BlobBuilder;
import org.jclouds.blobstore.domain.BlobMetadata;
import org.jclouds.blobstore.domain.ContainerAccess;
+import org.jclouds.blobstore.domain.MultipartPart;
+import org.jclouds.blobstore.domain.MultipartUpload;
import org.jclouds.blobstore.domain.MutableBlobMetadata;
import org.jclouds.blobstore.domain.PageSet;
import org.jclouds.blobstore.domain.StorageMetadata;
@@ -62,6 +65,7 @@ import org.jclouds.openstack.swift.v1.blobstore.functions.ToListContainerOptions
import org.jclouds.openstack.swift.v1.blobstore.functions.ToResourceMetadata;
import org.jclouds.openstack.swift.v1.domain.Container;
import org.jclouds.openstack.swift.v1.domain.ObjectList;
+import org.jclouds.openstack.swift.v1.domain.Segment;
import org.jclouds.openstack.swift.v1.domain.SwiftObject;
import org.jclouds.openstack.swift.v1.features.BulkApi;
import org.jclouds.openstack.swift.v1.features.ObjectApi;
@@ -76,6 +80,7 @@ import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.FluentIterable;
import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
@@ -396,6 +401,72 @@ public class RegionScopedSwiftBlobStore implements BlobStore {
}
@Override
+ public MultipartUpload initiateMultipartUpload(String container, BlobMetadata blobMetadata) {
+ String uploadId = UUID.randomUUID().toString();
+ return MultipartUpload.create(container, blobMetadata.getName(), uploadId, blobMetadata);
+ }
+
+ @Override
+ public void abortMultipartUpload(MultipartUpload mpu) {
+ ImmutableList.Builder<String> names = ImmutableList.builder();
+ for (MultipartPart part : listMultipartUpload(mpu)) {
+ names.add(mpu.blobName() + "-" + part.partNumber());
+ }
+ removeBlobs(mpu.containerName(), names.build());
+ }
+
+ @Override
+ public String completeMultipartUpload(MultipartUpload mpu, List<MultipartPart> parts) {
+ ImmutableList.Builder<Segment> builder = ImmutableList.builder();
+ for (MultipartPart part : parts) {
+ String path = mpu.containerName() + "/" + mpu.blobName() + "-" + part.partNumber();
+ builder.add(Segment.builder().path(path).etag(part.partETag()).sizeBytes(part.partSize()).build());
+ }
+ Map<String, String> metadata = ImmutableMap.of(); // TODO: how to populate this from mpu.blobMetadata()?
+ return api.getStaticLargeObjectApi(regionId, mpu.containerName()).replaceManifest(mpu.blobName(),
+ builder.build(), metadata);
+ }
+
+ @Override
+ public MultipartPart uploadMultipartPart(MultipartUpload mpu, int partNumber, Payload payload) {
+ String partName = mpu.blobName() + "-" + partNumber;
+ String eTag = api.getObjectApi(regionId, mpu.containerName()).put(partName, payload);
+ long partSize = payload.getContentMetadata().getContentLength();
+ return MultipartPart.create(partNumber, partSize, eTag);
+ }
+
+ @Override
+ public List<MultipartPart> listMultipartUpload(MultipartUpload mpu) {
+ ImmutableList.Builder<MultipartPart> parts = ImmutableList.builder();
+ PageSet<? extends StorageMetadata> pageSet = list(mpu.containerName(),
+ new ListContainerOptions().afterMarker(mpu.blobName()));
+ // TODO: pagination
+ for (StorageMetadata sm : pageSet) {
+ if (!sm.getName().startsWith(mpu.blobName() + "-")) {
+ break;
+ }
+ int partNumber = Integer.parseInt(sm.getName().substring((mpu.blobName() + "-").length()));
+ parts.add(MultipartPart.create(partNumber, sm.getSize(), sm.getETag()));
+ }
+ return parts.build();
+ }
+
+ @Override
+ public long getMinimumMultipartPartSize() {
+ return 1024 * 1024;
+ }
+
+ @Override
+ public long getMaximumMultipartPartSize() {
+ return 5L * 1024L * 1024L * 1024L;
+ }
+
+ @Override
+ public int getMaximumNumberOfParts() {
+ return Integer.MAX_VALUE;
+ }
+
+ @Override
public void clearContainer(String containerName) {
clearContainer(containerName, recursive());
}
http://git-wip-us.apache.org/repos/asf/jclouds/blob/deeebe46/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/functions/ParseObjectFromResponse.java
----------------------------------------------------------------------
diff --git a/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/functions/ParseObjectFromResponse.java b/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/functions/ParseObjectFromResponse.java
index cc934e4..1b63af1 100644
--- a/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/functions/ParseObjectFromResponse.java
+++ b/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/functions/ParseObjectFromResponse.java
@@ -65,6 +65,9 @@ public class ParseObjectFromResponse implements Function<HttpResponse, SwiftObje
String etag = from.getFirstHeaderOrNull(ETAG);
if (etag != null) {
+ if (etag.startsWith("\"") && etag.endsWith("\"") && etag.length() > 1) {
+ etag = etag.substring(1, etag.length() - 1);
+ }
payload.getContentMetadata().setContentMD5(HashCode.fromBytes(base16().lowerCase().decode(etag)));
}
http://git-wip-us.apache.org/repos/asf/jclouds/blob/deeebe46/apis/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/blobstore/integration/SwiftBlobIntegrationLiveTest.java
----------------------------------------------------------------------
diff --git a/apis/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/blobstore/integration/SwiftBlobIntegrationLiveTest.java b/apis/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/blobstore/integration/SwiftBlobIntegrationLiveTest.java
index c3eb7de..55e966a 100644
--- a/apis/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/blobstore/integration/SwiftBlobIntegrationLiveTest.java
+++ b/apis/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/blobstore/integration/SwiftBlobIntegrationLiveTest.java
@@ -83,4 +83,14 @@ public class SwiftBlobIntegrationLiveTest extends BaseBlobIntegrationTest {
public void testCopyBlobReplaceMetadata() throws Exception {
throw new SkipException("Swift only supports appending to user metadata, not replacing it");
}
+
+ @Override
+ public void testMultipartUploadSinglePart() throws Exception {
+ throw new SkipException("openstack-swift does not support setting blob metadata during multipart upload");
+ }
+
+ @Override
+ public void testMultipartUploadMultipleParts() throws Exception {
+ throw new SkipException("openstack-swift does not support setting blob metadata during multipart upload");
+ }
}