JCLOUDS-844: Portable putBlob ACLs

This commit is contained in:
Andrew Gaul 2015-12-21 16:51:50 -08:00
parent 37f307ecd0
commit 86491bc607
9 changed files with 81 additions and 14 deletions

View File

@ -264,7 +264,6 @@ public class S3BlobStore extends BaseBlobStore {
return putMultipartBlob(container, blob, overrides); return putMultipartBlob(container, blob, overrides);
} }
// TODO: Make use of options overrides
PutObjectOptions options = new PutObjectOptions(); PutObjectOptions options = new PutObjectOptions();
return sync.putObject(container, blob2Object.apply(blob), options); return sync.putObject(container, blob2Object.apply(blob), options);
} }

View File

@ -333,7 +333,7 @@ public interface BlobStore {
long countBlobs(String container, ListContainerOptions options); long countBlobs(String container, ListContainerOptions options);
@Beta @Beta
MultipartUpload initiateMultipartUpload(String container, BlobMetadata blob); MultipartUpload initiateMultipartUpload(String container, BlobMetadata blob, PutOptions options);
@Beta @Beta
// TODO: take parts? // TODO: take parts?

View File

@ -750,9 +750,9 @@ public final class LocalBlobStore implements BlobStore {
} }
@Override @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(), return MultipartUpload.create(container, blobMetadata.getName(), UUID.randomUUID().toString(),
blobMetadata); blobMetadata, options);
} }
@Override @Override
@ -809,6 +809,8 @@ public final class LocalBlobStore implements BlobStore {
storageStrategy.removeBlob(mpu.containerName(), mpu.blobName() + "-" + part.partNumber()); storageStrategy.removeBlob(mpu.containerName(), mpu.blobName() + "-" + part.partNumber());
} }
setBlobAccess(mpu.containerName(), mpu.blobName(), mpu.putOptions().getBlobAccess());
return eTag; return eTag;
} }

View File

@ -17,6 +17,8 @@
package org.jclouds.blobstore.domain; package org.jclouds.blobstore.domain;
import org.jclouds.blobstore.options.PutOptions;
import com.google.auto.value.AutoValue; import com.google.auto.value.AutoValue;
@AutoValue @AutoValue
@ -25,8 +27,10 @@ public abstract class MultipartUpload {
public abstract String blobName(); public abstract String blobName();
public abstract String id(); public abstract String id();
public abstract BlobMetadata blobMetadata(); public abstract BlobMetadata blobMetadata();
public abstract PutOptions putOptions();
public static MultipartUpload create(String containerName, String blobName, String id, BlobMetadata blobMetadata) { public static MultipartUpload create(String containerName, String blobName, String id, BlobMetadata blobMetadata,
return new AutoValue_MultipartUpload(containerName, blobName, id, blobMetadata); PutOptions putOptions) {
return new AutoValue_MultipartUpload(containerName, blobName, id, blobMetadata, putOptions);
} }
} }

View File

@ -290,7 +290,7 @@ public abstract class BaseBlobStore implements BlobStore {
// TODO: parallel uploads // TODO: parallel uploads
@Beta @Beta
protected String putMultipartBlob(String container, Blob blob, PutOptions overrides) { protected String putMultipartBlob(String container, Blob blob, PutOptions overrides) {
MultipartUpload mpu = initiateMultipartUpload(container, blob.getMetadata()); MultipartUpload mpu = initiateMultipartUpload(container, blob.getMetadata(), overrides);
List<MultipartPart> parts = Lists.newArrayList(); List<MultipartPart> parts = Lists.newArrayList();
long contentLength = blob.getMetadata().getContentMetadata().getContentLength(); long contentLength = blob.getMetadata().getContentMetadata().getContentLength();
MultipartUploadSlicingAlgorithm algorithm = new MultipartUploadSlicingAlgorithm( MultipartUploadSlicingAlgorithm algorithm = new MultipartUploadSlicingAlgorithm(

View File

@ -16,6 +16,10 @@
*/ */
package org.jclouds.blobstore.options; 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. <h2> * Contains options supported in the put blob operation. <h2>
* Usage</h2> The recommended way to instantiate a PutOptions object is to statically import * Usage</h2> 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()); public static final ImmutablePutOptions NONE = new ImmutablePutOptions(new PutOptions());
private BlobAccess blobAccess = BlobAccess.PRIVATE;
private boolean multipart = false; private boolean multipart = false;
public PutOptions() { public PutOptions() {
@ -46,6 +51,16 @@ public class PutOptions implements Cloneable {
this.delegate = delegate; this.delegate = delegate;
} }
@Override
public BlobAccess getBlobAccess() {
return delegate.getBlobAccess();
}
@Override
public PutOptions setBlobAccess(BlobAccess blobAccess) {
throw new UnsupportedOperationException();
}
@Override @Override
public boolean isMultipart() { public boolean isMultipart() {
return delegate.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() { public boolean isMultipart() {
return multipart; return multipart;
} }
@ -115,6 +139,6 @@ public class PutOptions implements Cloneable {
@Override @Override
public String toString() { public String toString() {
return "[multipart=" + multipart + "]"; return "[multipart=" + multipart + ", blobAccess=" + blobAccess + "]";
} }
} }

View File

@ -220,8 +220,8 @@ public abstract class ForwardingBlobStore extends ForwardingObject
} }
@Override @Override
public MultipartUpload initiateMultipartUpload(String container, BlobMetadata blobMetadata) { public MultipartUpload initiateMultipartUpload(String container, BlobMetadata blobMetadata, PutOptions options) {
return delegate().initiateMultipartUpload(container, blobMetadata); return delegate().initiateMultipartUpload(container, blobMetadata, options);
} }
@Override @Override

View File

@ -136,7 +136,7 @@ public final class ReadOnlyBlobStore extends ForwardingBlobStore {
} }
@Override @Override
public MultipartUpload initiateMultipartUpload(String container, BlobMetadata blobMetadata) { public MultipartUpload initiateMultipartUpload(String container, BlobMetadata blobMetadata, PutOptions options) {
throw new UnsupportedOperationException("Read-only BlobStore"); throw new UnsupportedOperationException("Read-only BlobStore");
} }

View File

@ -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<String, String> userMetadata1, Map<String, String> userMetadata2) { protected void checkUserMetadata(Map<String, String> userMetadata1, Map<String, String> userMetadata2) {
assertThat(userMetadata1).isEqualTo(userMetadata2); assertThat(userMetadata1).isEqualTo(userMetadata2);
} }
@ -900,7 +938,7 @@ public class BaseBlobIntegrationTest extends BaseBlobStoreIntegrationTest {
try { try {
String name = "blob-name"; String name = "blob-name";
Blob blob = blobStore.blobBuilder(name).build(); Blob blob = blobStore.blobBuilder(name).build();
MultipartUpload mpu = blobStore.initiateMultipartUpload(container, blob.getMetadata()); MultipartUpload mpu = blobStore.initiateMultipartUpload(container, blob.getMetadata(), new PutOptions());
List<MultipartPart> parts = blobStore.listMultipartUpload(mpu); List<MultipartPart> parts = blobStore.listMultipartUpload(mpu);
assertThat(parts).isEqualTo(ImmutableList.of()); assertThat(parts).isEqualTo(ImmutableList.of());
@ -926,7 +964,7 @@ public class BaseBlobIntegrationTest extends BaseBlobStoreIntegrationTest {
.payload(new byte[0]); .payload(new byte[0]);
addContentMetadata(blobBuilder); addContentMetadata(blobBuilder);
Blob blob = blobBuilder.build(); 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); ByteSource byteSource = TestUtils.randomByteSource().slice(0, 1);
Payload payload = Payloads.newByteSourcePayload(byteSource); Payload payload = Payloads.newByteSourcePayload(byteSource);
@ -960,7 +998,7 @@ public class BaseBlobIntegrationTest extends BaseBlobStoreIntegrationTest {
.payload(new byte[0]); .payload(new byte[0]);
addContentMetadata(blobBuilder); addContentMetadata(blobBuilder);
Blob blob = blobBuilder.build(); 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 byteSource = TestUtils.randomByteSource().slice(0, blobStore.getMinimumMultipartPartSize() + 1);
ByteSource byteSource1 = byteSource.slice(0, blobStore.getMinimumMultipartPartSize()); ByteSource byteSource1 = byteSource.slice(0, blobStore.getMinimumMultipartPartSize());