diff --git a/gax-java/gax/clirr-ignored-differences.xml b/gax-java/gax/clirr-ignored-differences.xml
new file mode 100644
index 0000000000..dcc0be350d
--- /dev/null
+++ b/gax-java/gax/clirr-ignored-differences.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+ 7012
+ com/google/api/gax/paging/Page
+ * stream*(*)
+
+
diff --git a/gax-java/gax/src/main/java/com/google/api/gax/paging/Page.java b/gax-java/gax/src/main/java/com/google/api/gax/paging/Page.java
index abacde970c..de1cbc0ab9 100644
--- a/gax-java/gax/src/main/java/com/google/api/gax/paging/Page.java
+++ b/gax-java/gax/src/main/java/com/google/api/gax/paging/Page.java
@@ -29,6 +29,9 @@
*/
package com.google.api.gax.paging;
+import java.util.stream.Stream;
+import java.util.stream.StreamSupport;
+
/**
* A Page object wraps an API list method response.
*
@@ -52,12 +55,26 @@ public interface Page {
Page getNextPage();
/**
- * Returns an iterable that traverses all of the elements of the underlying data source. The data
- * is fetched lazily page by page, where each page may contain multiple elements. A new page is
+ * Returns an iterable that traverses all the elements of the underlying data source. The data is
+ * fetched lazily page by page, where each page may contain multiple elements. A new page is
* fetched whenever the elements of any particular page are exhausted.
*/
Iterable iterateAll();
/** Returns an iterable over the elements in this page. */
Iterable getValues();
+
+ /**
+ * Returns a stream that traverses all the elements of the underlying data source. The data is
+ * fetched lazily page by page, where each page may contain multiple elements. A new page is
+ * fetched whenever the elements of any particular page are exhausted.
+ */
+ default Stream streamAll() {
+ return StreamSupport.stream(iterateAll().spliterator(), false);
+ }
+
+ /** Returns a stream over the elements in this page. */
+ default Stream streamValues() {
+ return StreamSupport.stream(getValues().spliterator(), false);
+ }
}
diff --git a/gax-java/gax/src/test/java/com/google/api/gax/rpc/PagingTest.java b/gax-java/gax/src/test/java/com/google/api/gax/rpc/PagingTest.java
index e1655b6bf7..f7f02c0f74 100644
--- a/gax-java/gax/src/test/java/com/google/api/gax/rpc/PagingTest.java
+++ b/gax-java/gax/src/test/java/com/google/api/gax/rpc/PagingTest.java
@@ -133,6 +133,54 @@ public void pagedByPage() {
Truth.assertThat(requestCapture.getAllValues()).containsExactly(0, 2, 4).inOrder();
}
+ @Test
+ public void streamValues_streamIsCorrectPerPage() {
+ ArgumentCaptor requestCapture = ArgumentCaptor.forClass(Integer.class);
+ Mockito.when(callIntList.futureCall(requestCapture.capture(), Mockito.any()))
+ .thenReturn(ApiFutures.immediateFuture(Arrays.asList(0, 1, 2)))
+ .thenReturn(ApiFutures.immediateFuture(Arrays.asList(3, 4)))
+ .thenReturn(ApiFutures.immediateFuture(Collections.emptyList()));
+
+ Page page =
+ FakeCallableFactory.createPagedCallable(
+ callIntList,
+ PagedCallSettings.newBuilder(new ListIntegersPagedResponseFactory()).build(),
+ clientContext)
+ .call(0)
+ .getPage();
+
+ Truth.assertThat(page.streamValues().count()).isEqualTo(3);
+ Truth.assertThat(page.hasNextPage()).isTrue();
+
+ page = page.getNextPage();
+ Truth.assertThat(page.streamValues().count()).isEqualTo(2);
+ Truth.assertThat(page.hasNextPage()).isTrue();
+
+ page = page.getNextPage();
+ Truth.assertThat(page.streamValues().count()).isEqualTo(0);
+ Truth.assertThat(page.hasNextPage()).isFalse();
+ Truth.assertThat(page.getNextPage()).isNull();
+ }
+
+ @Test
+ public void streamAll_streamIsCorrectInAllPages() {
+ ArgumentCaptor requestCapture = ArgumentCaptor.forClass(Integer.class);
+ Mockito.when(callIntList.futureCall(requestCapture.capture(), Mockito.any()))
+ .thenReturn(ApiFutures.immediateFuture(Arrays.asList(0, 1, 2)))
+ .thenReturn(ApiFutures.immediateFuture(Arrays.asList(3, 4)))
+ .thenReturn(ApiFutures.immediateFuture(Collections.emptyList()));
+
+ Page page =
+ FakeCallableFactory.createPagedCallable(
+ callIntList,
+ PagedCallSettings.newBuilder(new ListIntegersPagedResponseFactory()).build(),
+ clientContext)
+ .call(0)
+ .getPage();
+
+ Truth.assertThat(page.streamAll().count()).isEqualTo(5);
+ }
+
@Test
public void pagedByFixedSizeCollection() {
ArgumentCaptor requestCapture = ArgumentCaptor.forClass(Integer.class);