Search in sources :

Example 1 with ResourceEventHandler

use of io.fabric8.kubernetes.client.informers.ResourceEventHandler in project titus-control-plane by Netflix.

the class DefaultFabric8IOConnector method kubeInformerEvents.

private Flux<PodEvent> kubeInformerEvents() {
    return Flux.create(sink -> {
        ResourceEventHandler<Pod> handler = new ResourceEventHandler<Pod>() {

            @Override
            public void onAdd(Pod pod) {
                Stopwatch stopwatch = Stopwatch.createStarted();
                try {
                    String taskId = pod.getMetadata().getName();
                    Pod old = pods.get(taskId);
                    pods = pods.plus(taskId, pod);
                    PodEvent podEvent;
                    if (old != null) {
                        podEvent = PodEvent.onUpdate(old, pod, findNode(pod));
                    // metrics.onUpdate(pod);
                    } else {
                        podEvent = PodEvent.onAdd(pod);
                    // metrics.onAdd(pod);
                    }
                    sink.next(podEvent);
                    logger.info("Pod Added: pod={}, sequenceNumber={}", formatPodEssentials(pod), podEvent.getSequenceNumber());
                    logger.debug("complete pod data: {}", pod);
                } finally {
                    logger.info("Pod informer onAdd: pod={}, elapsedMs={}", pod.getMetadata().getName(), stopwatch.elapsed().toMillis());
                }
            }

            @Override
            public void onUpdate(Pod oldPod, Pod newPod) {
                Stopwatch stopwatch = Stopwatch.createStarted();
                try {
                    String taskId = newPod.getMetadata().getName();
                    pods = pods.plus(taskId, newPod);
                    PodUpdatedEvent podEvent = PodEvent.onUpdate(oldPod, newPod, findNode(newPod));
                    sink.next(podEvent);
                    logger.info("Pod Updated: old={}, new={}, sequenceNumber={}", formatPodEssentials(oldPod), formatPodEssentials(newPod), podEvent.getSequenceNumber());
                    logger.debug("Complete pod data: old={}, new={}", oldPod, newPod);
                } finally {
                    logger.info("Pod informer onUpdate: pod={}, elapsedMs={}", newPod.getMetadata().getName(), stopwatch.elapsed().toMillis());
                }
            }

            @Override
            public void onDelete(Pod pod, boolean deletedFinalStateUnknown) {
                Stopwatch stopwatch = Stopwatch.createStarted();
                try {
                    String taskId = pod.getMetadata().getName();
                    pods = pods.minus(taskId);
                    PodDeletedEvent podEvent = PodEvent.onDelete(pod, deletedFinalStateUnknown, findNode(pod));
                    sink.next(podEvent);
                    logger.info("Pod Deleted: {}, deletedFinalStateUnknown={}, sequenceNumber={}", formatPodEssentials(pod), deletedFinalStateUnknown, podEvent.getSequenceNumber());
                    logger.debug("complete pod data: {}", pod);
                } finally {
                    logger.info("Pod informer onDelete: pod={}, elapsedMs={}", pod.getMetadata().getName(), stopwatch.elapsed().toMillis());
                }
            }
        };
        this.getPodInformer().addEventHandler(handler);
    // A listener cannot be removed from shared informer.
    // sink.onCancel(() -> ???);
    });
}
Also used : ResourceEventHandler(io.fabric8.kubernetes.client.informers.ResourceEventHandler) PodDeletedEvent(com.netflix.titus.runtime.connector.kubernetes.fabric8io.model.PodDeletedEvent) Pod(io.fabric8.kubernetes.api.model.Pod) Stopwatch(com.google.common.base.Stopwatch) PodEvent(com.netflix.titus.runtime.connector.kubernetes.fabric8io.model.PodEvent) PodUpdatedEvent(com.netflix.titus.runtime.connector.kubernetes.fabric8io.model.PodUpdatedEvent)

Example 2 with ResourceEventHandler

use of io.fabric8.kubernetes.client.informers.ResourceEventHandler in project kubernetes-client by fabric8io.

the class ProcessorListenerTest method testNotificationHandling.

@Test
void testNotificationHandling() {
    Pod pod = new PodBuilder().withNewMetadata().withName("foo").withNamespace("default").endMetadata().build();
    ProcessorListener<Pod> listener = new ProcessorListener<>(new ResourceEventHandler<Pod>() {

        @Override
        public void onAdd(Pod obj) {
            assertEquals(pod, obj);
            addNotificationReceived = true;
        }

        @Override
        public void onUpdate(Pod oldObj, Pod newObj) {
            assertEquals(pod, newObj);
            updateNotificationReceived = true;
        }

        @Override
        public void onDelete(Pod obj, boolean deletedFinalStateUnknown) {
            assertEquals(pod, obj);
            deleteNotificationReceived = true;
        }
    }, 0);
    listener.add(new ProcessorListener.AddNotification<>(pod));
    listener.add(new ProcessorListener.UpdateNotification<>(null, pod));
    listener.add(new ProcessorListener.DeleteNotification<>(pod));
    assertTrue(addNotificationReceived);
    assertTrue(updateNotificationReceived);
    assertTrue(deleteNotificationReceived);
}
Also used : Pod(io.fabric8.kubernetes.api.model.Pod) PodBuilder(io.fabric8.kubernetes.api.model.PodBuilder) Test(org.junit.jupiter.api.Test)

Example 3 with ResourceEventHandler

use of io.fabric8.kubernetes.client.informers.ResourceEventHandler in project kubernetes-client by fabric8io.

the class DefaultSharedIndexInformerTest method testHasSynced.

@Test
@DisplayName("PodInformer's hasSynced() method should return false when it's not able to resync")
void testHasSynced() {
    // Given
    String startResourceVersion = "1000", endResourceVersion = "1001";
    server.expect().withPath("/api/v1/namespaces/test/pods").andReturn(200, new PodListBuilder().withNewMetadata().withResourceVersion(startResourceVersion).endMetadata().withItems(Collections.emptyList()).build()).once();
    server.expect().withPath("/api/v1/namespaces/test/pods?resourceVersion=" + startResourceVersion + "&allowWatchBookmarks=true&watch=true").andUpgradeToWebSocket().open().waitFor(WATCH_EVENT_EMIT_TIME).andEmit(new WatchEvent(new PodBuilder().withNewMetadata().withNamespace("test").withName("pod1").withResourceVersion(endResourceVersion).endMetadata().build(), "ADDED")).waitFor(OUTDATED_WATCH_EVENT_EMIT_TIME).andEmit(outdatedEvent).done().once();
    // When
    SharedIndexInformer<Pod> podInformer = factory.sharedIndexInformerFor(Pod.class, 2000L);
    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();
    await().atMost(1, TimeUnit.SECONDS).until(() -> !podInformer.hasSynced());
    // Then
    assertFalse(podInformer.hasSynced());
}
Also used : PodListBuilder(io.fabric8.kubernetes.api.model.PodListBuilder) Pod(io.fabric8.kubernetes.api.model.Pod) PodBuilder(io.fabric8.kubernetes.api.model.PodBuilder) WatchEvent(io.fabric8.kubernetes.api.model.WatchEvent) Test(org.junit.jupiter.api.Test) DisplayName(org.junit.jupiter.api.DisplayName)

Example 4 with ResourceEventHandler

use of io.fabric8.kubernetes.client.informers.ResourceEventHandler in project kubernetes-client by fabric8io.

the class DefaultSharedIndexInformerTest method shouldDeleteIfMissingOnResync.

@Test
@DisplayName("Pod Informer should delete the entry from the index")
void shouldDeleteIfMissingOnResync() throws InterruptedException {
    // Given
    String startResourceVersion = "1000", midResourceVersion = "1001", mid2ResourceVersion = "1002";
    server.expect().withPath("/api/v1/pods").andReturn(200, new PodListBuilder().withNewMetadata().withResourceVersion(startResourceVersion).endMetadata().withItems(Collections.emptyList()).build()).once();
    server.expect().withPath("/api/v1/pods?resourceVersion=" + startResourceVersion + "&allowWatchBookmarks=true&watch=true").andUpgradeToWebSocket().open().waitFor(WATCH_EVENT_EMIT_TIME).andEmit(new WatchEvent(new PodBuilder().withNewMetadata().withNamespace("test").withName("pod1").withResourceVersion(midResourceVersion).endMetadata().build(), "ADDED")).waitFor(OUTDATED_WATCH_EVENT_EMIT_TIME).andEmit(outdatedEvent).done().always();
    server.expect().withPath("/api/v1/pods").andReturn(200, new PodListBuilder().withNewMetadata().withResourceVersion(mid2ResourceVersion).endMetadata().withItems(Collections.emptyList()).build()).times(2);
    // When
    SharedIndexInformer<Pod> podInformer = factory.sharedIndexInformerFor(Pod.class, 10000L);
    CountDownLatch delete = new CountDownLatch(1);
    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) {
            if (deletedFinalStateUnknown) {
                delete.countDown();
            }
        }
    });
    factory.startAllRegisteredInformers();
    delete.await(LATCH_AWAIT_PERIOD_IN_SECONDS, TimeUnit.SECONDS);
    // Then
    assertEquals(0, delete.getCount());
    assertEquals(0, podInformer.getIndexer().list().size());
}
Also used : PodListBuilder(io.fabric8.kubernetes.api.model.PodListBuilder) Pod(io.fabric8.kubernetes.api.model.Pod) PodBuilder(io.fabric8.kubernetes.api.model.PodBuilder) WatchEvent(io.fabric8.kubernetes.api.model.WatchEvent) CountDownLatch(java.util.concurrent.CountDownLatch) Test(org.junit.jupiter.api.Test) DisplayName(org.junit.jupiter.api.DisplayName)

Example 5 with ResourceEventHandler

use of io.fabric8.kubernetes.client.informers.ResourceEventHandler in project kubernetes-client by fabric8io.

the class DefaultSharedIndexInformerTest method testInformerWithNamespaceAndNameConfigured.

@Test
void testInformerWithNamespaceAndNameConfigured() throws InterruptedException {
    // Given
    String startResourceVersion = "1000", endResourceVersion = "1001";
    server.expect().withPath("/api/v1/namespaces/test/pods?fieldSelector=" + Utils.toUrlEncoded("metadata.name=pod1")).andReturn(200, getList(startResourceVersion, Pod.class)).once();
    server.expect().withPath("/api/v1/namespaces/test/pods?fieldSelector=" + Utils.toUrlEncoded("metadata.name=pod1") + "&resourceVersion=" + startResourceVersion + "&allowWatchBookmarks=true&watch=true").andUpgradeToWebSocket().open().waitFor(WATCH_EVENT_EMIT_TIME).andEmit(new WatchEvent(new PodBuilder().withNewMetadata().withName("pod1").withResourceVersion(endResourceVersion).endMetadata().build(), "ADDED")).waitFor(OUTDATED_WATCH_EVENT_EMIT_TIME).andEmit(outdatedEvent).done().always();
    // When
    SharedIndexInformer<Pod> podInformer = factory.inNamespace("test").withName("pod1").sharedIndexInformerFor(Pod.class, RESYNC_PERIOD);
    CountDownLatch foundExistingPod = new CountDownLatch(1);
    podInformer.addEventHandler(new ResourceEventHandler<Pod>() {

        @Override
        public void onAdd(Pod obj) {
            if (obj.getMetadata().getName().equalsIgnoreCase("pod1")) {
                foundExistingPod.countDown();
            }
        }

        @Override
        public void onUpdate(Pod oldObj, Pod newObj) {
        }

        @Override
        public void onDelete(Pod oldObj, boolean deletedFinalStateUnknown) {
        }
    });
    factory.startAllRegisteredInformers();
    foundExistingPod.await(LATCH_AWAIT_PERIOD_IN_SECONDS, TimeUnit.SECONDS);
    // Then
    assertEquals(0L, foundExistingPod.getCount());
    await().atMost(1, TimeUnit.SECONDS).until(() -> podInformer.lastSyncResourceVersion().equals(endResourceVersion));
    assertEquals(endResourceVersion, podInformer.lastSyncResourceVersion());
}
Also used : Pod(io.fabric8.kubernetes.api.model.Pod) PodBuilder(io.fabric8.kubernetes.api.model.PodBuilder) WatchEvent(io.fabric8.kubernetes.api.model.WatchEvent) CountDownLatch(java.util.concurrent.CountDownLatch) Test(org.junit.jupiter.api.Test)

Aggregations

Pod (io.fabric8.kubernetes.api.model.Pod)16 PodBuilder (io.fabric8.kubernetes.api.model.PodBuilder)15 Test (org.junit.jupiter.api.Test)15 CountDownLatch (java.util.concurrent.CountDownLatch)12 WatchEvent (io.fabric8.kubernetes.api.model.WatchEvent)11 PodListBuilder (io.fabric8.kubernetes.api.model.PodListBuilder)10 ResourceEventHandler (io.fabric8.kubernetes.client.informers.ResourceEventHandler)7 DisplayName (org.junit.jupiter.api.DisplayName)5 SharedInformerFactory (io.fabric8.kubernetes.client.informers.SharedInformerFactory)4 GenericKubernetesResource (io.fabric8.kubernetes.api.model.GenericKubernetesResource)3 KubernetesClient (io.fabric8.kubernetes.client.KubernetesClient)3 KubernetesClientBuilder (io.fabric8.kubernetes.client.KubernetesClientBuilder)3 CustomResourceDefinitionContext (io.fabric8.kubernetes.client.dsl.base.CustomResourceDefinitionContext)3 Deployment (io.fabric8.kubernetes.api.model.apps.Deployment)2 DeploymentList (io.fabric8.kubernetes.api.model.apps.DeploymentList)2 KillSwitch (com.couchbase.connector.cluster.KillSwitch)1 Stopwatch (com.google.common.base.Stopwatch)1 PodDeletedEvent (com.netflix.titus.runtime.connector.kubernetes.fabric8io.model.PodDeletedEvent)1 PodEvent (com.netflix.titus.runtime.connector.kubernetes.fabric8io.model.PodEvent)1 PodUpdatedEvent (com.netflix.titus.runtime.connector.kubernetes.fabric8io.model.PodUpdatedEvent)1