diff --git a/apis/s3/src/main/java/org/jclouds/s3/blobstore/S3BlobStore.java b/apis/s3/src/main/java/org/jclouds/s3/blobstore/S3BlobStore.java index 37f264e7e8..a72f9e9687 100644 --- a/apis/s3/src/main/java/org/jclouds/s3/blobstore/S3BlobStore.java +++ b/apis/s3/src/main/java/org/jclouds/s3/blobstore/S3BlobStore.java @@ -264,7 +264,6 @@ public class S3BlobStore extends BaseBlobStore { return putMultipartBlob(container, blob, overrides); } - // TODO: Make use of options overrides PutObjectOptions options = new PutObjectOptions(); return sync.putObject(container, blob2Object.apply(blob), options); } diff --git a/blobstore/src/main/java/org/jclouds/blobstore/BlobStore.java b/blobstore/src/main/java/org/jclouds/blobstore/BlobStore.java index 3bbe708211..4cbc92e7d7 100644 --- a/blobstore/src/main/java/org/jclouds/blobstore/BlobStore.java +++ b/blobstore/src/main/java/org/jclouds/blobstore/BlobStore.java @@ -333,7 +333,7 @@ public interface BlobStore { long countBlobs(String container, ListContainerOptions options); @Beta - MultipartUpload initiateMultipartUpload(String container, BlobMetadata blob); + MultipartUpload initiateMultipartUpload(String container, BlobMetadata blob, PutOptions options); @Beta // TODO: take parts? diff --git a/blobstore/src/main/java/org/jclouds/blobstore/config/LocalBlobStore.java b/blobstore/src/main/java/org/jclouds/blobstore/config/LocalBlobStore.java index 08a49e3ba6..214dd5d320 100644 --- a/blobstore/src/main/java/org/jclouds/blobstore/config/LocalBlobStore.java +++ b/blobstore/src/main/java/org/jclouds/blobstore/config/LocalBlobStore.java @@ -750,9 +750,9 @@ public final class LocalBlobStore implements BlobStore { } @Override - public MultipartUpload initiateMultipartUpload(String container, BlobMetadata blobMetadata) { + public MultipartUpload initiateMultipartUpload(String container, BlobMetadata blobMetadata, PutOptions options) { return MultipartUpload.create(container, blobMetadata.getName(), UUID.randomUUID().toString(), - blobMetadata); + blobMetadata, options); } @Override @@ -809,6 +809,8 @@ public final class LocalBlobStore implements BlobStore { storageStrategy.removeBlob(mpu.containerName(), mpu.blobName() + "-" + part.partNumber()); } + setBlobAccess(mpu.containerName(), mpu.blobName(), mpu.putOptions().getBlobAccess()); + return eTag; } diff --git a/blobstore/src/main/java/org/jclouds/blobstore/domain/MultipartUpload.java b/blobstore/src/main/java/org/jclouds/blobstore/domain/MultipartUpload.java index d70c3ec462..94f2401b47 100644 --- a/blobstore/src/main/java/org/jclouds/blobstore/domain/MultipartUpload.java +++ b/blobstore/src/main/java/org/jclouds/blobstore/domain/MultipartUpload.java @@ -17,6 +17,8 @@ package org.jclouds.blobstore.domain; +import org.jclouds.blobstore.options.PutOptions; + import com.google.auto.value.AutoValue; @AutoValue @@ -25,8 +27,10 @@ public abstract class MultipartUpload { public abstract String blobName(); public abstract String id(); public abstract BlobMetadata blobMetadata(); + public abstract PutOptions putOptions(); - public static MultipartUpload create(String containerName, String blobName, String id, BlobMetadata blobMetadata) { - return new AutoValue_MultipartUpload(containerName, blobName, id, blobMetadata); + public static MultipartUpload create(String containerName, String blobName, String id, BlobMetadata blobMetadata, + PutOptions putOptions) { + return new AutoValue_MultipartUpload(containerName, blobName, id, blobMetadata, putOptions); } } diff --git a/blobstore/src/main/java/org/jclouds/blobstore/internal/BaseBlobStore.java b/blobstore/src/main/java/org/jclouds/blobstore/internal/BaseBlobStore.java index 5876985238..a608b18028 100644 --- a/blobstore/src/main/java/org/jclouds/blobstore/internal/BaseBlobStore.java +++ b/blobstore/src/main/java/org/jclouds/blobstore/internal/BaseBlobStore.java @@ -290,7 +290,7 @@ public abstract class BaseBlobStore implements BlobStore { // TODO: parallel uploads @Beta protected String putMultipartBlob(String container, Blob blob, PutOptions overrides) { - MultipartUpload mpu = initiateMultipartUpload(container, blob.getMetadata()); + MultipartUpload mpu = initiateMultipartUpload(container, blob.getMetadata(), overrides); List parts = Lists.newArrayList(); long contentLength = blob.getMetadata().getContentMetadata().getContentLength(); MultipartUploadSlicingAlgorithm algorithm = new MultipartUploadSlicingAlgorithm( diff --git a/blobstore/src/main/java/org/jclouds/blobstore/options/PutOptions.java b/blobstore/src/main/java/org/jclouds/blobstore/options/PutOptions.java index 813aeaa095..4cb8ca2b5c 100644 --- a/blobstore/src/main/java/org/jclouds/blobstore/options/PutOptions.java +++ b/blobstore/src/main/java/org/jclouds/blobstore/options/PutOptions.java @@ -16,6 +16,10 @@ */ package org.jclouds.blobstore.options; +import static com.google.common.base.Preconditions.checkNotNull; + +import org.jclouds.blobstore.domain.BlobAccess; + /** * Contains options supported in the put blob operation.

* Usage

The recommended way to instantiate a PutOptions object is to statically import @@ -30,6 +34,7 @@ public class PutOptions implements Cloneable { public static final ImmutablePutOptions NONE = new ImmutablePutOptions(new PutOptions()); + private BlobAccess blobAccess = BlobAccess.PRIVATE; private boolean multipart = false; public PutOptions() { @@ -46,6 +51,16 @@ public class PutOptions implements Cloneable { this.delegate = delegate; } + @Override + public BlobAccess getBlobAccess() { + return delegate.getBlobAccess(); + } + + @Override + public PutOptions setBlobAccess(BlobAccess blobAccess) { + throw new UnsupportedOperationException(); + } + @Override public boolean isMultipart() { return delegate.isMultipart(); @@ -68,6 +83,15 @@ public class PutOptions implements Cloneable { } + public BlobAccess getBlobAccess() { + return blobAccess; + } + + public PutOptions setBlobAccess(BlobAccess blobAccess) { + this.blobAccess = checkNotNull(blobAccess); + return this; + } + public boolean isMultipart() { return multipart; } @@ -115,6 +139,6 @@ public class PutOptions implements Cloneable { @Override public String toString() { - return "[multipart=" + multipart + "]"; + return "[multipart=" + multipart + ", blobAccess=" + blobAccess + "]"; } } diff --git a/blobstore/src/main/java/org/jclouds/blobstore/util/ForwardingBlobStore.java b/blobstore/src/main/java/org/jclouds/blobstore/util/ForwardingBlobStore.java index 77f01f6f61..2a4631b818 100644 --- a/blobstore/src/main/java/org/jclouds/blobstore/util/ForwardingBlobStore.java +++ b/blobstore/src/main/java/org/jclouds/blobstore/util/ForwardingBlobStore.java @@ -220,8 +220,8 @@ public abstract class ForwardingBlobStore extends ForwardingObject } @Override - public MultipartUpload initiateMultipartUpload(String container, BlobMetadata blobMetadata) { - return delegate().initiateMultipartUpload(container, blobMetadata); + public MultipartUpload initiateMultipartUpload(String container, BlobMetadata blobMetadata, PutOptions options) { + return delegate().initiateMultipartUpload(container, blobMetadata, options); } @Override diff --git a/blobstore/src/main/java/org/jclouds/blobstore/util/ReadOnlyBlobStore.java b/blobstore/src/main/java/org/jclouds/blobstore/util/ReadOnlyBlobStore.java index 0fd06ee4fc..3cfbb73924 100644 --- a/blobstore/src/main/java/org/jclouds/blobstore/util/ReadOnlyBlobStore.java +++ b/blobstore/src/main/java/org/jclouds/blobstore/util/ReadOnlyBlobStore.java @@ -136,7 +136,7 @@ public final class ReadOnlyBlobStore extends ForwardingBlobStore { } @Override - public MultipartUpload initiateMultipartUpload(String container, BlobMetadata blobMetadata) { + public MultipartUpload initiateMultipartUpload(String container, BlobMetadata blobMetadata, PutOptions options) { throw new UnsupportedOperationException("Read-only BlobStore"); } diff --git a/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseBlobIntegrationTest.java b/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseBlobIntegrationTest.java index cdcdec6411..02406022c1 100644 --- a/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseBlobIntegrationTest.java +++ b/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseBlobIntegrationTest.java @@ -674,6 +674,44 @@ public class BaseBlobIntegrationTest extends BaseBlobStoreIntegrationTest { } } + @Test(groups = { "integration", "live" }) + public void testPutBlobAccess() throws Exception { + BlobStore blobStore = view.getBlobStore(); + String containerName = getContainerName(); + try { + String blobNamePrivate = "put-access-blob-name-private"; + Blob blobPrivate = blobStore.blobBuilder(blobNamePrivate).payload(new byte[1]).build(); + blobStore.putBlob(containerName, blobPrivate, new PutOptions().setBlobAccess(BlobAccess.PRIVATE)); + assertThat(blobStore.getBlobAccess(containerName, blobNamePrivate)).isEqualTo(BlobAccess.PRIVATE); + + String blobNamePublic = "put-access-blob-name-public"; + Blob blobPublic = blobStore.blobBuilder(blobNamePublic).payload(new byte[1]).build(); + blobStore.putBlob(containerName, blobPublic, new PutOptions().setBlobAccess(BlobAccess.PUBLIC_READ)); + assertThat(blobStore.getBlobAccess(containerName, blobNamePublic)).isEqualTo(BlobAccess.PUBLIC_READ); + } finally { + returnContainer(containerName); + } + } + + @Test(groups = { "integration", "live" }) + public void testPutBlobAccessMultipart() throws Exception { + BlobStore blobStore = view.getBlobStore(); + String containerName = getContainerName(); + try { + String blobNamePrivate = "put-access-blob-name-private"; + Blob blobPrivate = blobStore.blobBuilder(blobNamePrivate).payload(new byte[1]).build(); + blobStore.putBlob(containerName, blobPrivate, new PutOptions().setBlobAccess(BlobAccess.PRIVATE).multipart(true)); + assertThat(blobStore.getBlobAccess(containerName, blobNamePrivate)).isEqualTo(BlobAccess.PRIVATE); + + String blobNamePublic = "put-access-blob-name-public"; + Blob blobPublic = blobStore.blobBuilder(blobNamePublic).payload(new byte[1]).build(); + blobStore.putBlob(containerName, blobPublic, new PutOptions().setBlobAccess(BlobAccess.PUBLIC_READ).multipart(true)); + assertThat(blobStore.getBlobAccess(containerName, blobNamePublic)).isEqualTo(BlobAccess.PUBLIC_READ); + } finally { + returnContainer(containerName); + } + } + protected void checkUserMetadata(Map userMetadata1, Map userMetadata2) { assertThat(userMetadata1).isEqualTo(userMetadata2); } @@ -900,7 +938,7 @@ public class BaseBlobIntegrationTest extends BaseBlobStoreIntegrationTest { try { String name = "blob-name"; Blob blob = blobStore.blobBuilder(name).build(); - MultipartUpload mpu = blobStore.initiateMultipartUpload(container, blob.getMetadata()); + MultipartUpload mpu = blobStore.initiateMultipartUpload(container, blob.getMetadata(), new PutOptions()); List parts = blobStore.listMultipartUpload(mpu); assertThat(parts).isEqualTo(ImmutableList.of()); @@ -926,7 +964,7 @@ public class BaseBlobIntegrationTest extends BaseBlobStoreIntegrationTest { .payload(new byte[0]); addContentMetadata(blobBuilder); Blob blob = blobBuilder.build(); - MultipartUpload mpu = blobStore.initiateMultipartUpload(container, blob.getMetadata()); + MultipartUpload mpu = blobStore.initiateMultipartUpload(container, blob.getMetadata(), new PutOptions()); ByteSource byteSource = TestUtils.randomByteSource().slice(0, 1); Payload payload = Payloads.newByteSourcePayload(byteSource); @@ -960,7 +998,7 @@ public class BaseBlobIntegrationTest extends BaseBlobStoreIntegrationTest { .payload(new byte[0]); addContentMetadata(blobBuilder); Blob blob = blobBuilder.build(); - MultipartUpload mpu = blobStore.initiateMultipartUpload(container, blob.getMetadata()); + MultipartUpload mpu = blobStore.initiateMultipartUpload(container, blob.getMetadata(), new PutOptions()); ByteSource byteSource = TestUtils.randomByteSource().slice(0, blobStore.getMinimumMultipartPartSize() + 1); ByteSource byteSource1 = byteSource.slice(0, blobStore.getMinimumMultipartPartSize());