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");
+   }
 }