Skip to content

Commit 5490ec1

Browse files
shawkinsmanusa
authored andcommitted
fix #4888: narrowing where the 0 resourceVersion is used
1 parent 73b2a04 commit 5490ec1

File tree

13 files changed

+41
-25
lines changed

13 files changed

+41
-25
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
* Fix #4823: (java-generator) handle special characters in field names
1717
* Fix #4723: [java-generator] Fix a race in the use of JavaParser hitting large CRDs
1818
* Fix #4885: addresses a potential hang in the jdk client with exec stream reading
19+
* Fix #4888: narrowing where the 0 initial list resourceVersion is used for informers - in particular if a limit is set or initialState is used, then we should not use 0. Additionally for the informOnCondition / wait methods we'll also not use 0 - it's not expected that the user should test any state prior to the latest.
1920
* Fix #4891: address vertx not completely reading exec streams
2021
* Fix #4899: BuildConfigs.instantiateBinary().fromFile() does not time out
2122
* Fix #4908: using the response headers in the vertx response

kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/BaseOperation.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -902,6 +902,8 @@ public CompletableFuture<List<T>> informOnCondition(Predicate<List<T>> condition
902902
// create an informer that supplies the tester with events and empty list handling
903903
SharedIndexInformer<T> informer = this.createInformer(0, Runnable::run);
904904

905+
informer.initialState(Stream.empty());
906+
905907
// prevent unnecessary watches and handle closure
906908
future.whenComplete((r, t) -> informer.stop());
907909

kubernetes-client/src/main/java/io/fabric8/kubernetes/client/informers/impl/DefaultSharedIndexInformer.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,7 @@ public CompletableFuture<Void> start() {
155155

156156
if (initialState != null) {
157157
initialState.forEach(indexer::put);
158+
reflector.usingInitialState();
158159
}
159160
}
160161

kubernetes-client/src/main/java/io/fabric8/kubernetes/client/informers/impl/cache/Reflector.java

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ public class Reflector<T extends HasMetadata, L extends KubernetesResourceList<T
6060

6161
private CompletableFuture<Void> timeoutFuture;
6262

63+
private boolean cachedListing = true;
64+
6365
public Reflector(ListerWatcher<T, L> listerWatcher, SyncableStore<T> store) {
6466
this.listerWatcher = listerWatcher;
6567
this.store = store;
@@ -167,10 +169,8 @@ private CompletableFuture<L> processList(Set<String> nextKeys, String continueVa
167169
CompletableFuture<L> futureResult = listerWatcher
168170
.submitList(
169171
new ListOptionsBuilder()
170-
// start with 0 - meaning any cached version is fine for the initial listing
171-
// but if we've already synced, then we have to get the latest as the version we're on
172-
// is no longer valid
173-
.withResourceVersion(lastSyncResourceVersion == null && continueVal == null ? "0" : null)
172+
// if caching is allowed, start with 0 - meaning any cached version is fine for the initial listing
173+
.withResourceVersion(isCachedListing(continueVal) ? "0" : null)
174174
.withLimit(listerWatcher.getLimit()).withContinue(continueVal)
175175
.build());
176176

@@ -188,6 +188,11 @@ private CompletableFuture<L> processList(Set<String> nextKeys, String continueVa
188188
});
189189
}
190190

191+
private boolean isCachedListing(String continueVal) {
192+
// allow an initial cached listing only if there's no initial state, no limit, we haven't already sync'd, and this isn't a continue request
193+
return cachedListing && listerWatcher.getLimit() == null && lastSyncResourceVersion == null && continueVal == null;
194+
}
195+
191196
private void stopWatch(Watch w) {
192197
log.debug("Stopping watcher for {} at v{}", this, lastSyncResourceVersion);
193198
w.close();
@@ -320,4 +325,8 @@ public void setExceptionHandler(ExceptionHandler handler) {
320325
this.handler = handler;
321326
}
322327

328+
public void usingInitialState() {
329+
this.cachedListing = false;
330+
}
331+
323332
}

kubernetes-tests/src/test/java/io/fabric8/kubernetes/client/mock/InformTest.java

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,7 @@ void testRunnableInformer() throws InterruptedException {
253253
.build();
254254

255255
server.expect()
256-
.withPath("/api/v1/namespaces/test/pods?labelSelector=my-label&resourceVersion=0")
256+
.withPath("/api/v1/namespaces/test/pods?labelSelector=my-label")
257257
.andReturn(HttpURLConnection.HTTP_OK,
258258
new PodListBuilder().withNewMetadata().withResourceVersion("1").endMetadata().withItems(pod1).build())
259259
.once();
@@ -320,7 +320,7 @@ void testListLimit() throws InterruptedException {
320320
.build();
321321

322322
server.expect()
323-
.withPath("/api/v1/namespaces/test/pods?limit=1&resourceVersion=0")
323+
.withPath("/api/v1/namespaces/test/pods?limit=1")
324324
.andReturn(HttpURLConnection.HTTP_OK,
325325
new PodListBuilder().withNewMetadata()
326326
.withResourceVersion("2")
@@ -337,7 +337,8 @@ void testListLimit() throws InterruptedException {
337337
.once();
338338

339339
server.expect()
340-
.withPath("/api/v1/namespaces/test/pods?resourceVersion=2&timeoutSeconds=600&allowWatchBookmarks=true&watch=true")
340+
.withPath(
341+
"/api/v1/namespaces/test/pods?resourceVersion=2&timeoutSeconds=600&allowWatchBookmarks=true&watch=true")
341342
.andUpgradeToWebSocket()
342343
.open()
343344
.done()
@@ -387,7 +388,8 @@ void testInformWithAlternativeKeyFunction() throws InterruptedException {
387388
.once();
388389

389390
server.expect()
390-
.withPath("/api/v1/namespaces/test/pods?resourceVersion=1&timeoutSeconds=600&allowWatchBookmarks=true&watch=true")
391+
.withPath(
392+
"/api/v1/namespaces/test/pods?resourceVersion=1&timeoutSeconds=600&allowWatchBookmarks=true&watch=true")
391393
.andUpgradeToWebSocket()
392394
.open()
393395
.done()
@@ -453,7 +455,8 @@ void testInformWithMinimalState() throws InterruptedException {
453455
.once();
454456

455457
server.expect()
456-
.withPath("/api/v1/namespaces/test/pods?resourceVersion=1&timeoutSeconds=600&allowWatchBookmarks=true&watch=true")
458+
.withPath(
459+
"/api/v1/namespaces/test/pods?resourceVersion=1&timeoutSeconds=600&allowWatchBookmarks=true&watch=true")
457460
.andUpgradeToWebSocket()
458461
.open()
459462
.done()

kubernetes-tests/src/test/java/io/fabric8/kubernetes/client/mock/PodTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -705,7 +705,7 @@ void testWait() throws InterruptedException {
705705

706706
server.expect()
707707
.get()
708-
.withPath("/api/v1/namespaces/test/pods?fieldSelector=metadata.name%3Dpod1&resourceVersion=0")
708+
.withPath("/api/v1/namespaces/test/pods?fieldSelector=metadata.name%3Dpod1")
709709
.andReturn(200, notReady)
710710
.once();
711711

kubernetes-tests/src/test/java/io/fabric8/kubernetes/client/mock/ReplicaSetTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ void testScaleAndWait() {
208208

209209
// list for waiting
210210
server.expect()
211-
.withPath("/apis/apps/v1/namespaces/test/replicasets?fieldSelector=metadata.name%3Drepl1&resourceVersion=0")
211+
.withPath("/apis/apps/v1/namespaces/test/replicasets?fieldSelector=metadata.name%3Drepl1")
212212
.andReturn(200,
213213
new ReplicaSetListBuilder().withItems(scaled).withMetadata(new ListMetaBuilder().build()).build())
214214
.always();

kubernetes-tests/src/test/java/io/fabric8/kubernetes/client/mock/ReplicationControllerTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,7 @@ void testScaleAndWait() {
212212

213213
// list for waiting
214214
server.expect()
215-
.withPath("/api/v1/namespaces/test/replicationcontrollers?fieldSelector=metadata.name%3Drepl1&resourceVersion=0")
215+
.withPath("/api/v1/namespaces/test/replicationcontrollers?fieldSelector=metadata.name%3Drepl1")
216216
.andReturn(200,
217217
new ReplicationControllerListBuilder().withItems(scaled).withMetadata(new ListMetaBuilder().build()).build())
218218
.always();

kubernetes-tests/src/test/java/io/fabric8/kubernetes/client/mock/ResourceListTest.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -159,12 +159,12 @@ void testCreateOrReplaceWithoutDeleteExisting() throws Exception {
159159
void testCreateOrReplaceWithDeleteExisting() throws Exception {
160160
server.expect().delete().withPath("/api/v1/namespaces/ns1/services/my-service").andReturn(HTTP_OK, service).once();
161161
server.expect().delete().withPath("/api/v1/namespaces/ns1/configmaps/my-configmap").andReturn(HTTP_OK, configMap).once();
162-
server.expect().get().withPath("/api/v1/namespaces/ns1/services?fieldSelector=metadata.name%3Dmy-service&resourceVersion=0")
162+
server.expect().get().withPath("/api/v1/namespaces/ns1/services?fieldSelector=metadata.name%3Dmy-service")
163163
.andReturn(HTTP_OK,
164164
new KubernetesListBuilder().withNewMetadata().endMetadata().build())
165165
.once();
166166
server.expect().get()
167-
.withPath("/api/v1/namespaces/ns1/configmaps?fieldSelector=metadata.name%3Dmy-configmap&resourceVersion=0")
167+
.withPath("/api/v1/namespaces/ns1/configmaps?fieldSelector=metadata.name%3Dmy-configmap")
168168
.andReturn(HTTP_OK,
169169
new KubernetesListBuilder().withNewMetadata().endMetadata().build())
170170
.once();
@@ -202,8 +202,8 @@ void testSuccessfulWaitUntilCondition() throws InterruptedException {
202202
.anyMatch(c -> "True".equals(c.getStatus()));
203203

204204
// The pods are never ready if you request them directly.
205-
ResourceTest.list(server, noReady1, "0");
206-
ResourceTest.list(server, noReady2, "0");
205+
ResourceTest.list(server, noReady1, null);
206+
ResourceTest.list(server, noReady2, null);
207207

208208
server.expect().get().withPath(
209209
"/api/v1/namespaces/ns1/pods?fieldSelector=metadata.name%3Dpod1&resourceVersion=1&timeoutSeconds=600&allowWatchBookmarks=true&watch=true")
@@ -247,8 +247,8 @@ void testPartialSuccessfulWaitUntilCondition() {
247247
.anyMatch(c -> "True".equals(c.getStatus()));
248248

249249
// The pods are never ready if you request them directly.
250-
ResourceTest.list(server, noReady1, "0");
251-
ResourceTest.list(server, noReady2, "0");
250+
ResourceTest.list(server, noReady1, null);
251+
ResourceTest.list(server, noReady2, null);
252252

253253
Status gone = new StatusBuilder()
254254
.withCode(HTTP_GONE)

kubernetes-tests/src/test/java/io/fabric8/kubernetes/client/mock/ResourceTest.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -327,7 +327,7 @@ void testWaitUntilReady() throws InterruptedException {
327327
* @param pod
328328
*/
329329
private void list(Pod pod) {
330-
list(server, pod, "0");
330+
list(server, pod, null);
331331
}
332332

333333
static void list(KubernetesMockServer server, Pod pod, String resourceVersion) {
@@ -355,7 +355,7 @@ void testWaitUntilExistsThenReady() throws InterruptedException {
355355
// and again so that "periodicWatchUntilReady" successfully begins
356356
server.expect()
357357
.get()
358-
.withPath("/api/v1/namespaces/test/pods?fieldSelector=metadata.name%3Dpod1&resourceVersion=0")
358+
.withPath("/api/v1/namespaces/test/pods?fieldSelector=metadata.name%3Dpod1")
359359
.andReturn(200, noReady)
360360
.times(2);
361361

@@ -715,7 +715,7 @@ void testFromServerWaitUntilConditionAlwaysGetsResourceFromServer() throws Excep
715715
void testWaitNullDoesntExist() throws InterruptedException {
716716
server.expect()
717717
.get()
718-
.withPath("/api/v1/namespaces/test/pods?fieldSelector=metadata.name%3Dpod1&resourceVersion=0")
718+
.withPath("/api/v1/namespaces/test/pods?fieldSelector=metadata.name%3Dpod1")
719719
.andReturn(200,
720720
new PodListBuilder().withNewMetadata().withResourceVersion("1").endMetadata().build())
721721
.once();

0 commit comments

Comments
 (0)