I'd like to make informers work with the CRUD API. The current behavior seems to break with the reflector code within the informer. For example:
@Test
void testCrudInformer() throws InterruptedException {
final KubernetesServer server = new KubernetesServer(true, true);
server.before();
KubernetesClient client = server.getClient();
SharedInformerFactory factory = client.informers();
SharedIndexInformer<Pod> podInformer = factory.sharedIndexInformerFor(Pod.class, PodList.class, 4000);
podInformer.addEventHandler(
new ResourceEventHandler<Pod>() {
@Override
public void onAdd(Pod obj) {
}
@Override
public void onUpdate(Pod oldObj, Pod newObj) {
}
@Override
public void onDelete(Pod oldObj, boolean deletedFinalStateUnknown) {
}
});
factory.startAllRegisteredInformers();
Thread.sleep(5000);
factory.stopAllRegisteredInformers();
}
Leads to the following NPE in the reflector....
Jun 22, 2020 7:15:46 PM okhttp3.mockwebserver.MockWebServer$2 execute
INFO: MockWebServer[58658] starting to accept connections
19:15:46.956 [informer-controller-Pod] INFO io.fabric8.kubernetes.client.informers.cache.Controller - informer#Controller: ready to run resync and reflector runnable
19:15:46.967 [informer-controller-Pod] INFO io.fabric8.kubernetes.client.informers.cache.Reflector - Started ReflectorRunnable watch for class io.fabric8.kubernetes.api.model.Pod
Jun 22, 2020 7:15:47 PM okhttp3.mockwebserver.MockWebServer$3 processOneRequest
INFO: MockWebServer[58658] received request: GET /api/v1/namespaces/test/pods HTTP/1.1 and responded: HTTP/1.1 200 OK
19:15:47.397 [informer-controller-Pod] WARN io.fabric8.kubernetes.client.informers.cache.Controller - Reflector list-watching job exiting because the thread-pool is shutting down
java.util.concurrent.RejectedExecutionException: Error while starting ReflectorRunnable watch
at io.fabric8.kubernetes.client.informers.cache.Reflector.listAndWatch(Reflector.java:85) ~[kubernetes-client-4.10.1.jar:?]
at io.fabric8.kubernetes.client.informers.cache.Controller.run(Controller.java:112) ~[kubernetes-client-4.10.1.jar:?]
at java.lang.Thread.run(Thread.java:835) [?:?]
Caused by: java.lang.NullPointerException
at io.fabric8.kubernetes.client.informers.cache.Reflector.reListAndSync(Reflector.java:95) ~[kubernetes-client-4.10.1.jar:?]
at io.fabric8.kubernetes.client.informers.cache.Reflector.listAndWatch(Reflector.java:80) ~[kubernetes-client-4.10.1.jar:?]
... 2 more
Which in turn happens because the list type (PodList) that the reflector gets back has a null metadata object:
private void reListAndSync() {
final L list = getList();
final String latestResourceVersion = list.getMetadata().getResourceVersion(); // NPE: Metadata is null
...
Right now Reflector seems to be failing since list returned by mockwebserver seems to have null metadata:
However, a real Kubernetes server returns metadata too:
~/go/src/github.com/fabric8io/kubernetes-client/kubernetes-tests : $ kubectl get pods -ojson
{
"apiVersion": "v1",
"items": [],
"kind": "List",
"metadata": {
"resourceVersion": "",
"selfLink": ""
}
}
Anyone who wants to fix this issue needs to update this method with metadata updated:
Thanks @rohanKanojia. I'll send over a PR soon.
Most helpful comment
Thanks @rohanKanojia. I'll send over a PR soon.