Skip to content

Commit cf0e01a

Browse files
authored
feat: add stream methods for Page (#1425)
* feat: add stream methods * add clirr ignore rule * add comments for stream methods * fix format * add tests for stream methods * modify tests * add showcase tests * Revert "add showcase tests" This reverts commit 6fcfa9b. * add a integration test for stream methods * add copyright * change client builder * set page token * remove page token in stream all * remove page token in stream values * modify paged request * modify tests * create users only once * delete showcase it * add comments * change unit test name
1 parent 184b662 commit cf0e01a

File tree

3 files changed

+77
-2
lines changed

3 files changed

+77
-2
lines changed
+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!-- see http://www.mojohaus.org/clirr-maven-plugin/examples/ignored-differences.html -->
3+
<differences>
4+
<difference>
5+
<!-- add default stream methods to `Page` interface -->
6+
<differenceType>7012</differenceType>
7+
<className>com/google/api/gax/paging/Page</className>
8+
<method>* stream*(*)</method>
9+
</difference>
10+
</differences>

gax-java/gax/src/main/java/com/google/api/gax/paging/Page.java

+19-2
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@
2929
*/
3030
package com.google.api.gax.paging;
3131

32+
import java.util.stream.Stream;
33+
import java.util.stream.StreamSupport;
34+
3235
/**
3336
* A Page object wraps an API list method response.
3437
*
@@ -52,12 +55,26 @@ public interface Page<ResourceT> {
5255
Page<ResourceT> getNextPage();
5356

5457
/**
55-
* Returns an iterable that traverses all of the elements of the underlying data source. The data
56-
* is fetched lazily page by page, where each page may contain multiple elements. A new page is
58+
* Returns an iterable that traverses all the elements of the underlying data source. The data is
59+
* fetched lazily page by page, where each page may contain multiple elements. A new page is
5760
* fetched whenever the elements of any particular page are exhausted.
5861
*/
5962
Iterable<ResourceT> iterateAll();
6063

6164
/** Returns an iterable over the elements in this page. */
6265
Iterable<ResourceT> getValues();
66+
67+
/**
68+
* Returns a stream that traverses all the elements of the underlying data source. The data is
69+
* fetched lazily page by page, where each page may contain multiple elements. A new page is
70+
* fetched whenever the elements of any particular page are exhausted.
71+
*/
72+
default Stream<ResourceT> streamAll() {
73+
return StreamSupport.stream(iterateAll().spliterator(), false);
74+
}
75+
76+
/** Returns a stream over the elements in this page. */
77+
default Stream<ResourceT> streamValues() {
78+
return StreamSupport.stream(getValues().spliterator(), false);
79+
}
6380
}

gax-java/gax/src/test/java/com/google/api/gax/rpc/PagingTest.java

+48
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,54 @@ public void pagedByPage() {
133133
Truth.assertThat(requestCapture.getAllValues()).containsExactly(0, 2, 4).inOrder();
134134
}
135135

136+
@Test
137+
public void streamValues_streamIsCorrectPerPage() {
138+
ArgumentCaptor<Integer> requestCapture = ArgumentCaptor.forClass(Integer.class);
139+
Mockito.when(callIntList.futureCall(requestCapture.capture(), Mockito.any()))
140+
.thenReturn(ApiFutures.immediateFuture(Arrays.asList(0, 1, 2)))
141+
.thenReturn(ApiFutures.immediateFuture(Arrays.asList(3, 4)))
142+
.thenReturn(ApiFutures.immediateFuture(Collections.emptyList()));
143+
144+
Page<Integer> page =
145+
FakeCallableFactory.createPagedCallable(
146+
callIntList,
147+
PagedCallSettings.newBuilder(new ListIntegersPagedResponseFactory()).build(),
148+
clientContext)
149+
.call(0)
150+
.getPage();
151+
152+
Truth.assertThat(page.streamValues().count()).isEqualTo(3);
153+
Truth.assertThat(page.hasNextPage()).isTrue();
154+
155+
page = page.getNextPage();
156+
Truth.assertThat(page.streamValues().count()).isEqualTo(2);
157+
Truth.assertThat(page.hasNextPage()).isTrue();
158+
159+
page = page.getNextPage();
160+
Truth.assertThat(page.streamValues().count()).isEqualTo(0);
161+
Truth.assertThat(page.hasNextPage()).isFalse();
162+
Truth.assertThat(page.getNextPage()).isNull();
163+
}
164+
165+
@Test
166+
public void streamAll_streamIsCorrectInAllPages() {
167+
ArgumentCaptor<Integer> requestCapture = ArgumentCaptor.forClass(Integer.class);
168+
Mockito.when(callIntList.futureCall(requestCapture.capture(), Mockito.any()))
169+
.thenReturn(ApiFutures.immediateFuture(Arrays.asList(0, 1, 2)))
170+
.thenReturn(ApiFutures.immediateFuture(Arrays.asList(3, 4)))
171+
.thenReturn(ApiFutures.immediateFuture(Collections.emptyList()));
172+
173+
Page<Integer> page =
174+
FakeCallableFactory.createPagedCallable(
175+
callIntList,
176+
PagedCallSettings.newBuilder(new ListIntegersPagedResponseFactory()).build(),
177+
clientContext)
178+
.call(0)
179+
.getPage();
180+
181+
Truth.assertThat(page.streamAll().count()).isEqualTo(5);
182+
}
183+
136184
@Test
137185
public void pagedByFixedSizeCollection() {
138186
ArgumentCaptor<Integer> requestCapture = ArgumentCaptor.forClass(Integer.class);

0 commit comments

Comments
 (0)