blob: 9c994b2fe303bb47e4bc86e06f8000a65eb774f2 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jclouds.s3;
import static com.google.common.hash.Hashing.md5;
import static org.assertj.core.api.Assertions.assertThat;
import static org.jclouds.io.Payloads.newByteArrayPayload;
import static org.jclouds.s3.options.CopyObjectOptions.Builder.ifSourceETagDoesntMatch;
import static org.jclouds.s3.options.CopyObjectOptions.Builder.ifSourceETagMatches;
import static org.jclouds.s3.options.CopyObjectOptions.Builder.ifSourceModifiedSince;
import static org.jclouds.s3.options.CopyObjectOptions.Builder.ifSourceUnmodifiedSince;
import static org.jclouds.s3.options.CopyObjectOptions.Builder.overrideAcl;
import static org.jclouds.s3.options.CopyObjectOptions.Builder.overrideMetadataWith;
import static org.jclouds.s3.options.PutObjectOptions.Builder.withAcl;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertTrue;
import static org.testng.Assert.fail;
import java.io.IOException;
import java.net.URI;
import java.net.URL;
import java.util.Date;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.TimeUnit;
import org.jclouds.ContextBuilder;
import org.jclouds.aws.domain.SessionCredentials;
import org.jclouds.blobstore.KeyNotFoundException;
import org.jclouds.blobstore.domain.Blob;
import org.jclouds.blobstore.domain.PageSet;
import org.jclouds.blobstore.domain.StorageMetadata;
import org.jclouds.blobstore.integration.internal.BaseBlobStoreIntegrationTest;
import org.jclouds.blobstore.options.ListContainerOptions;
import org.jclouds.domain.Credentials;
import org.jclouds.http.HttpResponseException;
import org.jclouds.io.ByteStreams2;
import org.jclouds.io.Payload;
import org.jclouds.s3.domain.AccessControlList;
import org.jclouds.s3.domain.AccessControlList.CanonicalUserGrantee;
import org.jclouds.s3.domain.AccessControlList.EmailAddressGrantee;
import org.jclouds.s3.domain.AccessControlList.GroupGranteeURI;
import org.jclouds.s3.domain.AccessControlList.Permission;
import org.jclouds.s3.domain.CannedAccessPolicy;
import org.jclouds.s3.domain.DeleteResult;
import org.jclouds.s3.domain.ListMultipartUploadResponse;
import org.jclouds.s3.domain.ListMultipartUploadsResponse;
import org.jclouds.s3.domain.ObjectMetadata;
import org.jclouds.s3.domain.ObjectMetadataBuilder;
import org.jclouds.s3.domain.S3Object;
import org.jclouds.s3.options.PutObjectOptions;
import org.jclouds.util.Strings2;
import org.jclouds.utils.TestUtils;
import org.testng.annotations.Test;
import com.google.common.base.Supplier;
import com.google.common.base.Throwables;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Maps;
import com.google.common.hash.HashCode;
import com.google.common.io.ByteSource;
@Test(groups = { "integration", "live" })
public class S3ClientLiveTest extends BaseBlobStoreIntegrationTest {
public static final String TEST_ACL_ID = "1a405254c932b52e5b5caaa88186bc431a1bacb9ece631f835daddaf0c47677c";
public static final String TEST_ACL_EMAIL = "james@misterm.org";
public static final String DEFAULT_OWNER_ID = "abc123";
private static final ByteSource oneHundredOneConstitutions = TestUtils.randomByteSource().slice(0, 5 * 1024 * 1024 + 1);
protected String sessionToken;
public S3ClientLiveTest() {
this.provider = "s3";
}
@Override
protected Properties setupProperties() {
Properties overrides = super.setupProperties();
sessionToken = setIfTestSystemPropertyPresent(overrides, provider + ".sessionToken");
return overrides;
}
@Override
protected ContextBuilder newBuilder() {
ContextBuilder builder = super.newBuilder();
if (sessionToken != null) {
builder.credentialsSupplier(new Supplier<Credentials>() {
@Override
public Credentials get() {
return SessionCredentials.builder().identity(identity).credential(credential).sessionToken(sessionToken).build();
}
});
}
return builder;
}
public S3Client getApi() {
return view.unwrapApi(S3Client.class);
}
/**
* this method overrides containerName to ensure it isn't found
*/
@Test(groups = { "integration", "live" })
public void deleteContainerIfEmptyNotFound() throws Exception {
assert getApi().deleteBucketIfEmpty("dbienf");
}
@Test(groups = { "integration", "live" })
public void deleteContainerIfEmptyButHasContents() throws Exception {
String containerName = getContainerName();
try {
addBlobToContainer(containerName, "test");
assert !getApi().deleteBucketIfEmpty(containerName);
} finally {
returnContainer(containerName);
}
}
protected URL getObjectURL(String containerName, String key) throws Exception {
URL url = new URL(String.format("http://%s.%s/%s", containerName, URI.create(endpoint).getHost(), key));
return url;
}
@Test(groups = {"fails-on-s3proxy"})
public void testPutCannedAccessPolicyPublic() throws Exception {
String containerName = getContainerName();
try {
String key = "hello";
S3Object object = getApi().newS3Object();
object.getMetadata().setKey(key);
object.setPayload(TEST_STRING);
getApi().putObject(containerName, object,
withAcl(CannedAccessPolicy.PUBLIC_READ));
URL url = this.getObjectURL(containerName, key);
Strings2.toStringAndClose(url.openStream());
} finally {
returnContainer(containerName);
}
}
@Test(groups = {"fails-on-s3proxy"})
public void testCopyCannedAccessPolicyPublic() throws Exception {
String containerName = getContainerName();
String destinationContainer = getContainerName();
try {
addBlobToContainer(containerName, sourceKey);
validateContent(containerName, sourceKey);
getApi().copyObject(containerName, sourceKey, destinationContainer, destinationKey,
overrideAcl(CannedAccessPolicy.PUBLIC_READ));
validateContent(destinationContainer, destinationKey);
URL url = getObjectURL(destinationContainer, destinationKey);
Strings2.toStringAndClose(url.openStream());
} finally {
returnContainer(containerName);
returnContainer(destinationContainer);
}
}
String sourceKey = "apples";
String destinationKey = "pears";
@Test(groups = {"fails-on-s3proxy"})
public void testPublicWriteOnObject() throws InterruptedException, ExecutionException, TimeoutException, IOException {
final String publicReadWriteObjectKey = "public-read-write-acl";
final String containerName = getContainerName();
try {
S3Object object = getApi().newS3Object();
object.getMetadata().setKey(publicReadWriteObjectKey);
object.setPayload("");
// Public Read-Write object
getApi()
.putObject(containerName, object,
new PutObjectOptions().withAcl(CannedAccessPolicy.PUBLIC_READ_WRITE));
assertConsistencyAware(new Runnable() {
public void run() {
try {
AccessControlList acl = getApi().getObjectACL(containerName, publicReadWriteObjectKey);
assertEquals(acl.getGrants().size(), 3);
assertEquals(acl.getPermissions(GroupGranteeURI.ALL_USERS).size(), 2);
assertNotNull(acl.getOwner());
String ownerId = acl.getOwner().getId();
assertTrue(acl.hasPermission(ownerId, Permission.FULL_CONTROL));
assertTrue(acl.hasPermission(GroupGranteeURI.ALL_USERS, Permission.READ));
assertTrue(acl.hasPermission(GroupGranteeURI.ALL_USERS, Permission.WRITE));
assertFalse(acl.hasPermission(GroupGranteeURI.ALL_USERS, Permission.READ_ACP));
assertFalse(acl.hasPermission(GroupGranteeURI.ALL_USERS, Permission.WRITE_ACP));
assertFalse(acl.hasPermission(GroupGranteeURI.ALL_USERS, Permission.FULL_CONTROL));
} catch (Exception e) {
Throwables.propagateIfPossible(e);
}
}
});
} finally {
returnContainer(containerName);
}
}
@Test(groups = {"fails-on-s3proxy"})
public void testUpdateObjectACL() throws InterruptedException, ExecutionException, TimeoutException, IOException {
String containerName = getContainerName();
try {
String objectKey = "private-acl";
// Private object
addBlobToContainer(containerName, objectKey);
AccessControlList acl = getApi().getObjectACL(containerName, objectKey);
String ownerId = acl.getOwner().getId();
assertEquals(acl.getGrants().size(), 1);
assertTrue(acl.hasPermission(ownerId, Permission.FULL_CONTROL));
addGrantsToACL(acl);
assertEquals(acl.getGrants().size(), 4);
assertTrue(getApi().putObjectACL(containerName, objectKey, acl));
// Confirm that the updated ACL has stuck.
acl = getApi().getObjectACL(containerName, objectKey);
checkGrants(acl);
/*
* Revoke all of owner's permissions!
*/
acl.revokeAllPermissions(new CanonicalUserGrantee(ownerId));
if (!ownerId.equals(TEST_ACL_ID))
acl.revokeAllPermissions(new CanonicalUserGrantee(TEST_ACL_ID));
assertEquals(acl.getGrants().size(), 1);
// Only public read permission should remain...
assertTrue(acl.hasPermission(GroupGranteeURI.ALL_USERS, Permission.READ));
// Update the object's ACL settings
assertTrue(getApi().putObjectACL(containerName, objectKey, acl));
// Confirm that the updated ACL has stuck
acl = getApi().getObjectACL(containerName, objectKey);
assertEquals(acl.getGrants().size(), 1);
assertEquals(acl.getPermissions(ownerId).size(), 0);
assertTrue(acl.hasPermission(GroupGranteeURI.ALL_USERS, Permission.READ), acl.toString());
} finally {
returnContainer(containerName);
}
}
public void testPrivateAclIsDefaultForObject() throws InterruptedException, ExecutionException, TimeoutException,
IOException {
String privateObjectKey = "private-acl";
String containerName = getContainerName();
try {
// Private object
addBlobToContainer(containerName, privateObjectKey);
AccessControlList acl = getApi().getObjectACL(containerName, privateObjectKey);
assertEquals(acl.getGrants().size(), 1);
assertNotNull(acl.getOwner());
String ownerId = acl.getOwner().getId();
assertTrue(acl.hasPermission(ownerId, Permission.FULL_CONTROL));
} finally {
returnContainer(containerName);
}
}
public void testPublicReadOnObject() throws InterruptedException, ExecutionException, TimeoutException, IOException {
final String publicReadObjectKey = "public-read-acl";
final String containerName = getContainerName();
try {
S3Object object = getApi().newS3Object();
object.getMetadata().setKey(publicReadObjectKey);
object.setPayload("");
getApi().putObject(containerName, object, new PutObjectOptions().withAcl(CannedAccessPolicy.PUBLIC_READ));
assertConsistencyAware(new Runnable() {
public void run() {
try {
AccessControlList acl = getApi().getObjectACL(containerName, publicReadObjectKey);
assertEquals(acl.getGrants().size(), 2);
assertEquals(acl.getPermissions(GroupGranteeURI.ALL_USERS).size(), 1);
assertNotNull(acl.getOwner());
String ownerId = acl.getOwner().getId();
assertTrue(acl.hasPermission(ownerId, Permission.FULL_CONTROL));
assertTrue(acl.hasPermission(GroupGranteeURI.ALL_USERS, Permission.READ));
} catch (Exception e) {
Throwables.propagateIfPossible(e);
}
}
});
} finally {
returnContainer(containerName);
}
}
protected String addBlobToContainer(String sourceContainer, String key) {
S3Object sourceObject = getApi().newS3Object();
sourceObject.getMetadata().setKey(key);
sourceObject.getMetadata().getContentMetadata().setContentType("text/xml");
sourceObject.setPayload(TEST_STRING);
return getApi().putObject(sourceContainer, sourceObject);
}
protected S3Object validateObject(String sourceContainer, String key) throws InterruptedException,
ExecutionException, TimeoutException, IOException {
assertConsistencyAwareContainerSize(sourceContainer, 1);
S3Object newObject = getApi().getObject(sourceContainer, key);
assert newObject != null;
assertEquals(Strings2.toStringAndClose(newObject.getPayload().openStream()), TEST_STRING);
return newObject;
}
public void testMetadataWithCacheControlAndContentDisposition() throws Exception {
String key = "hello";
S3Object object = getApi().newS3Object();
object.getMetadata().setKey(key);
object.setPayload(TEST_STRING);
object.getMetadata().setCacheControl("no-cache");
object.getMetadata().getContentMetadata().setContentDisposition("attachment; filename=hello.txt");
String containerName = getContainerName();
try {
getApi().putObject(containerName, object);
S3Object newObject = validateObject(containerName, key);
assertCacheControl(newObject, "no-cache");
assertEquals(newObject.getMetadata().getContentMetadata().getContentDisposition(),
"attachment; filename=hello.txt");
} finally {
returnContainer(containerName);
}
}
protected void assertCacheControl(S3Object newObject, String string) {
assert newObject.getMetadata().getCacheControl().indexOf(string) != -1 : newObject.getMetadata()
.getCacheControl();
}
protected void assertContentEncoding(S3Object newObject, String string) {
assert newObject.getPayload().getContentMetadata().getContentEncoding().indexOf(string) != -1 : newObject
.getPayload().getContentMetadata().getContentEncoding();
assert newObject.getMetadata().getContentMetadata().getContentEncoding().indexOf(string) != -1 : newObject
.getMetadata().getContentMetadata().getContentEncoding();
}
@Test(groups = { "integration", "live" })
public void testMetadataContentEncoding() throws Exception {
String key = "hello";
S3Object object = getApi().newS3Object();
object.getMetadata().setKey(key);
object.setPayload(TEST_STRING);
object.getMetadata().getContentMetadata().setContentEncoding("x-compress");
String containerName = getContainerName();
try {
getApi().putObject(containerName, object);
S3Object newObject = validateObject(containerName, key);
assertContentEncoding(newObject, "x-compress");
} finally {
returnContainer(containerName);
}
}
public void testCopyObject() throws Exception {
String containerName = getContainerName();
String destinationContainer = getContainerName();
try {
addToContainerAndValidate(containerName, sourceKey);
getApi().copyObject(containerName, sourceKey, destinationContainer, destinationKey);
validateContent(destinationContainer, destinationKey);
} finally {
returnContainer(containerName);
returnContainer(destinationContainer);
}
}
public void testCopyObjectWithSourceKeyRequiringEncoding() throws Exception {
String containerName = getContainerName();
String sourceKeyRequiringEncoding = "apples#?:$&'\"<>čॐ";
String destinationContainer = getContainerName();
try {
addToContainerAndValidate(containerName, sourceKeyRequiringEncoding);
getApi().copyObject(containerName, sourceKeyRequiringEncoding, destinationContainer, destinationKey);
validateContent(destinationContainer, destinationKey);
} finally {
returnContainer(containerName);
returnContainer(destinationContainer);
}
}
protected String addToContainerAndValidate(String containerName, String sourceKey) throws InterruptedException,
ExecutionException, TimeoutException, IOException {
String etag = addBlobToContainer(containerName, sourceKey);
validateContent(containerName, sourceKey);
return etag;
}
public void testCopyIfModifiedSince() throws InterruptedException, ExecutionException, TimeoutException, IOException {
String containerName = getContainerName();
String destinationContainer = getContainerName();
try {
Date before = new Date(System.currentTimeMillis() - 10 * 1000);
addToContainerAndValidate(containerName, sourceKey + "mod");
Date after = new Date(System.currentTimeMillis() + 10 * 1000);
getApi().copyObject(containerName, sourceKey + "mod", destinationContainer, destinationKey,
ifSourceModifiedSince(before));
validateContent(destinationContainer, destinationKey);
// Sleep since Amazon returns 200 if the date is in the future:
// https://forums.aws.amazon.com/message.jspa?messageID=325930
TimeUnit.SECONDS.sleep(20);
try {
getApi().copyObject(containerName, sourceKey + "mod", destinationContainer, destinationKey,
ifSourceModifiedSince(after));
fail("should have thrown HttpResponseException");
} catch (HttpResponseException ex) {
assertEquals(ex.getResponse().getStatusCode(), 412);
}
} finally {
returnContainer(containerName);
returnContainer(destinationContainer);
}
}
public void testCopyIfUnmodifiedSince() throws InterruptedException, ExecutionException, TimeoutException,
IOException {
String containerName = getContainerName();
String destinationContainer = getContainerName();
try {
Date before = new Date(System.currentTimeMillis() - 10 * 1000);
addToContainerAndValidate(containerName, sourceKey + "un");
Date after = new Date(System.currentTimeMillis() + 10 * 1000);
getApi().copyObject(containerName, sourceKey + "un", destinationContainer, destinationKey,
ifSourceUnmodifiedSince(after));
validateContent(destinationContainer, destinationKey);
try {
getApi().copyObject(containerName, sourceKey + "un", destinationContainer, destinationKey,
ifSourceUnmodifiedSince(before));
fail("should have thrown HttpResponseException");
} catch (HttpResponseException ex) {
assertEquals(ex.getResponse().getStatusCode(), 412);
}
} finally {
returnContainer(containerName);
returnContainer(destinationContainer);
}
}
public void testCopyIfMatch() throws InterruptedException, ExecutionException, TimeoutException, IOException {
String containerName = getContainerName();
String destinationContainer = getContainerName();
try {
String goodETag = addToContainerAndValidate(containerName, sourceKey);
getApi().copyObject(containerName, sourceKey, destinationContainer, destinationKey,
ifSourceETagMatches(goodETag));
validateContent(destinationContainer, destinationKey);
try {
getApi().copyObject(containerName, sourceKey, destinationContainer, destinationKey,
ifSourceETagMatches("setsds"));
} catch (HttpResponseException ex) {
assertEquals(ex.getResponse().getStatusCode(), 412);
}
} finally {
returnContainer(containerName);
returnContainer(destinationContainer);
}
}
public void testCopyIfNoneMatch() throws IOException, InterruptedException, ExecutionException, TimeoutException {
String containerName = getContainerName();
String destinationContainer = getContainerName();
try {
String goodETag = addToContainerAndValidate(containerName, sourceKey);
getApi().copyObject(containerName, sourceKey, destinationContainer, destinationKey,
ifSourceETagDoesntMatch("asfasdf"));
validateContent(destinationContainer, destinationKey);
try {
getApi().copyObject(containerName, sourceKey, destinationContainer, destinationKey,
ifSourceETagDoesntMatch(goodETag));
} catch (HttpResponseException ex) {
assertEquals(ex.getResponse().getStatusCode(), 412);
}
} finally {
returnContainer(containerName);
returnContainer(destinationContainer);
}
}
public void testCopyWithMetadata() throws InterruptedException, ExecutionException, TimeoutException, IOException {
String containerName = getContainerName();
String destinationContainer = getContainerName();
try {
addToContainerAndValidate(containerName, sourceKey);
Map<String, String> metadata = Maps.newHashMap();
metadata.put("adrian", "cole");
getApi().copyObject(containerName, sourceKey, destinationContainer, destinationKey,
overrideMetadataWith(metadata));
validateContent(destinationContainer, destinationKey);
ObjectMetadata objectMeta = getApi().headObject(destinationContainer, destinationKey);
assertEquals(objectMeta.getUserMetadata(), metadata);
} finally {
returnContainer(containerName);
returnContainer(destinationContainer);
}
}
// JCLOUDS-1401
public void testUnusualKeyCharacters() throws InterruptedException, ExecutionException, TimeoutException, IOException {
String containerName = getContainerName();
try {
String dirName = "a%2Fb&xxx#?:$'\\\"<>čॐ";
String fileName = "foo%3Abar.xml";
addToContainerAndValidate(containerName, dirName + '/' + fileName);
PageSet<? extends StorageMetadata> list = view.getBlobStore().list(containerName,
ListContainerOptions.Builder.prefix(dirName + "/"));
assertEquals(list.size(), 1);
StorageMetadata md = list.iterator().next();
assertEquals(md.getName(), dirName + '/' + fileName);
} finally {
returnContainer(containerName);
}
}
public void testMultipartSynchronously() throws InterruptedException, IOException {
HashCode oneHundredOneConstitutionsMD5 = oneHundredOneConstitutions.hash(md5());
String containerName = getContainerName();
S3Object object = null;
try {
String key = "constitution.txt";
String uploadId = getApi().initiateMultipartUpload(containerName,
ObjectMetadataBuilder.create().key(key).contentMD5(oneHundredOneConstitutionsMD5.asBytes()).build());
assertThat(getApi().listMultipartPartsFull(containerName, key, uploadId)).isEmpty();
byte[] buffer = oneHundredOneConstitutions.read();
assertEquals(oneHundredOneConstitutions.size(), (long) buffer.length);
Payload part1 = newByteArrayPayload(buffer);
part1.getContentMetadata().setContentLength((long) buffer.length);
part1.getContentMetadata().setContentMD5(oneHundredOneConstitutionsMD5);
String eTagOf1 = null;
try {
eTagOf1 = getApi().uploadPart(containerName, key, 1, uploadId, part1);
} catch (KeyNotFoundException e) {
// note that because of eventual consistency, the upload id may not be present yet
// we may wish to add this condition to the retry handler
// we may also choose to implement ListParts and wait for the uploadId to become
// available there.
eTagOf1 = getApi().uploadPart(containerName, key, 1, uploadId, part1);
}
Map<Integer, ListMultipartUploadResponse> map = getApi().listMultipartPartsFull(containerName, key, uploadId);
assertThat(map).containsOnlyKeys(1);
assertThat(map.get(1).eTag()).isEqualTo(eTagOf1);
getApi().completeMultipartUpload(containerName, key, uploadId, ImmutableMap.of(1, eTagOf1));
object = getApi().getObject(containerName, key);
assertEquals(ByteStreams2.toByteArrayAndClose(object.getPayload().openStream()), buffer);
} finally {
if (object != null)
object.getPayload().close();
returnContainer(containerName);
}
}
public void testMultipartCopy() throws Exception {
String containerName = getContainerName();
try {
String fromObject = "fromObject";
S3Object object = getApi().newS3Object();
object.getMetadata().setKey(fromObject);
object.setPayload(oneHundredOneConstitutions);
object.getMetadata().getContentMetadata().setContentLength(oneHundredOneConstitutions.size());
getApi().putObject(containerName, object);
String toObject = "toObject";
String uploadId = getApi().initiateMultipartUpload(containerName, ObjectMetadataBuilder.create().key(toObject).build());
String eTagOf1 = getApi().uploadPartCopy(containerName, toObject, 1, uploadId, containerName, fromObject, 1, oneHundredOneConstitutions.size() - 1);
getApi().completeMultipartUpload(containerName, toObject, uploadId, ImmutableMap.of(1, eTagOf1));
object = getApi().getObject(containerName, toObject);
assertEquals(ByteStreams2.toByteArrayAndClose(object.getPayload().openStream()), oneHundredOneConstitutions.slice(1, oneHundredOneConstitutions.size() - 1).read());
} finally {
returnContainer(containerName);
}
}
public void testListMultipartUploads() throws Exception {
String containerName = getContainerName();
String key = "testListMultipartUploads";
String uploadId = null;
try {
ListMultipartUploadsResponse response = getApi().listMultipartUploads(containerName, null, null, null, null, null);
assertThat(response.bucket()).isEqualTo(containerName);
assertThat(response.isTruncated()).isFalse();
assertThat(response.uploads()).isEmpty();
uploadId = getApi().initiateMultipartUpload(containerName, ObjectMetadataBuilder.create().key(key).build());
response = getApi().listMultipartUploads(containerName, null, null, null, null, null);
assertThat(response.bucket()).isEqualTo(containerName);
assertThat(response.isTruncated()).isFalse();
assertThat(response.uploads()).hasSize(1);
ListMultipartUploadsResponse.Upload upload = response.uploads().get(0);
assertThat(upload.key()).isEqualTo(key);
assertThat(upload.uploadId()).isEqualTo(uploadId);
assertThat(upload.storageClass()).isEqualTo(ObjectMetadata.StorageClass.STANDARD);
} finally {
if (uploadId != null) {
getApi().abortMultipartUpload(containerName, key, uploadId);
}
returnContainer(containerName);
}
}
public void testDeleteMultipleObjects() throws InterruptedException {
String container = getContainerName();
try {
ImmutableSet.Builder<String> builder = ImmutableSet.builder();
for (int i = 0; i < 5; i++) {
String key = UUID.randomUUID().toString();
Blob blob = view.getBlobStore().blobBuilder(key).payload("").build();
view.getBlobStore().putBlob(container, blob);
builder.add(key);
}
Set<String> keys = builder.build();
DeleteResult result = getApi().deleteObjects(container, keys);
assertTrue(result.getDeleted().containsAll(keys));
assertEquals(result.getErrors().size(), 0);
for (String key : keys) {
assertConsistencyAwareBlobDoesntExist(container, key);
}
} finally {
returnContainer(container);
}
}
private void checkGrants(AccessControlList acl) {
String ownerId = acl.getOwner().getId();
assertEquals(acl.getGrants().size(), 4, acl.toString());
assertTrue(acl.hasPermission(ownerId, Permission.FULL_CONTROL), acl.toString());
assertTrue(acl.hasPermission(GroupGranteeURI.ALL_USERS, Permission.READ), acl.toString());
assertTrue(acl.hasPermission(ownerId, Permission.WRITE_ACP), acl.toString());
// EmailAddressGrantee is replaced by a CanonicalUserGrantee, so we cannot test by email addr
assertTrue(acl.hasPermission(TEST_ACL_ID, Permission.READ_ACP), acl.toString());
}
private void addGrantsToACL(AccessControlList acl) {
String ownerId = acl.getOwner().getId();
acl.addPermission(GroupGranteeURI.ALL_USERS, Permission.READ);
acl.addPermission(new EmailAddressGrantee(TEST_ACL_EMAIL), Permission.READ_ACP);
acl.addPermission(new CanonicalUserGrantee(ownerId), Permission.WRITE_ACP);
}
public void testUpdateBucketCannedACL() throws Exception {
String containerName = getContainerName();
try {
getApi().updateBucketCannedACL(containerName, CannedAccessPolicy.PUBLIC_READ);
AccessControlList acl = getApi().getBucketACL(containerName);
assertThat(acl.hasPermission(GroupGranteeURI.ALL_USERS, Permission.READ)).isTrue();
getApi().updateBucketCannedACL(containerName, CannedAccessPolicy.PRIVATE);
acl = getApi().getBucketACL(containerName);
assertThat(acl.hasPermission(GroupGranteeURI.ALL_USERS, Permission.READ)).isFalse();
} finally {
recycleContainerAndAddToPool(containerName);
}
}
public void testUpdateObjectCannedACL() throws Exception {
String containerName = getContainerName();
try {
String key = "testUpdateObjectCannedACL";
S3Object object = getApi().newS3Object();
object.getMetadata().setKey(key);
object.setPayload(TEST_STRING);
getApi().putObject(containerName, object);
getApi().updateObjectCannedACL(containerName, key, CannedAccessPolicy.PUBLIC_READ);
AccessControlList acl = getApi().getObjectACL(containerName, key);
assertThat(acl.hasPermission(GroupGranteeURI.ALL_USERS, Permission.READ)).isTrue();
getApi().updateObjectCannedACL(containerName, key, CannedAccessPolicy.PRIVATE);
acl = getApi().getObjectACL(containerName, key);
assertThat(acl.hasPermission(GroupGranteeURI.ALL_USERS, Permission.READ)).isFalse();
object = getApi().getObject(containerName, key);
assertThat(Strings2.toStringAndClose(object.getPayload().openStream())).isEqualTo(TEST_STRING);
} finally {
returnContainer(containerName);
}
}
}