Skip to content

Commit

Permalink
Merge pull request #688 from aozarov/master
Browse files Browse the repository at this point in the history
Add a versions option to BlobListOption
  • Loading branch information
mziccard committed Mar 1, 2016
2 parents bbe7b50 + e66c9a4 commit 3930ff9
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -700,6 +700,15 @@ public static BlobListOption recursive(boolean recursive) {
return new BlobListOption(StorageRpc.Option.DELIMITER, recursive);
}

/**
* If set to {@code true}, lists all versions of a blob. The default is {@code false}.
*
* @see <a href ="https://cloud.google.com/storage/docs/object-versioning">Object Versioning</a>
*/
public static BlobListOption versions(boolean versions) {
return new BlobListOption(StorageRpc.Option.VERSIONS, versions);
}

/**
* Returns an option to specify the blob's fields to be returned by the RPC call. If this option
* is not provided all blob's fields are returned. {@code BlobListOption.fields}) can be used to
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import com.google.gcloud.RetryParams;
import com.google.gcloud.storage.BlobInfo;
import com.google.gcloud.storage.Storage;
import com.google.gcloud.storage.Storage.BlobListOption;
import com.google.gcloud.storage.StorageException;
import com.google.gcloud.storage.StorageOptions;

Expand Down Expand Up @@ -173,8 +174,8 @@ public DeleteBucketTask(Storage storage, String bucket) {
@Override
public Boolean call() {
while (true) {
for (BlobInfo info : storage.list(bucket).values()) {
storage.delete(bucket, info.name());
for (BlobInfo info : storage.list(bucket, BlobListOption.versions(true)).values()) {
storage.delete(info.blobId());
}
try {
storage.delete(bucket);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

import com.google.common.collect.ImmutableList;
import com.google.gcloud.Page;
import com.google.gcloud.storage.Storage.BlobListOption;
import com.google.gcloud.storage.testing.RemoteGcsHelper;

import org.easymock.EasyMock;
Expand Down Expand Up @@ -117,9 +118,10 @@ public Iterator<Blob> iterateAll() {
@Test
public void testForceDelete() throws InterruptedException, ExecutionException {
Storage storageMock = EasyMock.createMock(Storage.class);
EasyMock.expect(storageMock.list(BUCKET_NAME)).andReturn(blobPage);
EasyMock.expect(storageMock.list(BUCKET_NAME, BlobListOption.versions(true)))
.andReturn(blobPage);
for (BlobInfo info : blobList) {
EasyMock.expect(storageMock.delete(BUCKET_NAME, info.name())).andReturn(true);
EasyMock.expect(storageMock.delete(info.blobId())).andReturn(true);
}
EasyMock.expect(storageMock.delete(BUCKET_NAME)).andReturn(true);
EasyMock.replay(storageMock);
Expand All @@ -132,7 +134,7 @@ public void testForceDeleteTimeout() throws InterruptedException, ExecutionExcep
Storage storageMock = EasyMock.createMock(Storage.class);
EasyMock.expect(storageMock.list(BUCKET_NAME)).andReturn(blobPage).anyTimes();
for (BlobInfo info : blobList) {
EasyMock.expect(storageMock.delete(BUCKET_NAME, info.name())).andReturn(true).anyTimes();
EasyMock.expect(storageMock.delete(info.blobId())).andReturn(true).anyTimes();
}
EasyMock.expect(storageMock.delete(BUCKET_NAME)).andThrow(RETRYABLE_EXCEPTION).anyTimes();
EasyMock.replay(storageMock);
Expand All @@ -143,9 +145,10 @@ public void testForceDeleteTimeout() throws InterruptedException, ExecutionExcep
@Test
public void testForceDeleteFail() throws InterruptedException, ExecutionException {
Storage storageMock = EasyMock.createMock(Storage.class);
EasyMock.expect(storageMock.list(BUCKET_NAME)).andReturn(blobPage);
EasyMock.expect(storageMock.list(BUCKET_NAME, BlobListOption.versions(true)))
.andReturn(blobPage);
for (BlobInfo info : blobList) {
EasyMock.expect(storageMock.delete(BUCKET_NAME, info.name())).andReturn(true);
EasyMock.expect(storageMock.delete(info.blobId())).andReturn(true);
}
EasyMock.expect(storageMock.delete(BUCKET_NAME)).andThrow(FATAL_EXCEPTION);
EasyMock.replay(storageMock);
Expand All @@ -160,9 +163,10 @@ public void testForceDeleteFail() throws InterruptedException, ExecutionExceptio
@Test
public void testForceDeleteNoTimeout() {
Storage storageMock = EasyMock.createMock(Storage.class);
EasyMock.expect(storageMock.list(BUCKET_NAME)).andReturn(blobPage);
EasyMock.expect(storageMock.list(BUCKET_NAME, BlobListOption.versions(true)))
.andReturn(blobPage);
for (BlobInfo info : blobList) {
EasyMock.expect(storageMock.delete(BUCKET_NAME, info.name())).andReturn(true);
EasyMock.expect(storageMock.delete(info.blobId())).andReturn(true);
}
EasyMock.expect(storageMock.delete(BUCKET_NAME)).andReturn(true);
EasyMock.replay(storageMock);
Expand All @@ -173,9 +177,10 @@ public void testForceDeleteNoTimeout() {
@Test
public void testForceDeleteNoTimeoutFail() {
Storage storageMock = EasyMock.createMock(Storage.class);
EasyMock.expect(storageMock.list(BUCKET_NAME)).andReturn(blobPage);
EasyMock.expect(storageMock.list(BUCKET_NAME, BlobListOption.versions(true)))
.andReturn(blobPage);
for (BlobInfo info : blobList) {
EasyMock.expect(storageMock.delete(BUCKET_NAME, info.name())).andReturn(true);
EasyMock.expect(storageMock.delete(info.blobId())).andReturn(true);
}
EasyMock.expect(storageMock.delete(BUCKET_NAME)).andThrow(FATAL_EXCEPTION);
EasyMock.replay(storageMock);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -200,11 +200,14 @@ public class StorageImplTest {
Storage.BlobListOption.prefix("prefix");
private static final Storage.BlobListOption BLOB_LIST_FIELDS =
Storage.BlobListOption.fields(Storage.BlobField.CONTENT_TYPE, Storage.BlobField.MD5HASH);
private static final Storage.BlobListOption BLOB_LIST_VERSIONS =
Storage.BlobListOption.versions(false);
private static final Storage.BlobListOption BLOB_LIST_EMPTY_FIELDS =
Storage.BlobListOption.fields();
private static final Map<StorageRpc.Option, ?> BLOB_LIST_OPTIONS = ImmutableMap.of(
StorageRpc.Option.MAX_RESULTS, BLOB_LIST_MAX_RESULT.value(),
StorageRpc.Option.PREFIX, BLOB_LIST_PREFIX.value());
StorageRpc.Option.PREFIX, BLOB_LIST_PREFIX.value(),
StorageRpc.Option.VERSIONS, BLOB_LIST_VERSIONS.value());

private static final String PRIVATE_KEY_STRING = "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoG"
+ "BAL2xolH1zrISQ8+GzOV29BNjjzq4/HIP8Psd1+cZb81vDklSF+95wB250MSE0BDc81pvIMwj5OmIfLg1NY6uB"
Expand Down Expand Up @@ -650,7 +653,8 @@ public void testListBlobsWithOptions() {
EasyMock.replay(storageRpcMock);
initializeService();
ImmutableList<Blob> blobList = ImmutableList.of(expectedBlob1, expectedBlob2);
Page<Blob> page = storage.list(BUCKET_NAME1, BLOB_LIST_MAX_RESULT, BLOB_LIST_PREFIX);
Page<Blob> page =
storage.list(BUCKET_NAME1, BLOB_LIST_MAX_RESULT, BLOB_LIST_PREFIX, BLOB_LIST_VERSIONS);
assertEquals(cursor, page.nextPageCursor());
assertArrayEquals(blobList.toArray(), Iterables.toArray(page.values(), Blob.class));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import com.google.api.client.util.Lists;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.gcloud.Page;
import com.google.gcloud.ReadChannel;
import com.google.gcloud.RestorableState;
Expand Down Expand Up @@ -63,6 +64,7 @@
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
Expand Down Expand Up @@ -302,8 +304,7 @@ public void testListBlobsSelectedFields() {
Blob remoteBlob2 = storage.create(blob2);
assertNotNull(remoteBlob1);
assertNotNull(remoteBlob2);
Page<Blob> page =
storage.list(BUCKET,
Page<Blob> page = storage.list(BUCKET,
Storage.BlobListOption.prefix("test-list-blobs-selected-fields-blob"),
Storage.BlobListOption.fields(BlobField.METADATA));
int index = 0;
Expand Down Expand Up @@ -331,8 +332,7 @@ public void testListBlobsEmptySelectedFields() {
Blob remoteBlob2 = storage.create(blob2);
assertNotNull(remoteBlob1);
assertNotNull(remoteBlob2);
Page<Blob> page = storage.list(
BUCKET,
Page<Blob> page = storage.list(BUCKET,
Storage.BlobListOption.prefix("test-list-blobs-empty-selected-fields-blob"),
Storage.BlobListOption.fields());
int index = 0;
Expand All @@ -345,6 +345,41 @@ public void testListBlobsEmptySelectedFields() {
assertTrue(remoteBlob2.delete());
}

@Test
public void testListBlobsVersioned() throws ExecutionException, InterruptedException {
String bucketName = RemoteGcsHelper.generateBucketName();
Bucket bucket = storage.create(BucketInfo.builder(bucketName).versioningEnabled(true).build());
try {
String[] blobNames = {"test-list-blobs-versioned-blob1", "test-list-blobs-versioned-blob2"};
BlobInfo blob1 = BlobInfo.builder(bucket, blobNames[0])
.contentType(CONTENT_TYPE)
.build();
BlobInfo blob2 = BlobInfo.builder(bucket, blobNames[1])
.contentType(CONTENT_TYPE)
.build();
Blob remoteBlob1 = storage.create(blob1);
Blob remoteBlob2 = storage.create(blob2);
Blob remoteBlob3 = storage.create(blob2);
assertNotNull(remoteBlob1);
assertNotNull(remoteBlob2);
assertNotNull(remoteBlob3);
Page<Blob> page = storage.list(bucketName,
Storage.BlobListOption.prefix("test-list-blobs-versioned-blob"),
Storage.BlobListOption.versions(true));
Set<String> blobSet = ImmutableSet.of(blobNames[0], blobNames[1]);
for (Blob remoteBlob : page.values()) {
assertEquals(bucketName, remoteBlob.bucket());
assertTrue(blobSet.contains(remoteBlob.name()));
assertNotNull(remoteBlob.generation());
}
assertTrue(remoteBlob1.delete());
assertTrue(remoteBlob2.delete());
assertTrue(remoteBlob3.delete());
} finally {
RemoteGcsHelper.forceDelete(storage, bucketName, 5, TimeUnit.SECONDS);
}
}

@Test
public void testUpdateBlob() {
String blobName = "test-update-blob";
Expand Down

0 comments on commit 3930ff9

Please sign in to comment.