mirror of https://github.com/apache/jclouds.git
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.
This commit is contained in:
parent
720e92c54a
commit
a1df0bb1f5
|
@ -193,7 +193,14 @@ public class TransientStorageStrategy implements LocalStorageStrategy {
|
||||||
Closeables2.closeQuietly(input);
|
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);
|
Map<String, Blob> map = containerToBlobs.get(containerName);
|
||||||
String blobName = newBlob.getMetadata().getName();
|
String blobName = newBlob.getMetadata().getName();
|
||||||
map.put(blobName, newBlob);
|
map.put(blobName, newBlob);
|
||||||
|
@ -240,11 +247,12 @@ public class TransientStorageStrategy implements LocalStorageStrategy {
|
||||||
return "/";
|
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(containerName, "containerName");
|
||||||
checkNotNull(in, "blob");
|
checkNotNull(in, "blob");
|
||||||
checkNotNull(input, "input");
|
checkNotNull(input, "input");
|
||||||
checkNotNull(contentMd5, "contentMd5");
|
checkNotNull(contentMd5, "contentMd5");
|
||||||
|
checkNotNull(eTag, "eTag");
|
||||||
Payload payload = createPayload(input);
|
Payload payload = createPayload(input);
|
||||||
MutableContentMetadata oldMd = in.getPayload().getContentMetadata();
|
MutableContentMetadata oldMd = in.getPayload().getContentMetadata();
|
||||||
HttpUtils.copy(oldMd, payload.getContentMetadata());
|
HttpUtils.copy(oldMd, payload.getContentMetadata());
|
||||||
|
@ -255,7 +263,6 @@ public class TransientStorageStrategy implements LocalStorageStrategy {
|
||||||
blob.getMetadata().setContainer(containerName);
|
blob.getMetadata().setContainer(containerName);
|
||||||
blob.getMetadata().setLastModified(new Date());
|
blob.getMetadata().setLastModified(new Date());
|
||||||
blob.getMetadata().setSize((long) input.length);
|
blob.getMetadata().setSize((long) input.length);
|
||||||
String eTag = base16().lowerCase().encode(contentMd5.asBytes());
|
|
||||||
blob.getMetadata().setETag(eTag);
|
blob.getMetadata().setETag(eTag);
|
||||||
// Set HTTP headers to match metadata
|
// Set HTTP headers to match metadata
|
||||||
blob.getAllHeaders().replaceValues(HttpHeaders.LAST_MODIFIED,
|
blob.getAllHeaders().replaceValues(HttpHeaders.LAST_MODIFIED,
|
||||||
|
|
|
@ -16,10 +16,19 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.blobstore.integration;
|
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.jclouds.blobstore.integration.internal.BaseBlobIntegrationTest;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
import org.testng.SkipException;
|
import org.testng.SkipException;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
@Test(groups = { "integration" })
|
@Test(groups = { "integration" })
|
||||||
public class TransientBlobIntegrationTest extends BaseBlobIntegrationTest {
|
public class TransientBlobIntegrationTest extends BaseBlobIntegrationTest {
|
||||||
public TransientBlobIntegrationTest() {
|
public TransientBlobIntegrationTest() {
|
||||||
|
@ -31,4 +40,20 @@ public class TransientBlobIntegrationTest extends BaseBlobIntegrationTest {
|
||||||
public void testSetBlobAccess() throws Exception {
|
public void testSetBlobAccess() throws Exception {
|
||||||
throw new SkipException("transient does not support anonymous access");
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue