mirror of https://github.com/apache/jclouds.git
JCLOUDS-844: Portable putBlob ACLs
This commit is contained in:
parent
37f307ecd0
commit
86491bc607
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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?
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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(
|
||||||
|
|
|
@ -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 + "]";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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());
|
||||||
|
|
Loading…
Reference in New Issue