Skip to content

Commit 2e43cbe

Browse files
authored
Merge pull request #543 from yue9944882/refactor/pager-colon-loop
Refactor pager to support colon-loop java grammar
2 parents d600430 + 371605b commit 2e43cbe

File tree

6 files changed

+123
-95
lines changed

6 files changed

+123
-95
lines changed

examples/src/main/java/io/kubernetes/client/examples/PagerExample.java

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,8 @@
1818
import io.kubernetes.client.models.V1Namespace;
1919
import io.kubernetes.client.models.V1NamespaceList;
2020
import io.kubernetes.client.pager.Pager;
21-
import io.kubernetes.client.pager.PagerParams;
2221
import io.kubernetes.client.util.Config;
2322
import java.io.IOException;
24-
import java.util.List;
2523
import java.util.concurrent.TimeUnit;
2624

2725
/**
@@ -40,14 +38,14 @@ public static void main(String[] args) throws IOException {
4038
Configuration.setDefaultApiClient(client);
4139
CoreV1Api api = new CoreV1Api();
4240
int i = 0;
43-
Pager pager =
41+
Pager<V1Namespace, V1NamespaceList> pager =
4442
new Pager<V1Namespace, V1NamespaceList>(
45-
(PagerParams param) -> {
43+
(Pager.PagerParams param) -> {
4644
try {
4745
return api.listNamespaceCall(
4846
null,
4947
null,
50-
param.getContinue(),
48+
param.getContinueToken(),
5149
null,
5250
null,
5351
param.getLimit(),
@@ -63,14 +61,9 @@ public static void main(String[] args) throws IOException {
6361
client,
6462
10,
6563
V1NamespaceList.class);
66-
while (pager.hasNext()) {
67-
V1NamespaceList list = (V1NamespaceList) pager.next();
68-
List<V1Namespace> items = list.getItems();
69-
System.out.println("count:" + items.size());
70-
for (V1Namespace namespace : items) {
71-
System.out.println(namespace.getMetadata().getName());
72-
}
73-
System.out.println("------------------" + (++i));
64+
for (V1Namespace namespace : pager) {
65+
System.out.println(namespace.getMetadata().getName());
7466
}
67+
System.out.println("------------------");
7568
}
7669
}

util/src/main/java/io/kubernetes/client/pager/Pager.java

Lines changed: 55 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,21 @@
2020
import io.kubernetes.client.util.exception.ObjectMetaReflectException;
2121
import java.io.IOException;
2222
import java.lang.reflect.Type;
23+
import java.util.Iterator;
2324
import java.util.function.Function;
2425

25-
public class Pager<ApiType, ApiListType> {
26+
public class Pager<ApiType, ApiListType> implements Iterable<ApiType>, Iterator<ApiType> {
2627
private String continueToken;
2728
private Integer limit;
2829
private ApiClient client;
2930
private Call call;
3031
private Type listType;
3132
private Function<PagerParams, Call> listFunc;
3233

34+
private ApiListType listObjectCurrentPage;
35+
private int offsetCurrentPage;
36+
private int currentPageSize;
37+
3338
/**
3439
* Pagination in kubernetes list call depends on continue and limit variable
3540
*
@@ -52,8 +57,13 @@ public Pager(
5257
*
5358
* @return
5459
*/
55-
public Boolean hasNext() {
56-
if (continueToken == null && call != null) {
60+
@Override
61+
public boolean hasNext() {
62+
if (call == null) {
63+
// the first time looping over the pager
64+
return Boolean.TRUE;
65+
}
66+
if (continueToken == null && offsetCurrentPage >= currentPageSize) {
5767
return Boolean.FALSE;
5868
}
5969
return Boolean.TRUE;
@@ -64,43 +74,67 @@ public Boolean hasNext() {
6474
*
6575
* @return Object
6676
*/
67-
public <ApiType> ApiListType next() {
68-
return next(null);
69-
}
70-
71-
/**
72-
* returns next chunk of list. size of list depends on limit set in constructor or nextLimit.
73-
*
74-
* @param nextLimit
75-
* @return
76-
*/
77-
public <ApiType> ApiListType next(Integer nextLimit) {
77+
@Override
78+
public ApiType next() {
7879
try {
79-
call = getNextCall(nextLimit);
80-
return executeRequest(call);
81-
} catch (Exception e) {
82-
if (e instanceof ApiException) {
83-
throw new RuntimeException(((ApiException) e).getResponseBody());
80+
if (offsetCurrentPage >= currentPageSize) {
81+
call = getNextCall(limit);
82+
listObjectCurrentPage = executeRequest(call);
83+
84+
offsetCurrentPage = 0;
85+
currentPageSize = Reflect.<ApiType>getItems(listObjectCurrentPage).size();
8486
}
87+
return Reflect.<ApiType>getItems(listObjectCurrentPage).get(offsetCurrentPage++);
88+
} catch (ApiException e) {
89+
throw new RuntimeException(e.getResponseBody());
90+
} catch (ObjectMetaReflectException | IOException e) {
8591
throw new RuntimeException(e);
8692
}
8793
}
8894

95+
@Override
96+
public Iterator<ApiType> iterator() {
97+
this.call = null;
98+
return this;
99+
}
100+
89101
/** returns next list call by setting continue variable and limit */
90102
private Call getNextCall(Integer nextLimit) {
91103
PagerParams params = new PagerParams((nextLimit != null) ? nextLimit : limit);
92104
if (continueToken != null) {
93-
params.setContinue(continueToken);
105+
params.continueToken = continueToken;
94106
}
95107
return listFunc.apply(params);
96108
}
97109

98110
/** executes the list call and sets the continue variable for next list call */
99-
private <ApiType> ApiListType executeRequest(Call call)
111+
private ApiListType executeRequest(Call call)
100112
throws IOException, ApiException, ObjectMetaReflectException {
101113
ApiListType data = client.handleResponse(call.execute(), listType);
102114
V1ListMeta listMetaData = Reflect.listMetadata(data);
103115
continueToken = listMetaData.getContinue();
104116
return data;
105117
}
118+
119+
public static class PagerParams {
120+
private Integer limit;
121+
private String continueToken;
122+
123+
public PagerParams(Integer limit) {
124+
this.limit = limit;
125+
}
126+
127+
public PagerParams(Integer limit, String continueToken) {
128+
this.limit = limit;
129+
this.continueToken = continueToken;
130+
}
131+
132+
public Integer getLimit() {
133+
return limit;
134+
}
135+
136+
public String getContinueToken() {
137+
return continueToken;
138+
}
139+
}
106140
}

util/src/main/java/io/kubernetes/client/pager/PagerParams.java

Lines changed: 0 additions & 40 deletions
This file was deleted.

util/src/test/java/io/kubernetes/client/pager/PagerTest.java

Lines changed: 34 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,10 @@
3939
public class PagerTest {
4040

4141
private ApiClient client;
42-
private static final String LIST_FILE_PATH =
43-
Resources.getResource("namespace-list.json").getPath();
42+
private static final String LIST_PAGE1_FILE_PATH =
43+
Resources.getResource("namespace-list-pager1.json").getPath();
44+
private static final String LIST_PAGE2_FILE_PATH =
45+
Resources.getResource("namespace-list-pager2.json").getPath();
4446
private static final String LIST_STATUS_FILE_PATH =
4547
Resources.getResource("status-400.json").getPath();
4648
private static final String STATUS_BAD_TOKEN_FILE_PATH =
@@ -55,7 +57,8 @@ public void setup() throws IOException {
5557

5658
@Test
5759
public void testPaginationForNamespaceListWithSuccess() throws IOException {
58-
String namespaceListStr = new String(Files.readAllBytes(Paths.get(LIST_FILE_PATH)));
60+
String namespaceListPage1Str = new String(Files.readAllBytes(Paths.get(LIST_PAGE1_FILE_PATH)));
61+
String namespaceListPage2Str = new String(Files.readAllBytes(Paths.get(LIST_PAGE2_FILE_PATH)));
5962
CoreV1Api api = new CoreV1Api(client);
6063

6164
stubFor(
@@ -65,15 +68,25 @@ public void testPaginationForNamespaceListWithSuccess() throws IOException {
6568
aResponse()
6669
.withStatus(200)
6770
.withHeader("Content-Type", "application/json")
68-
.withBody(namespaceListStr)));
69-
Pager pager =
71+
.withBody(namespaceListPage1Str)));
72+
stubFor(
73+
get(urlPathEqualTo("/api/v1/namespaces"))
74+
.withQueryParam("limit", equalTo("1"))
75+
.withQueryParam("continue", equalTo("c1"))
76+
.willReturn(
77+
aResponse()
78+
.withStatus(200)
79+
.withHeader("Content-Type", "application/json")
80+
.withBody(namespaceListPage2Str)));
81+
82+
Pager<V1Namespace, V1NamespaceList> pager =
7083
new Pager<V1Namespace, V1NamespaceList>(
71-
(PagerParams param) -> {
84+
(Pager.PagerParams param) -> {
7285
try {
7386
return api.listNamespaceCall(
7487
null,
7588
null,
76-
param.getContinue(),
89+
param.getContinueToken(),
7790
null,
7891
null,
7992
param.getLimit(),
@@ -89,16 +102,16 @@ public void testPaginationForNamespaceListWithSuccess() throws IOException {
89102
client,
90103
1,
91104
V1NamespaceList.class);
92-
while (pager.hasNext()) {
93-
V1NamespaceList list = (V1NamespaceList) pager.next();
94-
List<V1Namespace> items = list.getItems();
95-
assertEquals(1, items.size());
96-
for (V1Namespace namespace : items) {
97-
assertEquals("default", namespace.getMetadata().getName());
98-
}
105+
106+
int size = 0;
107+
for (V1Namespace namespace : pager) {
108+
assertEquals("default", namespace.getMetadata().getName());
109+
size++;
99110
}
111+
assertEquals(2, size);
100112

101113
verify(
114+
2,
102115
getRequestedFor(urlPathEqualTo("/api/v1/namespaces"))
103116
.withQueryParam("limit", equalTo("1")));
104117
}
@@ -118,12 +131,12 @@ public void testPaginationForNamespaceListWithBadTokenFailure() throws IOExcepti
118131
.withBody(status400Str)));
119132
Pager pager =
120133
new Pager<V1Namespace, V1NamespaceList>(
121-
(PagerParams param) -> {
134+
(Pager.PagerParams param) -> {
122135
try {
123136
return api.listNamespaceCall(
124137
null,
125138
null,
126-
param.getContinue(),
139+
param.getContinueToken(),
127140
null,
128141
null,
129142
param.getLimit(),
@@ -163,7 +176,7 @@ public void testPaginationForNamespaceListWithFieldSelectorFailure() throws IOEx
163176

164177
stubFor(
165178
get(urlPathEqualTo("/api/v1/namespaces"))
166-
.withQueryParam("fieldSelector", equalTo("metadata.nam=default"))
179+
.withQueryParam("fieldSelector", equalTo("metadata.name=default"))
167180
.withQueryParam("limit", equalTo("1"))
168181
.willReturn(
169182
aResponse()
@@ -172,13 +185,13 @@ public void testPaginationForNamespaceListWithFieldSelectorFailure() throws IOEx
172185
.withBody(status400Str)));
173186
Pager pager =
174187
new Pager<V1Namespace, V1NamespaceList>(
175-
(PagerParams param) -> {
188+
(Pager.PagerParams param) -> {
176189
try {
177190
return api.listNamespaceCall(
178191
null,
179192
null,
180-
param.getContinue(),
181-
"metadata.nam=default",
193+
param.getContinueToken(),
194+
"metadata.name=default",
182195
null,
183196
param.getLimit(),
184197
null,
@@ -207,7 +220,7 @@ public void testPaginationForNamespaceListWithFieldSelectorFailure() throws IOEx
207220
}
208221
verify(
209222
getRequestedFor(urlPathEqualTo("/api/v1/namespaces"))
210-
.withQueryParam("fieldSelector", equalTo("metadata.nam=default"))
223+
.withQueryParam("fieldSelector", equalTo("metadata.name=default"))
211224
.withQueryParam("limit", equalTo("1")));
212225
}
213226
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
{
2+
"kind": "NamespaceList",
3+
"apiVersion": "v1",
4+
"metadata": {
5+
"selfLink": "/api/v1/namespaces",
6+
"resourceVersion": "61027",
7+
"continue": "c1"
8+
},
9+
"items": [
10+
{
11+
"metadata": {
12+
"name": "default",
13+
"selfLink": "/api/v1/namespaces/default",
14+
"uid": "6daaf10d-3ca3-11e9-ac34-0800272a766a",
15+
"resourceVersion": "4",
16+
"creationTimestamp": "2019-03-02T04:27:02Z"
17+
},
18+
"spec": {
19+
"finalizers": [
20+
"kubernetes"
21+
]
22+
},
23+
"status": {
24+
"phase": "Active"
25+
}
26+
}
27+
]
28+
}

0 commit comments

Comments
 (0)