This is an automated email from the ASF dual-hosted git repository.

gaul pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/jclouds.git


The following commit(s) were added to refs/heads/master by this push:
     new a1df0bb  Store the MPU ETag for the transient blobstore
a1df0bb is described below

commit a1df0bb1f5f094774c81595fe8145d6f094a9ed6
Author: Timur Alperovich <ti...@timuralp.com>
AuthorDate: Wed Aug 4 01:33:57 2021 -0700

    Store the MPU ETag for the transient blobstore
    
    JCLOUDS-1582: fixes a bug in the transient blobstore where after
    uploading a multipart upload, GET/HEAD returns the hash of the content,
    rather than the MPU ETag.
---
 .../blobstore/TransientStorageStrategy.java        | 13 ++++++++---
 .../integration/TransientBlobIntegrationTest.java  | 25 ++++++++++++++++++++++
 2 files changed, 35 insertions(+), 3 deletions(-)

diff --git 
a/blobstore/src/main/java/org/jclouds/blobstore/TransientStorageStrategy.java 
b/blobstore/src/main/java/org/jclouds/blobstore/TransientStorageStrategy.java
index 398d55b..76a66b4 100644
--- 
a/blobstore/src/main/java/org/jclouds/blobstore/TransientStorageStrategy.java
+++ 
b/blobstore/src/main/java/org/jclouds/blobstore/TransientStorageStrategy.java
@@ -193,7 +193,14 @@ public class TransientStorageStrategy implements 
LocalStorageStrategy {
          Closeables2.closeQuietly(input);
       }
 
-      Blob newBlob = createUpdatedCopyOfBlobInContainer(containerName, blob, 
payload, actualHashCode);
+      String eTag = null;
+      if (blob.getMetadata() != null) {
+         eTag = blob.getMetadata().getETag();
+      }
+      if (eTag == null) {
+         eTag = base16().lowerCase().encode(actualHashCode.asBytes());
+      }
+      Blob newBlob = createUpdatedCopyOfBlobInContainer(containerName, blob, 
payload, actualHashCode, eTag);
       Map<String, Blob> map = containerToBlobs.get(containerName);
       String blobName = newBlob.getMetadata().getName();
       map.put(blobName, newBlob);
@@ -240,11 +247,12 @@ public class TransientStorageStrategy implements 
LocalStorageStrategy {
       return "/";
    }
 
-   private Blob createUpdatedCopyOfBlobInContainer(String containerName, Blob 
in, byte[] input, HashCode contentMd5) {
+   private Blob createUpdatedCopyOfBlobInContainer(String containerName, Blob 
in, byte[] input, HashCode contentMd5, String eTag) {
       checkNotNull(containerName, "containerName");
       checkNotNull(in, "blob");
       checkNotNull(input, "input");
       checkNotNull(contentMd5, "contentMd5");
+      checkNotNull(eTag, "eTag");
       Payload payload = createPayload(input);
       MutableContentMetadata oldMd = in.getPayload().getContentMetadata();
       HttpUtils.copy(oldMd, payload.getContentMetadata());
@@ -255,7 +263,6 @@ public class TransientStorageStrategy implements 
LocalStorageStrategy {
       blob.getMetadata().setContainer(containerName);
       blob.getMetadata().setLastModified(new Date());
       blob.getMetadata().setSize((long) input.length);
-      String eTag = base16().lowerCase().encode(contentMd5.asBytes());
       blob.getMetadata().setETag(eTag);
       // Set HTTP headers to match metadata
       blob.getAllHeaders().replaceValues(HttpHeaders.LAST_MODIFIED,
diff --git 
a/blobstore/src/test/java/org/jclouds/blobstore/integration/TransientBlobIntegrationTest.java
 
b/blobstore/src/test/java/org/jclouds/blobstore/integration/TransientBlobIntegrationTest.java
index e2b842e..d2d32c6 100644
--- 
a/blobstore/src/test/java/org/jclouds/blobstore/integration/TransientBlobIntegrationTest.java
+++ 
b/blobstore/src/test/java/org/jclouds/blobstore/integration/TransientBlobIntegrationTest.java
@@ -16,10 +16,19 @@
  */
 package org.jclouds.blobstore.integration;
 
+import com.google.common.hash.Hasher;
+import com.google.common.hash.Hashing;
+import com.google.common.io.BaseEncoding;
+import org.jclouds.blobstore.domain.Blob;
+import org.jclouds.blobstore.domain.MultipartPart;
 import org.jclouds.blobstore.integration.internal.BaseBlobIntegrationTest;
 import org.testng.annotations.Test;
 import org.testng.SkipException;
 
+import java.util.List;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
 @Test(groups = { "integration" })
 public class TransientBlobIntegrationTest extends BaseBlobIntegrationTest {
    public TransientBlobIntegrationTest() {
@@ -31,4 +40,20 @@ public class TransientBlobIntegrationTest extends 
BaseBlobIntegrationTest {
    public void testSetBlobAccess() throws Exception {
       throw new SkipException("transient does not support anonymous access");
    }
+
+   @Override
+   protected void checkMPUParts(Blob blob, List<MultipartPart> parts) {
+      assertThat(blob.getMetadata().getETag()).endsWith(String.format("-%d\"", 
parts.size()));
+      Hasher eTagHasher = Hashing.md5().newHasher();
+      for (MultipartPart part : parts) {
+         
eTagHasher.putBytes(BaseEncoding.base16().lowerCase().decode(part.partETag()));
+      }
+      String expectedETag = new StringBuilder("\"")
+              .append(eTagHasher.hash())
+              .append("-")
+              .append(parts.size())
+              .append("\"")
+              .toString();
+      assertThat(blob.getMetadata().getETag()).isEqualTo(expectedETag);
+   }
 }

Reply via email to