diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/ListResult.java b/gcloud-java-core/src/main/java/com/google/gcloud/Page.java similarity index 58% rename from gcloud-java-storage/src/main/java/com/google/gcloud/storage/ListResult.java rename to gcloud-java-core/src/main/java/com/google/gcloud/Page.java index 62b1f442310c..1b7754562716 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/ListResult.java +++ b/gcloud-java-core/src/main/java/com/google/gcloud/Page.java @@ -14,12 +14,29 @@ * limitations under the License. */ -package com.google.gcloud.storage; +package com.google.gcloud; /** - * Interface for Google Cloud storage list result. + * Interface for Google Cloud paginated results. + * + *

+ * A typical {@code Page} usage: + *

 {@code
+ * Page page = ...; // get a Page instance
+ * while (page != null) {
+ *   for (T value : page.values()) {
+ *     // do something with value
+ *   }
+ *   page = page.nextPage();
+ * }
+ * }
*/ -public interface ListResult extends Iterable { +public interface Page { + + /** + * Returns the values contained in this page. + */ + Iterable values(); /** * Returns the cursor for the nextPage or {@code null} if no more results. @@ -27,8 +44,8 @@ public interface ListResult extends Iterable { String nextPageCursor(); /** - * Returns the results of the nextPage or {@code null} if no more result. + * Returns the next page of results or {@code null} if no more result. */ - ListResult nextPage(); + Page nextPage(); } diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/BaseListResult.java b/gcloud-java-core/src/main/java/com/google/gcloud/PageImpl.java similarity index 65% rename from gcloud-java-storage/src/main/java/com/google/gcloud/storage/BaseListResult.java rename to gcloud-java-core/src/main/java/com/google/gcloud/PageImpl.java index fdcd84705555..3925079c8d4b 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/BaseListResult.java +++ b/gcloud-java-core/src/main/java/com/google/gcloud/PageImpl.java @@ -14,52 +14,55 @@ * limitations under the License. */ -package com.google.gcloud.storage; +package com.google.gcloud; import java.io.Serializable; import java.util.Collections; -import java.util.Iterator; import java.util.Objects; /** - * Base implementation for Google Cloud storage list result. + * Base implementation for Google Cloud paginated results. */ -public class BaseListResult implements ListResult, Serializable { +public class PageImpl implements Page, Serializable { - private static final long serialVersionUID = -6937287874908527950L; + private static final long serialVersionUID = 3914827379823557934L; private final String cursor; private final Iterable results; private final NextPageFetcher pageFetcher; - public interface NextPageFetcher extends Serializable { - ListResult nextPage(); + public interface NextPageFetcher extends Serializable { + Page nextPage(); } - public BaseListResult(NextPageFetcher pageFetcher, String cursor, Iterable results) { + /** + * Creates a {@code PageImpl} object. In order for the object to be serializable the {@code + * results} parameter must be serializable. + */ + public PageImpl(NextPageFetcher pageFetcher, String cursor, Iterable results) { this.pageFetcher = pageFetcher; this.cursor = cursor; this.results = results; } + @Override + public Iterable values() { + return results == null ? Collections.EMPTY_LIST : results; + } + @Override public String nextPageCursor() { return cursor; } @Override - public ListResult nextPage() { + public Page nextPage() { if (cursor == null || pageFetcher == null) { return null; } return pageFetcher.nextPage(); } - @Override - public Iterator iterator() { - return results == null ? Collections.emptyIterator() : results.iterator(); - } - @Override public int hashCode() { return Objects.hash(cursor, results); @@ -67,10 +70,10 @@ public int hashCode() { @Override public boolean equals(Object obj) { - if (!(obj instanceof BaseListResult)) { + if (!(obj instanceof PageImpl)) { return false; } - BaseListResult other = (BaseListResult) obj; + PageImpl other = (PageImpl) obj; return Objects.equals(cursor, other.cursor) && Objects.equals(results, other.results); } diff --git a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/BaseListResultTest.java b/gcloud-java-core/src/test/java/com/google/gcloud/PageImplTest.java similarity index 65% rename from gcloud-java-storage/src/test/java/com/google/gcloud/storage/BaseListResultTest.java rename to gcloud-java-core/src/test/java/com/google/gcloud/PageImplTest.java index 4c22edbc35c8..78aa3feaa281 100644 --- a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/BaseListResultTest.java +++ b/gcloud-java-core/src/test/java/com/google/gcloud/PageImplTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.storage; +package com.google.gcloud; import static org.junit.Assert.assertEquals; @@ -24,24 +24,23 @@ import java.util.Collections; -public class BaseListResultTest { +public class PageImplTest { @Test - public void testListResult() throws Exception { + public void testPage() throws Exception { ImmutableList values = ImmutableList.of("1", "2"); - final BaseListResult nextResult = - new BaseListResult<>(null, "c", Collections.emptyList()); - BaseListResult.NextPageFetcher fetcher = new BaseListResult.NextPageFetcher() { + final PageImpl nextResult = + new PageImpl<>(null, "c", Collections.emptyList()); + PageImpl.NextPageFetcher fetcher = new PageImpl.NextPageFetcher() { @Override - public BaseListResult nextPage() { + public PageImpl nextPage() { return nextResult; } }; - BaseListResult result = new BaseListResult<>(fetcher, "c", values); + PageImpl result = new PageImpl<>(fetcher, "c", values); assertEquals(nextResult, result.nextPage()); assertEquals("c", result.nextPageCursor()); - assertEquals(values, ImmutableList.copyOf(result.iterator())); - + assertEquals(values, ImmutableList.copyOf(result.values().iterator())); } } diff --git a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/StorageExample.java b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/StorageExample.java index fb207023203f..7cf7fe2454fc 100644 --- a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/StorageExample.java +++ b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/StorageExample.java @@ -18,6 +18,7 @@ import com.google.gcloud.AuthCredentials; import com.google.gcloud.AuthCredentials.ServiceAccountAuthCredentials; +import com.google.gcloud.Page; import com.google.gcloud.RetryParams; import com.google.gcloud.spi.StorageRpc.Tuple; import com.google.gcloud.storage.Blob; @@ -213,8 +214,12 @@ String parse(String... args) { public void run(Storage storage, String bucketName) { if (bucketName == null) { // list buckets - for (BucketInfo b : storage.list()) { - System.out.println(b); + Page bucketPage = storage.list(); + while (bucketPage != null) { + for (BucketInfo b : bucketPage.values()) { + System.out.println(b); + } + bucketPage = bucketPage.nextPage(); } } else { // list a bucket's blobs @@ -223,8 +228,12 @@ public void run(Storage storage, String bucketName) { System.out.println("No such bucket"); return; } - for (Blob b : bucket.list()) { - System.out.println(b.info()); + Page blobPage = bucket.list(); + while (blobPage != null) { + for (Blob b : blobPage.values()) { + System.out.println(b.info()); + } + blobPage = blobPage.nextPage(); } } } diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/BlobListResult.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/BlobListResult.java deleted file mode 100644 index 9e6ec9dc5655..000000000000 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/BlobListResult.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed 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 com.google.gcloud.storage; - -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.common.base.Function; -import com.google.common.collect.Iterators; - -import java.util.Iterator; -import java.util.Objects; - -/** - * Implementation of a paginated list of Google Cloud storage {@code Blob}. - */ -public class BlobListResult implements ListResult { - - private final ListResult infoList; - private final Storage storage; - - public BlobListResult(Storage storage, ListResult infoList) { - this.storage = checkNotNull(storage); - this.infoList = checkNotNull(infoList); - } - - @Override - public String nextPageCursor() { - return infoList.nextPageCursor(); - } - - @Override - public ListResult nextPage() { - ListResult nextPageInfoList = infoList.nextPage(); - if (nextPageInfoList == null) { - return null; - } - return new BlobListResult(storage, nextPageInfoList); - } - - @Override - public Iterator iterator() { - return Iterators.transform(infoList.iterator(), new Function() { - @Override - public Blob apply(BlobInfo info) { - return new Blob(storage, info); - } - }); - } - - @Override - public int hashCode() { - return Objects.hash(infoList); - } - - @Override - public boolean equals(Object obj) { - if (!(obj instanceof BlobListResult)) { - return false; - } - BlobListResult other = (BlobListResult) obj; - return Objects.equals(infoList, other.infoList); - } -} diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Bucket.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Bucket.java index 8d696dc2ab6b..1f696d07ac33 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Bucket.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Bucket.java @@ -19,16 +19,24 @@ import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; +import com.google.common.base.Function; import com.google.common.base.MoreObjects; +import com.google.common.collect.Iterators; +import com.google.gcloud.PageImpl; +import com.google.gcloud.Page; import com.google.gcloud.storage.Storage.BlobSourceOption; import com.google.gcloud.storage.Storage.BlobTargetOption; import com.google.gcloud.storage.Storage.BlobWriteOption; import com.google.gcloud.storage.Storage.BucketSourceOption; import com.google.gcloud.storage.Storage.BucketTargetOption; -import java.io.InputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.ObjectInputStream; +import java.io.Serializable; import java.util.ArrayList; import java.util.Collections; +import java.util.Iterator; import java.util.List; import java.util.Objects; @@ -46,6 +54,71 @@ public final class Bucket { private final Storage storage; private final BucketInfo info; + private static class BlobPageFetcher implements PageImpl.NextPageFetcher { + + private static final long serialVersionUID = 3221100177471323801L; + + private final StorageOptions options; + private final Page infoPage; + + BlobPageFetcher(StorageOptions options, Page infoPage) { + this.options = options; + this.infoPage = infoPage; + } + + @Override + public Page nextPage() { + Page nextInfoPage = infoPage.nextPage(); + return new PageImpl(new BlobPageFetcher(options, nextInfoPage), + nextInfoPage.nextPageCursor(), new LazyBlobIterable(options, nextInfoPage.values())); + } + } + + private static class LazyBlobIterable implements Iterable, Serializable { + + private static final long serialVersionUID = -3092290247725378832L; + + private final StorageOptions options; + private Iterable infoIterable; + private transient Storage storage; + + public LazyBlobIterable(StorageOptions options, Iterable infoIterable) { + this.options = options; + this.infoIterable = infoIterable; + this.storage = options.service(); + } + + private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { + in.defaultReadObject(); + this.storage = options.service(); + } + + @Override + public Iterator iterator() { + return Iterators.transform(infoIterable.iterator(), new Function() { + @Override + public Blob apply(BlobInfo blobInfo) { + return new Blob(storage, blobInfo); + } + }); + } + + @Override + public int hashCode() { + return Objects.hash(options, infoIterable); + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof LazyBlobIterable)) { + return false; + } + LazyBlobIterable other = (LazyBlobIterable) obj; + return Objects.equals(options, other.options) + && Objects.equals(infoIterable, other.infoIterable); + } + } + /** * Constructs a {@code Bucket} object for the provided {@code BucketInfo}. The storage service is * used to issue requests. @@ -134,8 +207,11 @@ public boolean delete(BucketSourceOption... options) { * @param options options for listing blobs * @throws StorageException upon failure */ - public ListResult list(Storage.BlobListOption... options) { - return new BlobListResult(storage, storage.list(info.name(), options)); + public Page list(Storage.BlobListOption... options) { + Page infoPage = storage.list(info.name(), options); + StorageOptions storageOptions = storage.options(); + return new PageImpl<>(new BlobPageFetcher(storageOptions, infoPage), infoPage.nextPageCursor(), + new LazyBlobIterable(storageOptions, infoPage.values())); } /** diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java index 9bc971a09dba..2fd4df0cc6ba 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java @@ -24,6 +24,7 @@ import com.google.common.collect.Lists; import com.google.gcloud.AuthCredentials.ServiceAccountAuthCredentials; import com.google.gcloud.Service; +import com.google.gcloud.Page; import com.google.gcloud.spi.StorageRpc; import com.google.gcloud.spi.StorageRpc.Tuple; @@ -827,14 +828,14 @@ private static void checkContentType(BlobInfo blobInfo) throws IllegalArgumentEx * * @throws StorageException upon failure */ - ListResult list(BucketListOption... options); + Page list(BucketListOption... options); /** * List the bucket's blobs. * * @throws StorageException upon failure */ - ListResult list(String bucket, BlobListOption... options); + Page list(String bucket, BlobListOption... options); /** * Update bucket information. diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/StorageImpl.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/StorageImpl.java index ab85dc8b4609..d1e85368fecb 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/StorageImpl.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/StorageImpl.java @@ -44,10 +44,12 @@ import com.google.common.io.BaseEncoding; import com.google.common.primitives.Ints; import com.google.gcloud.AuthCredentials.ServiceAccountAuthCredentials; +import com.google.gcloud.PageImpl; import com.google.gcloud.BaseService; import com.google.gcloud.ExceptionHandler; import com.google.gcloud.ExceptionHandler.Interceptor; import com.google.gcloud.RetryHelper.RetryHelperException; +import com.google.gcloud.Page; import com.google.gcloud.spi.StorageRpc; import com.google.gcloud.spi.StorageRpc.RewriteResponse; import com.google.gcloud.spi.StorageRpc.Tuple; @@ -224,7 +226,7 @@ public BlobInfo get(BlobId blob) { } private abstract static class BasePageFetcher - implements BaseListResult.NextPageFetcher { + implements PageImpl.NextPageFetcher { private static final long serialVersionUID = 8236329004030295223L; protected final Map requestOptions; @@ -256,7 +258,7 @@ private static class BucketPageFetcher extends BasePageFetcher { } @Override - public ListResult nextPage() { + public Page nextPage() { return listBuckets(serviceOptions, requestOptions); } } @@ -273,17 +275,17 @@ private static class BlobPageFetcher extends BasePageFetcher { } @Override - public ListResult nextPage() { + public Page nextPage() { return listBlobs(bucket, serviceOptions, requestOptions); } } @Override - public ListResult list(BucketListOption... options) { + public Page list(BucketListOption... options) { return listBuckets(options(), optionMap(options)); } - private static ListResult listBuckets(final StorageOptions serviceOptions, + private static Page listBuckets(final StorageOptions serviceOptions, final Map optionsMap) { try { Tuple> result = runWithRetries( @@ -302,7 +304,7 @@ public BucketInfo apply(com.google.api.services.storage.model.Bucket bucketPb) { return BucketInfo.fromPb(bucketPb); } }); - return new BaseListResult<>(new BucketPageFetcher(serviceOptions, cursor, optionsMap), cursor, + return new PageImpl<>(new BucketPageFetcher(serviceOptions, cursor, optionsMap), cursor, buckets); } catch (RetryHelperException e) { throw StorageException.translateAndThrow(e); @@ -310,11 +312,11 @@ public BucketInfo apply(com.google.api.services.storage.model.Bucket bucketPb) { } @Override - public ListResult list(final String bucket, BlobListOption... options) { + public Page list(final String bucket, BlobListOption... options) { return listBlobs(bucket, options(), optionMap(options)); } - private static ListResult listBlobs(final String bucket, + private static Page listBlobs(final String bucket, final StorageOptions serviceOptions, final Map optionsMap) { try { Tuple> result = runWithRetries( @@ -333,7 +335,7 @@ public BlobInfo apply(StorageObject storageObject) { return BlobInfo.fromPb(storageObject); } }); - return new BaseListResult<>(new BlobPageFetcher(bucket, serviceOptions, cursor, optionsMap), + return new PageImpl<>(new BlobPageFetcher(bucket, serviceOptions, cursor, optionsMap), cursor, blobs); } catch (RetryHelperException e) { diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/testing/RemoteGcsHelper.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/testing/RemoteGcsHelper.java index 6ad655db8670..b15768cffa98 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/testing/RemoteGcsHelper.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/testing/RemoteGcsHelper.java @@ -195,7 +195,7 @@ public DeleteBucketTask(Storage storage, String bucket) { @Override public Boolean call() throws Exception { while (true) { - for (BlobInfo info : storage.list(bucket)) { + for (BlobInfo info : storage.list(bucket).values()) { storage.delete(bucket, info.name()); } try { diff --git a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/BlobListResultTest.java b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/BlobListResultTest.java deleted file mode 100644 index 615213ab1516..000000000000 --- a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/BlobListResultTest.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed 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 com.google.gcloud.storage; - -import static org.easymock.EasyMock.createStrictMock; -import static org.easymock.EasyMock.expect; -import static org.easymock.EasyMock.replay; -import static org.easymock.EasyMock.verify; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; - -import com.google.common.collect.ImmutableList; - -import org.junit.Before; -import org.junit.Test; - -import java.util.Iterator; - -public class BlobListResultTest { - - private static final Iterable FIRST_PAGE_RESULTS = ImmutableList.of( - BlobInfo.builder("b1", "n1").build(), - BlobInfo.builder("b2", "n2").build()); - - private static final Iterable SECOND_PAGE_RESULTS = ImmutableList.of( - BlobInfo.builder("b1", "n1").build(), - BlobInfo.builder("b2", "n2").build()); - - private BaseListResult firstPage; - private BaseListResult secondPage; - private Storage storage; - private BlobListResult blobListResult; - - @Before - public void setUp() throws Exception { - firstPage = createStrictMock(BaseListResult.class); - secondPage = createStrictMock(BaseListResult.class); - storage = createStrictMock(Storage.class); - blobListResult = new BlobListResult(storage, firstPage); - } - - @Test - public void testListResult() throws Exception { - expect(firstPage.iterator()).andReturn(FIRST_PAGE_RESULTS.iterator()); - replay(firstPage); - Iterator firstPageIterator = FIRST_PAGE_RESULTS.iterator(); - Iterator blobListIterator = blobListResult.iterator(); - while (blobListIterator.hasNext() && firstPageIterator.hasNext()) { - assertEquals(firstPageIterator.next(), blobListIterator.next().info()); - } - assertFalse(blobListIterator.hasNext()); - assertFalse(firstPageIterator.hasNext()); - verify(firstPage); - } - - @Test - public void testCursor() throws Exception { - expect(firstPage.nextPageCursor()).andReturn("c"); - replay(firstPage); - assertEquals("c", blobListResult.nextPageCursor()); - verify(firstPage); - } - - @Test - public void testNextPage() throws Exception { - expect(firstPage.nextPage()).andReturn(secondPage); - expect(secondPage.iterator()).andReturn(SECOND_PAGE_RESULTS.iterator()); - replay(firstPage); - replay(secondPage); - ListResult nextPageResult = blobListResult.nextPage(); - Iterator secondPageIterator = SECOND_PAGE_RESULTS.iterator(); - Iterator blobListIterator = nextPageResult.iterator(); - while (blobListIterator.hasNext() && secondPageIterator.hasNext()) { - assertEquals(secondPageIterator.next(), blobListIterator.next().info()); - } - assertFalse(blobListIterator.hasNext()); - assertFalse(secondPageIterator.hasNext()); - verify(firstPage); - verify(secondPage); - } -} diff --git a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/BucketTest.java b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/BucketTest.java index 370850a5b6d4..decac7b1e0d2 100644 --- a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/BucketTest.java +++ b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/BucketTest.java @@ -27,6 +27,8 @@ import static org.junit.Assert.assertTrue; import com.google.common.collect.ImmutableList; +import com.google.gcloud.PageImpl; +import com.google.gcloud.Page; import com.google.gcloud.storage.BatchResponse.Result; import org.easymock.Capture; @@ -114,18 +116,22 @@ public void testDelete() throws Exception { @Test public void testList() throws Exception { - BaseListResult blobInfoResult = new BaseListResult<>(null, "c", BLOB_INFO_RESULTS); - expect(storage.list(BUCKET_INFO.name())).andReturn(blobInfoResult); - replay(storage); - ListResult blobResult = bucket.list(); - Iterator blobInfoIterator = blobInfoResult.iterator(); - Iterator blobIterator = blobResult.iterator(); + StorageOptions storageOptions = createStrictMock(StorageOptions.class); + PageImpl blobInfoPage = new PageImpl<>(null, "c", BLOB_INFO_RESULTS); + expect(storage.list(BUCKET_INFO.name())).andReturn(blobInfoPage); + expect(storage.options()).andReturn(storageOptions); + expect(storageOptions.service()).andReturn(storage); + replay(storage, storageOptions); + Page blobPage = bucket.list(); + Iterator blobInfoIterator = blobInfoPage.values().iterator(); + Iterator blobIterator = blobPage.values().iterator(); while (blobInfoIterator.hasNext() && blobIterator.hasNext()) { assertEquals(blobInfoIterator.next(), blobIterator.next().info()); } assertFalse(blobInfoIterator.hasNext()); assertFalse(blobIterator.hasNext()); - assertEquals(blobInfoResult.nextPageCursor(), blobResult.nextPageCursor()); + assertEquals(blobInfoPage.nextPageCursor(), blobPage.nextPageCursor()); + verify(storageOptions); } @Test diff --git a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/ITStorageTest.java b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/ITStorageTest.java index 3aad7b712e48..d15e07dfeff7 100644 --- a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/ITStorageTest.java +++ b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/ITStorageTest.java @@ -81,10 +81,10 @@ public static void afterClass() @Test(timeout = 5000) public void testListBuckets() throws InterruptedException { Iterator bucketIterator = - storage.list(Storage.BucketListOption.prefix(BUCKET)).iterator(); + storage.list(Storage.BucketListOption.prefix(BUCKET)).values().iterator(); while (!bucketIterator.hasNext()) { Thread.sleep(500); - bucketIterator = storage.list(Storage.BucketListOption.prefix(BUCKET)).iterator(); + bucketIterator = storage.list(Storage.BucketListOption.prefix(BUCKET)).values().iterator(); } while (bucketIterator.hasNext()) { assertTrue(bucketIterator.next().name().startsWith(BUCKET)); diff --git a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/RemoteGcsHelperTest.java b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/RemoteGcsHelperTest.java index 329767e85d4a..ff6fd68fd1eb 100644 --- a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/RemoteGcsHelperTest.java +++ b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/RemoteGcsHelperTest.java @@ -20,6 +20,7 @@ import static org.junit.Assert.assertTrue; import com.google.common.collect.ImmutableList; +import com.google.gcloud.Page; import com.google.gcloud.storage.testing.RemoteGcsHelper; import org.easymock.EasyMock; @@ -32,7 +33,6 @@ import java.io.InputStream; import java.nio.file.Files; import java.nio.file.Paths; -import java.util.Iterator; import java.util.List; import java.util.UUID; import java.util.concurrent.ExecutionException; @@ -74,21 +74,21 @@ public class RemoteGcsHelperTest { BlobInfo.builder(BUCKET_NAME, "n2").build()); private static final StorageException RETRYABLE_EXCEPTION = new StorageException(409, "", true); private static final StorageException FATAL_EXCEPTION = new StorageException(500, "", false); - private static final ListResult BLOB_LIST_RESULT = new ListResult() { + private static final Page BLOB_PAGE = new Page() { @Override public String nextPageCursor() { - return "listResult"; + return "nextPageCursor"; } @Override - public ListResult nextPage() { + public Page nextPage() { return null; } @Override - public Iterator iterator() { - return BLOB_LIST.iterator(); + public Iterable values() { + return BLOB_LIST; } }; private static String keyPath = "/does/not/exist/key." + UUID.randomUUID().toString() + ".json"; @@ -106,7 +106,7 @@ public static void beforeClass() { @Test public void testForceDelete() throws InterruptedException, ExecutionException { Storage storageMock = EasyMock.createMock(Storage.class); - EasyMock.expect(storageMock.list(BUCKET_NAME)).andReturn(BLOB_LIST_RESULT); + EasyMock.expect(storageMock.list(BUCKET_NAME)).andReturn(BLOB_PAGE); for (BlobInfo info : BLOB_LIST) { EasyMock.expect(storageMock.delete(BUCKET_NAME, info.name())).andReturn(true); } @@ -119,7 +119,7 @@ public void testForceDelete() throws InterruptedException, ExecutionException { @Test public void testForceDeleteTimeout() throws InterruptedException, ExecutionException { Storage storageMock = EasyMock.createMock(Storage.class); - EasyMock.expect(storageMock.list(BUCKET_NAME)).andReturn(BLOB_LIST_RESULT).anyTimes(); + EasyMock.expect(storageMock.list(BUCKET_NAME)).andReturn(BLOB_PAGE).anyTimes(); for (BlobInfo info : BLOB_LIST) { EasyMock.expect(storageMock.delete(BUCKET_NAME, info.name())).andReturn(true).anyTimes(); } @@ -132,7 +132,7 @@ 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(BLOB_LIST_RESULT); + EasyMock.expect(storageMock.list(BUCKET_NAME)).andReturn(BLOB_PAGE); for (BlobInfo info : BLOB_LIST) { EasyMock.expect(storageMock.delete(BUCKET_NAME, info.name())).andReturn(true); } diff --git a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/SerializationTest.java b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/SerializationTest.java index 4c22170bba80..a125a64df6d6 100644 --- a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/SerializationTest.java +++ b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/SerializationTest.java @@ -21,6 +21,7 @@ import com.google.common.collect.ImmutableMap; import com.google.gcloud.AuthCredentials; +import com.google.gcloud.PageImpl; import com.google.gcloud.RestorableState; import com.google.gcloud.RetryParams; import com.google.gcloud.spi.StorageRpc; @@ -54,7 +55,7 @@ public class SerializationTest { Collections.singletonList(BatchResponse.Result.of(true)), Collections.>emptyList(), Collections.>emptyList()); - private static final BaseListResult LIST_RESULT = new BaseListResult<>( + private static final PageImpl PAGE_RESULT = new PageImpl<>( null, "c", Collections.singletonList(BlobInfo.builder("b", "n").build())); private static final Storage.BlobListOption BLOB_LIST_OPTIONS = Storage.BlobListOption.maxResults(100); @@ -93,7 +94,7 @@ public void testServiceOptions() throws Exception { public void testModelAndRequests() throws Exception { Serializable[] objects = {ACL_DOMAIN, ACL_GROUP, ACL_PROJECT_, ACL_USER, ACL_RAW, BLOB_INFO, BUCKET_INFO, - ORIGIN, CORS, BATCH_REQUEST, BATCH_RESPONSE, LIST_RESULT, BLOB_LIST_OPTIONS, + ORIGIN, CORS, BATCH_REQUEST, BATCH_RESPONSE, PAGE_RESULT, BLOB_LIST_OPTIONS, BLOB_SOURCE_OPTIONS, BLOB_TARGET_OPTIONS, BUCKET_LIST_OPTIONS, BUCKET_SOURCE_OPTIONS, BUCKET_TARGET_OPTIONS}; for (Serializable obj : objects) { diff --git a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/StorageImplTest.java b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/StorageImplTest.java index bdac54bcef2d..6c77b4fcfc99 100644 --- a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/StorageImplTest.java +++ b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/StorageImplTest.java @@ -35,6 +35,7 @@ import com.google.gcloud.AuthCredentials.ServiceAccountAuthCredentials; import com.google.gcloud.RetryParams; import com.google.gcloud.ServiceOptions; +import com.google.gcloud.Page; import com.google.gcloud.spi.StorageRpc; import com.google.gcloud.spi.StorageRpc.Tuple; import com.google.gcloud.spi.StorageRpcFactory; @@ -400,9 +401,9 @@ public void testListBuckets() { EasyMock.expect(storageRpcMock.list(EMPTY_RPC_OPTIONS)).andReturn(result); EasyMock.replay(storageRpcMock); storage = options.service(); - ListResult listResult = storage.list(); - assertEquals(cursor, listResult.nextPageCursor()); - assertArrayEquals(bucketList.toArray(), Iterables.toArray(listResult, BucketInfo.class)); + Page page = storage.list(); + assertEquals(cursor, page.nextPageCursor()); + assertArrayEquals(bucketList.toArray(), Iterables.toArray(page.values(), BucketInfo.class)); } @Test @@ -411,10 +412,10 @@ public void testListBucketsEmpty() { Tuple.>of(null, null)); EasyMock.replay(storageRpcMock); storage = options.service(); - ListResult listResult = storage.list(); - assertNull(listResult.nextPageCursor()); + Page page = storage.list(); + assertNull(page.nextPageCursor()); assertArrayEquals(ImmutableList.of().toArray(), - Iterables.toArray(listResult, BucketInfo.class)); + Iterables.toArray(page.values(), BucketInfo.class)); } @Test @@ -426,9 +427,9 @@ public void testListBucketsWithOptions() { EasyMock.expect(storageRpcMock.list(BUCKET_LIST_OPTIONS)).andReturn(result); EasyMock.replay(storageRpcMock); storage = options.service(); - ListResult listResult = storage.list(BUCKET_LIST_MAX_RESULT, BUCKET_LIST_PREFIX); - assertEquals(cursor, listResult.nextPageCursor()); - assertArrayEquals(bucketList.toArray(), Iterables.toArray(listResult, BucketInfo.class)); + Page page = storage.list(BUCKET_LIST_MAX_RESULT, BUCKET_LIST_PREFIX); + assertEquals(cursor, page.nextPageCursor()); + assertArrayEquals(bucketList.toArray(), Iterables.toArray(page.values(), BucketInfo.class)); } @Test @@ -440,22 +441,22 @@ public void testListBlobs() { EasyMock.expect(storageRpcMock.list(BUCKET_NAME1, EMPTY_RPC_OPTIONS)).andReturn(result); EasyMock.replay(storageRpcMock); storage = options.service(); - ListResult listResult = storage.list(BUCKET_NAME1); - assertEquals(cursor, listResult.nextPageCursor()); - assertArrayEquals(blobList.toArray(), Iterables.toArray(listResult, BlobInfo.class)); + Page page = storage.list(BUCKET_NAME1); + assertEquals(cursor, page.nextPageCursor()); + assertArrayEquals(blobList.toArray(), Iterables.toArray(page.values(), BlobInfo.class)); } @Test public void testListBlobsEmpty() { EasyMock.expect(storageRpcMock.list(BUCKET_NAME1, EMPTY_RPC_OPTIONS)) - .andReturn( - Tuple.>of(null, - null)); + .andReturn(Tuple.>of( + null, null)); EasyMock.replay(storageRpcMock); storage = options.service(); - ListResult listResult = storage.list(BUCKET_NAME1); - assertNull(listResult.nextPageCursor()); - assertArrayEquals(ImmutableList.of().toArray(), Iterables.toArray(listResult, BlobInfo.class)); + Page page = storage.list(BUCKET_NAME1); + assertNull(page.nextPageCursor()); + assertArrayEquals(ImmutableList.of().toArray(), + Iterables.toArray(page.values(), BlobInfo.class)); } @Test @@ -467,10 +468,9 @@ public void testListBlobsWithOptions() { EasyMock.expect(storageRpcMock.list(BUCKET_NAME1, BLOB_LIST_OPTIONS)).andReturn(result); EasyMock.replay(storageRpcMock); storage = options.service(); - ListResult listResult = - storage.list(BUCKET_NAME1, BLOB_LIST_MAX_RESULT, BLOB_LIST_PREFIX); - assertEquals(cursor, listResult.nextPageCursor()); - assertArrayEquals(blobList.toArray(), Iterables.toArray(listResult, BlobInfo.class)); + Page page = storage.list(BUCKET_NAME1, BLOB_LIST_MAX_RESULT, BLOB_LIST_PREFIX); + assertEquals(cursor, page.nextPageCursor()); + assertArrayEquals(blobList.toArray(), Iterables.toArray(page.values(), BlobInfo.class)); } @Test