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 2014/12/23 01:01:56 UTC

jclouds git commit: JCLOUDS-391: Azure multipart putBlob user metadata

Repository: jclouds
Updated Branches:
  refs/heads/master 787ce446c -> 1c781cc5f


JCLOUDS-391: Azure multipart putBlob user metadata


Project: http://git-wip-us.apache.org/repos/asf/jclouds/repo
Commit: http://git-wip-us.apache.org/repos/asf/jclouds/commit/1c781cc5
Tree: http://git-wip-us.apache.org/repos/asf/jclouds/tree/1c781cc5
Diff: http://git-wip-us.apache.org/repos/asf/jclouds/diff/1c781cc5

Branch: refs/heads/master
Commit: 1c781cc5fa79ab2f476ec07600f493bd04940cc3
Parents: 787ce44
Author: Andrew Gaul <ga...@apache.org>
Authored: Fri Dec 19 15:48:49 2014 -0800
Committer: Andrew Gaul <ga...@apache.org>
Committed: Mon Dec 22 15:58:49 2014 -0800

----------------------------------------------------------------------
 .../org/jclouds/azureblob/AzureBlobClient.java  | 18 +++++++
 ...BindAzureBlobMetadataToMultipartRequest.java | 53 ++++++++++++++++++++
 .../strategy/AzureBlobBlockUploadStrategy.java  | 11 ++--
 .../AzureBlobIntegrationLiveTest.java           | 26 ++++++++++
 .../AzureBlobBlockUploadStrategyTest.java       | 10 ++--
 5 files changed, 111 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/jclouds/blob/1c781cc5/providers/azureblob/src/main/java/org/jclouds/azureblob/AzureBlobClient.java
----------------------------------------------------------------------
diff --git a/providers/azureblob/src/main/java/org/jclouds/azureblob/AzureBlobClient.java b/providers/azureblob/src/main/java/org/jclouds/azureblob/AzureBlobClient.java
index 790a0f4..a6e17c4 100644
--- a/providers/azureblob/src/main/java/org/jclouds/azureblob/AzureBlobClient.java
+++ b/providers/azureblob/src/main/java/org/jclouds/azureblob/AzureBlobClient.java
@@ -43,6 +43,7 @@ import org.jclouds.azure.storage.filters.SharedKeyLiteAuthentication;
 import org.jclouds.azure.storage.options.ListOptions;
 import org.jclouds.azure.storage.reference.AzureStorageHeaders;
 import org.jclouds.azureblob.binders.BindAzureBlobMetadataToRequest;
+import org.jclouds.azureblob.binders.BindAzureBlobMetadataToMultipartRequest;
 import org.jclouds.azureblob.binders.BindAzureBlocksToRequest;
 import org.jclouds.azureblob.domain.AzureBlob;
 import org.jclouds.azureblob.domain.BlobProperties;
@@ -347,7 +348,10 @@ public interface AzureBlobClient extends Closeable {
     *  The Put Block List assembles a list of blocks previously uploaded with Put Block into a single
     *  blob. Blocks are either already committed to a blob or uncommitted. The blocks ids passed here
     *  are searched for first in the uncommitted block list; then committed using the "latest" strategy.
+    *
+    *  @deprecated call putBlockList(String, AzureBlob, List&lt;String&gt;) instead
     */
+   @Deprecated
    @Named("PutBlockList")
    @PUT
    @Path("{container}/{name}")
@@ -357,6 +361,20 @@ public interface AzureBlobClient extends Closeable {
          @PathParam("name") String name,
          @BinderParam(BindAzureBlocksToRequest.class) List<String> blockIdList);
 
+   /**
+    *  The Put Block List assembles a list of blocks previously uploaded with Put Block into a single
+    *  blob. Blocks are either already committed to a blob or uncommitted. The blocks ids passed here
+    *  are searched for first in the uncommitted block list; then committed using the "latest" strategy.
+    */
+   @Named("PutBlockList")
+   @PUT
+   @Path("{container}/{name}")
+   @ResponseParser(ParseETagHeader.class)
+   @QueryParams(keys = { "comp" }, values = { "blocklist" })
+   String putBlockList(@PathParam("container") @ParamValidators(ContainerNameValidator.class) String container,
+         @PathParam("name") @ParamParser(BlobName.class) @BinderParam(BindAzureBlobMetadataToMultipartRequest.class) AzureBlob object,
+         @BinderParam(BindAzureBlocksToRequest.class) List<String> blockIdList);
+
    @Named("GetBlockList")
    @GET
    @Path("{container}/{name}")

http://git-wip-us.apache.org/repos/asf/jclouds/blob/1c781cc5/providers/azureblob/src/main/java/org/jclouds/azureblob/binders/BindAzureBlobMetadataToMultipartRequest.java
----------------------------------------------------------------------
diff --git a/providers/azureblob/src/main/java/org/jclouds/azureblob/binders/BindAzureBlobMetadataToMultipartRequest.java b/providers/azureblob/src/main/java/org/jclouds/azureblob/binders/BindAzureBlobMetadataToMultipartRequest.java
new file mode 100644
index 0000000..74741d4
--- /dev/null
+++ b/providers/azureblob/src/main/java/org/jclouds/azureblob/binders/BindAzureBlobMetadataToMultipartRequest.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.azureblob.binders;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import javax.inject.Inject;
+
+import org.jclouds.azureblob.blobstore.functions.AzureBlobToBlob;
+import org.jclouds.azureblob.domain.AzureBlob;
+import org.jclouds.blobstore.binders.BindUserMetadataToHeadersWithPrefix;
+import org.jclouds.http.HttpRequest;
+import org.jclouds.rest.Binder;
+
+public class BindAzureBlobMetadataToMultipartRequest implements Binder {
+
+   private final AzureBlobToBlob azureBlob2Blob;
+   private final BindUserMetadataToHeadersWithPrefix blobBinder;
+
+   @Inject
+   BindAzureBlobMetadataToMultipartRequest(AzureBlobToBlob azureBlob2Blob, BindUserMetadataToHeadersWithPrefix blobBinder) {
+      this.azureBlob2Blob = azureBlob2Blob;
+      this.blobBinder = blobBinder;
+   }
+
+   @SuppressWarnings("unchecked")
+   @Override
+   public <R extends HttpRequest> R bindToRequest(R request, Object input) {
+      checkArgument(checkNotNull(input, "input") instanceof AzureBlob, "this binder is only valid for AzureBlobs!");
+      checkNotNull(request, "request");
+      AzureBlob blob = AzureBlob.class.cast(input);
+
+      checkArgument(blob.getPayload().getContentMetadata().getContentLength() != null
+            && blob.getPayload().getContentMetadata().getContentLength() >= 0, "size must be set");
+
+      return blobBinder.bindToRequest(request, azureBlob2Blob.apply(blob));
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/1c781cc5/providers/azureblob/src/main/java/org/jclouds/azureblob/blobstore/strategy/AzureBlobBlockUploadStrategy.java
----------------------------------------------------------------------
diff --git a/providers/azureblob/src/main/java/org/jclouds/azureblob/blobstore/strategy/AzureBlobBlockUploadStrategy.java b/providers/azureblob/src/main/java/org/jclouds/azureblob/blobstore/strategy/AzureBlobBlockUploadStrategy.java
index 74ebda9..8619a54 100644
--- a/providers/azureblob/src/main/java/org/jclouds/azureblob/blobstore/strategy/AzureBlobBlockUploadStrategy.java
+++ b/providers/azureblob/src/main/java/org/jclouds/azureblob/blobstore/strategy/AzureBlobBlockUploadStrategy.java
@@ -21,6 +21,7 @@ import com.google.common.hash.Hashing;
 import com.google.common.io.BaseEncoding;
 import com.google.inject.Inject;
 import org.jclouds.azureblob.AzureBlobClient;
+import org.jclouds.azureblob.blobstore.functions.BlobToAzureBlob;
 import org.jclouds.blobstore.domain.Blob;
 import org.jclouds.blobstore.reference.BlobStoreConstants;
 import org.jclouds.io.Payload;
@@ -46,11 +47,13 @@ public class AzureBlobBlockUploadStrategy implements MultipartUploadStrategy {
 
    private final AzureBlobClient client;
    private final PayloadSlicer slicer;
+   private final BlobToAzureBlob blobToAzureBlob;
 
    @Inject
-   public AzureBlobBlockUploadStrategy(AzureBlobClient client, PayloadSlicer slicer) {
-      this.client = checkNotNull(client, "client");
-      this.slicer = checkNotNull(slicer, "slicer");
+   AzureBlobBlockUploadStrategy(AzureBlobClient client, PayloadSlicer slicer, BlobToAzureBlob blobToAzureBlob) {
+      this.client = client;
+      this.slicer = slicer;
+      this.blobToAzureBlob = blobToAzureBlob;
    }
 
    @Override
@@ -74,6 +77,6 @@ public class AzureBlobBlockUploadStrategy implements MultipartUploadStrategy {
       }
 
       checkState(bytesWritten == length, "Wrote %s bytes, but we wanted to write %s bytes", bytesWritten, length);
-      return client.putBlockList(container, blobName, blockIds);
+      return client.putBlockList(container, blobToAzureBlob.apply(blob), blockIds);
    }
 }

http://git-wip-us.apache.org/repos/asf/jclouds/blob/1c781cc5/providers/azureblob/src/test/java/org/jclouds/azureblob/blobstore/integration/AzureBlobIntegrationLiveTest.java
----------------------------------------------------------------------
diff --git a/providers/azureblob/src/test/java/org/jclouds/azureblob/blobstore/integration/AzureBlobIntegrationLiveTest.java b/providers/azureblob/src/test/java/org/jclouds/azureblob/blobstore/integration/AzureBlobIntegrationLiveTest.java
index 44bd7db..dea1a57 100644
--- a/providers/azureblob/src/test/java/org/jclouds/azureblob/blobstore/integration/AzureBlobIntegrationLiveTest.java
+++ b/providers/azureblob/src/test/java/org/jclouds/azureblob/blobstore/integration/AzureBlobIntegrationLiveTest.java
@@ -18,13 +18,16 @@ package org.jclouds.azureblob.blobstore.integration;
 
 import java.io.File;
 import java.io.IOException;
+import java.util.Map;
 import java.util.concurrent.ExecutionException;
 
+import com.google.common.collect.ImmutableMap;
 import com.google.common.io.ByteSource;
 import com.google.common.io.Files;
 import org.jclouds.azureblob.blobstore.strategy.MultipartUploadStrategy;
 import org.jclouds.blobstore.BlobStore;
 import org.jclouds.blobstore.domain.Blob;
+import org.jclouds.blobstore.domain.BlobMetadata;
 import org.jclouds.blobstore.integration.internal.BaseBlobIntegrationTest;
 import org.jclouds.blobstore.options.PutOptions;
 import org.jclouds.io.ByteStreams2;
@@ -133,4 +136,27 @@ public class AzureBlobIntegrationLiveTest extends BaseBlobIntegrationTest {
          returnContainer(containerName);
       }
    }
+
+   public void testMultipartUserMetadata() throws Exception {
+      BlobStore blobStore = view.getBlobStore();
+      String containerName = getContainerName();
+      String blobName = "const.txt";
+      ByteSource byteSource = TestUtils.randomByteSource().slice(0, MultipartUploadStrategy.MAX_BLOCK_SIZE + 1);
+      Map<String, String> userMetadata = ImmutableMap.of("foo", "bar");
+
+      blobStore.createContainerInLocation(null, containerName);
+      try {
+         Blob blob = blobStore.blobBuilder(blobName)
+            .payload(byteSource)
+            .contentLength(byteSource.size())
+            .userMetadata(userMetadata)
+            .build();
+         blobStore.putBlob(containerName, blob, PutOptions.Builder.multipart());
+
+         BlobMetadata blobMetadata = blobStore.blobMetadata(containerName, blobName);
+         assertThat(blobMetadata.getUserMetadata()).isEqualTo(userMetadata);
+      } finally {
+         returnContainer(containerName);
+      }
+   }
 }

http://git-wip-us.apache.org/repos/asf/jclouds/blob/1c781cc5/providers/azureblob/src/test/java/org/jclouds/azureblob/blobstore/strategy/AzureBlobBlockUploadStrategyTest.java
----------------------------------------------------------------------
diff --git a/providers/azureblob/src/test/java/org/jclouds/azureblob/blobstore/strategy/AzureBlobBlockUploadStrategyTest.java b/providers/azureblob/src/test/java/org/jclouds/azureblob/blobstore/strategy/AzureBlobBlockUploadStrategyTest.java
index aac7d30..35b68d0 100644
--- a/providers/azureblob/src/test/java/org/jclouds/azureblob/blobstore/strategy/AzureBlobBlockUploadStrategyTest.java
+++ b/providers/azureblob/src/test/java/org/jclouds/azureblob/blobstore/strategy/AzureBlobBlockUploadStrategyTest.java
@@ -22,6 +22,8 @@ import com.google.common.collect.ImmutableList;
 import com.google.common.io.ByteSource;
 import org.easymock.EasyMock;
 import org.jclouds.azureblob.AzureBlobClient;
+import org.jclouds.azureblob.blobstore.functions.BlobToAzureBlob;
+import org.jclouds.azureblob.domain.AzureBlob;
 import org.jclouds.blobstore.domain.Blob;
 import org.jclouds.blobstore.domain.MutableBlobMetadata;
 import org.jclouds.blobstore.domain.internal.BlobImpl;
@@ -54,6 +56,7 @@ public class AzureBlobBlockUploadStrategyTest {
       byte[] blobData = "ABCD".getBytes(Charsets.UTF_8);
       AzureBlobClient client = createMock(AzureBlobClient.class);
       PayloadSlicer slicer = createMock(PayloadSlicer.class);
+      BlobToAzureBlob blobToAzureBlob = createMock(BlobToAzureBlob.class);
       MutableBlobMetadata metadata = new MutableBlobMetadataImpl();
       MutableContentMetadata contentMetadata = new BaseMutableContentMetadata();
       contentMetadata.setContentLength((long)blobData.length);
@@ -76,9 +79,9 @@ public class AzureBlobBlockUploadStrategyTest {
       client.putBlock(eq(container), eq(blobName), anyObject(String.class), eq(payloads.get(1)));
       client.putBlock(eq(container), eq(blobName), anyObject(String.class), eq(payloads.get(2)));
       client.putBlock(eq(container), eq(blobName), anyObject(String.class), eq(payloads.get(3)));
-      expect(client.putBlockList(eq(container), eq(blobName), EasyMock.<List<String>>anyObject())).andReturn("Fake ETAG");
+      expect(client.putBlockList(eq(container), anyObject(AzureBlob.class), EasyMock.<List<String>>anyObject())).andReturn("Fake ETAG");
 
-      AzureBlobBlockUploadStrategy strat = new AzureBlobBlockUploadStrategy(client, slicer);
+      AzureBlobBlockUploadStrategy strat = new AzureBlobBlockUploadStrategy(client, slicer, blobToAzureBlob);
       replay(slicer, client);
       String etag = strat.execute(container, blob);
       assertEquals(etag, "Fake ETAG");
@@ -93,6 +96,7 @@ public class AzureBlobBlockUploadStrategyTest {
 
       AzureBlobClient client = createNiceMock(AzureBlobClient.class);
       PayloadSlicer slicer = createNiceMock(PayloadSlicer.class);
+      BlobToAzureBlob blobToAzureBlob = createMock(BlobToAzureBlob.class);
 
       MutableBlobMetadata metadata = new MutableBlobMetadataImpl();
       MutableContentMetadata contentMetadata = new BaseMutableContentMetadata();
@@ -105,7 +109,7 @@ public class AzureBlobBlockUploadStrategyTest {
       payload.setContentMetadata(contentMetadata);
       blob.setPayload(payload);
 
-      AzureBlobBlockUploadStrategy strat = new AzureBlobBlockUploadStrategy(client, slicer);
+      AzureBlobBlockUploadStrategy strat = new AzureBlobBlockUploadStrategy(client, slicer, blobToAzureBlob);
       strat.execute(container, blob);
    }