io.fabric8.kubernetes.client.Watcher Java Examples
The following examples show how to use
io.fabric8.kubernetes.client.Watcher.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: EventSchedulerTest.java From java-operator-sdk with Apache License 2.0 | 6 votes |
@Test public void notGenerationAwareSchedulingProcessesAllEventsRegardlessOfGeneration() { generationUnAwareScheduler(); normalDispatcherExecution(); CustomResource resource1 = sampleResource(); CustomResource resource2 = sampleResource(); resource2.getMetadata().setResourceVersion("2"); eventScheduler.eventReceived(Watcher.Action.MODIFIED, resource1); eventScheduler.eventReceived(Watcher.Action.MODIFIED, resource2); waitTimeForExecution(2); log.info("Event processing details 1.: {}. 2: {}", eventProcessingList.get(0), eventProcessingList.get(1)); assertThat(eventProcessingList).hasSize(2) .matches(list -> eventProcessingList.get(0).getCustomResource().getMetadata().getResourceVersion().equals("1") && eventProcessingList.get(1).getCustomResource().getMetadata().getResourceVersion().equals("2"), "Events processed in correct order") .matches(list -> eventExecutedBefore(0, 1), "Start time of event 2 is after end time of event 1"); }
Example #2
Source File: KubernetesDockerRunnerTest.java From styx with Apache License 2.0 | 6 votes |
@Test public void shouldGenerateStartedAndRecordSubmitToRunningTimeWhenContainerIsReady() throws Exception { when(time.nanoTime()).thenReturn(TimeUnit.SECONDS.toNanos(17)); kdr.start(RUN_STATE, RunSpec.simple(POD_NAME, "busybox")); verify(stats).recordSubmission(POD_NAME); when(time.nanoTime()).thenReturn(TimeUnit.SECONDS.toNanos(18)); when(time.nanoTime()).thenReturn(TimeUnit.SECONDS.toNanos(19)); setRunning(createdPod, /* ready= */ false); receiveAndProcessEvent(Watcher.Action.MODIFIED, createdPod); verify(stateManager, never()).receive(Event.started(WORKFLOW_INSTANCE), -1); when(time.nanoTime()).thenReturn(TimeUnit.SECONDS.toNanos(4711)); setRunning(createdPod, /* ready= */ true); receiveAndProcessEvent(Watcher.Action.MODIFIED, createdPod); verify(stateManager).receive(Event.started(WORKFLOW_INSTANCE), -1); verify(stats).recordRunning(POD_NAME); }
Example #3
Source File: KubernetesNamespaceTest.java From che with Eclipse Public License 2.0 | 6 votes |
@Test(expectedExceptions = InfrastructureException.class) public void testThrowsInfrastructureExceptionWhenWatcherClosed() throws Exception { prepareCreateNamespaceRequest(); final Resource resource = prepareNamespaceResource(NAMESPACE); doThrow(new KubernetesClientException("error", 403, null)).when(resource).get(); when(serviceAccountResource.get()).thenReturn(null); doAnswer( (Answer<Watch>) invocation -> { final Watcher<ServiceAccount> watcher = invocation.getArgument(0); watcher.onClose(mock(KubernetesClientException.class)); return mock(Watch.class); }) .when(serviceAccountResource) .watch(any()); new KubernetesNamespace(clientFactory, executor, NAMESPACE, WORKSPACE_ID).prepare(false); }
Example #4
Source File: RawWatchConnectionManager.java From kubernetes-client with Apache License 2.0 | 6 votes |
public RawWatchConnectionManager(OkHttpClient okHttpClient, HttpUrl.Builder watchUrlBuilder, ListOptions listOptions, ObjectMapper objectMapper, final Watcher<String> watcher, int reconnectLimit, int reconnectInterval, int maxIntervalExponent) { this.clonedClient = okHttpClient; this.watchUrlBuilder = watchUrlBuilder; this.objectMapper = objectMapper; this.watcher = watcher; this.reconnectLimit = reconnectLimit; this.reconnectInterval = reconnectInterval; this.resourceVersion = new AtomicReference<>(listOptions.getResourceVersion()); this.maxIntervalExponent = maxIntervalExponent; executor = Executors.newSingleThreadScheduledExecutor(r -> { Thread ret = new Thread(r, "Executor for Watch " + System.identityHashCode(RawWatchConnectionManager.this)); ret.setDaemon(true); return ret; }); runWatch(); }
Example #5
Source File: WatchOverHTTP.java From kubernetes-client with Apache License 2.0 | 6 votes |
@Test public void testOutdated() throws InterruptedException { logger.info("testOutdated"); KubernetesClient client = server.getClient().inNamespace("test"); server.expect() .withPath(path) .andReturn(200, "Failed WebSocket Connection").once(); server.expect().withPath(path).andReturnChunked(200, outdatedEvent, "\n").once(); final boolean[] onCloseCalled = {false}; try (Watch watch = client.pods().withName("pod1").withResourceVersion("1").watch(new Watcher<Pod>() { @Override public void eventReceived(Action action, Pod resource) { throw new AssertionFailedError(); } @Override public void onClose(KubernetesClientException cause) { onCloseCalled[0] = true; } })){}; assertTrue(onCloseCalled[0]); }
Example #6
Source File: KubernetesPersistentVolumeClaims.java From che with Eclipse Public License 2.0 | 6 votes |
private Watch pvcIsBoundWatcher( CompletableFuture<PersistentVolumeClaim> future, Resource<PersistentVolumeClaim, DoneablePersistentVolumeClaim> pvcResource) { return pvcResource.watch( new Watcher<PersistentVolumeClaim>() { @Override public void eventReceived(Action action, PersistentVolumeClaim pvc) { if (pvc.getStatus().getPhase().equals(PVC_BOUND_PHASE)) { LOG.debug("pvc '" + pvc.getMetadata().getName() + "' is bound"); future.complete(pvc); } } @Override public void onClose(KubernetesClientException cause) { safelyFinishFutureOnClose(cause, future, pvcResource.get().getMetadata().getName()); } }); }
Example #7
Source File: Reaper.java From kubernetes-plugin with Apache License 2.0 | 6 votes |
@Override public void eventReceived(Watcher.Action action, Pod pod) { String ns = pod.getMetadata().getNamespace(); String name = pod.getMetadata().getName(); Jenkins jenkins = Jenkins.getInstanceOrNull(); if (jenkins == null) { return; } Optional<KubernetesSlave> optionalNode = resolveNode(jenkins, ns, name); if (!optionalNode.isPresent()) { return; } ExtensionList.lookup(Listener.class).forEach(listener -> { try { listener.onEvent(action, optionalNode.get(), pod); } catch (Exception x) { LOGGER.log(Level.WARNING, "Listener " + listener + " failed for " + ns + "/" + name, x); } }); }
Example #8
Source File: AbstractResourceOperator.java From strimzi-kafka-operator with Apache License 2.0 | 6 votes |
@SuppressWarnings("unchecked") // due to L extends KubernetesResourceList/*<T>*/ protected List<T> listInNamespace(String namespace, Labels selector) { NonNamespaceOperation<T, L, D, R> tldrNonNamespaceOperation = operation().inNamespace(namespace); if (selector != null) { Map<String, String> labels = selector.toMap(); FilterWatchListDeletable<T, L, Boolean, Watch, Watcher<T>> tlBooleanWatchWatcherFilterWatchListDeletable = tldrNonNamespaceOperation.withLabels(labels); return tlBooleanWatchWatcherFilterWatchListDeletable .list() .getItems(); } else { return tldrNonNamespaceOperation .list() .getItems(); } }
Example #9
Source File: StatefulSetRollingUpdater.java From kubernetes-client with Apache License 2.0 | 6 votes |
@Override protected PodList listSelectedPods(StatefulSet obj) { FilterWatchListDeletable<Pod, PodList, Boolean, Watch, Watcher<Pod>> podLister = pods().inNamespace(namespace); if (obj.getSpec().getSelector().getMatchLabels() != null) { podLister.withLabels(obj.getSpec().getSelector().getMatchLabels()); } if (obj.getSpec().getSelector().getMatchExpressions() != null) { for (LabelSelectorRequirement req : obj.getSpec().getSelector().getMatchExpressions()) { switch (req.getOperator()) { case "In": podLister.withLabelIn(req.getKey(), req.getValues().toArray(new String[]{})); break; case "NotIn": podLister.withLabelNotIn(req.getKey(), req.getValues().toArray(new String[]{})); break; case "DoesNotExist": podLister.withoutLabel(req.getKey()); break; case "Exists": podLister.withLabel(req.getKey()); break; } } } return podLister.list(); }
Example #10
Source File: WatchTest.java From kubernetes-client with Apache License 2.0 | 6 votes |
@Test public void testHttpErrorWithOutdated() { Assertions.assertThrows(KubernetesClientException.class, () -> { logger.info("testHttpErrorWithOutdated"); KubernetesClient client = server.getClient().inNamespace("test"); // http error: history outdated server.expect() .withPath("/api/v1/namespaces/test/pods?fieldSelector=metadata.name%3Dpod1&resourceVersion=1&watch=true") .andReturn(410, outdatedEvent).once(); final boolean[] onCloseCalled = {false}; try (Watch watch = client.pods().withName("pod1").withResourceVersion("1").watch(new Watcher<Pod>() { @Override public void eventReceived(Action action, Pod resource) { throw new AssertionFailedError(); } @Override public void onClose(KubernetesClientException cause) { onCloseCalled[0] =true; } })) { } assertTrue(onCloseCalled[0]); }); }
Example #11
Source File: EventSchedulerTest.java From java-operator-sdk with Apache License 2.0 | 6 votes |
@Test public void onlyLastEventIsScheduledIfMoreReceivedDuringAndExecution() { normalDispatcherExecution(); CustomResource resource1 = sampleResource(); CustomResource resource2 = sampleResource(); resource2.getMetadata().setResourceVersion("2"); resource2.getMetadata().setGeneration(2l); CustomResource resource3 = sampleResource(); resource3.getMetadata().setResourceVersion("3"); resource3.getMetadata().setGeneration(3l); eventScheduler.eventReceived(Watcher.Action.MODIFIED, resource1); eventScheduler.eventReceived(Watcher.Action.MODIFIED, resource2); eventScheduler.eventReceived(Watcher.Action.MODIFIED, resource3); waitTimeForExecution(3); log.info("Event processing details 1.: {}. 2: {}", eventProcessingList.get(0), eventProcessingList.get(1)); assertThat(eventProcessingList).hasSize(2) .matches(list -> eventProcessingList.get(0).getCustomResource().getMetadata().getResourceVersion().equals("1") && eventProcessingList.get(1).getCustomResource().getMetadata().getResourceVersion().equals("3"), "Events processed in correct order") .matches(list -> eventExecutedBefore(0, 1), "Start time of event 2 is after end time of event 1"); }
Example #12
Source File: KubernetesDockerRunnerTest.java From styx with Apache License 2.0 | 5 votes |
@Test public void shouldFailOnMissingContainer() throws Exception { createdPod.setStatus(podStatusNoContainer("Succeeded")); receiveAndProcessEvent(Watcher.Action.MODIFIED, createdPod); verify(stateManager).receive( Event.runError(WORKFLOW_INSTANCE, "Could not find our container in pod"), -1); }
Example #13
Source File: Pods.java From dekorate with Apache License 2.0 | 5 votes |
/** * Returns the {@link PodList} that match the specified {@link ReplicaSet}. * * @param replicaSet The {@link ReplicaSet} */ protected PodList map(ReplicaSet replicaSet) { FilterWatchListDeletable<Pod, PodList, Boolean, Watch, Watcher<Pod>> podLister = client.pods() .inNamespace(replicaSet.getMetadata().getNamespace()); if (replicaSet.getSpec().getSelector().getMatchLabels() != null) { podLister.withLabels(replicaSet.getSpec().getSelector().getMatchLabels()); } if (replicaSet.getSpec().getSelector().getMatchExpressions() != null) { for (LabelSelectorRequirement req : replicaSet.getSpec().getSelector().getMatchExpressions()) { switch (req.getOperator()) { case "In": podLister.withLabelIn(req.getKey(), req.getValues().toArray(new String[] {})); break; case "NotIn": podLister.withLabelNotIn(req.getKey(), req.getValues().toArray(new String[] {})); break; case "DoesNotExist": podLister.withoutLabel(req.getKey()); break; case "Exists": podLister.withLabel(req.getKey()); break; } } } return podLister.list(); }
Example #14
Source File: MockBuilder.java From strimzi-kafka-operator with Apache License 2.0 | 5 votes |
private T doPatch(String resourceName, R resource, T instance) { checkDoesExist(resourceName); T argument = copyResource(instance); LOGGER.debug("patch {} {} -> {}", resourceType, resourceName, resource); db.put(resourceName, incrementGeneration(incrementResourceVersion(argument))); fireWatchers(resourceName, argument, Watcher.Action.MODIFIED, "patch"); return copyResource(argument); }
Example #15
Source File: TopicOperatorTest.java From strimzi-kafka-operator with Apache License 2.0 | 5 votes |
/** * Test reconciliation when a topic has been deleted while the operator * wasn't running */ @Test public void testReconcile_withResource_noKafka_withPrivate(VertxTestContext context) { Topic kubeTopic = new Topic.Builder(topicName.toString(), 10, (short) 2, map("cleanup.policy", "bar")).build(); Topic kafkaTopic = null; Topic privateTopic = kubeTopic; Checkpoint async0 = context.checkpoint(2); KafkaTopic topicResource = TopicSerialization.toTopicResource(kubeTopic, labels); LogContext logContext = LogContext.kubeWatch(Watcher.Action.DELETED, topicResource); mockK8s.setCreateResponse(resourceName, null) .createResource(topicResource).onComplete(ar -> async0.flag()); mockK8s.setDeleteResponse(resourceName, null); mockTopicStore.setCreateTopicResponse(topicName, null) .create(privateTopic).onComplete(ar -> async0.flag()); mockTopicStore.setDeleteTopicResponse(topicName, null); Checkpoint async = context.checkpoint(); topicOperator.reconcile(reconciliation(), logContext, null, kubeTopic, kafkaTopic, privateTopic).onComplete(reconcileResult -> { assertSucceeded(context, reconcileResult); mockKafka.assertNotExists(context, kubeTopic.getTopicName()); mockTopicStore.assertNotExists(context, kubeTopic.getTopicName()); mockK8s.assertNotExists(context, kubeTopic.getResourceName()); mockK8s.assertNoEvents(context); context.completeNow(); }); }
Example #16
Source File: PodReadinessWatcherTest.java From spring-cloud-kubernetes with Apache License 2.0 | 5 votes |
@Test public void shouldIgnoreEventIfStateDoesNotChange() { given(this.mockPod.getStatus()).willReturn(this.mockPodStatus); this.watcher.start(); this.watcher.eventReceived(Watcher.Action.ADDED, this.mockPod); verify(this.mockLeadershipController, times(0)).update(); }
Example #17
Source File: KubernetesDockerRunner.java From styx with Apache License 2.0 | 5 votes |
@Override public void poll(RunState runState) { var executionId = runState.data().executionId().orElseThrow(IllegalArgumentException::new); var podOpt = client.getPod(executionId); if (podOpt.isEmpty()) { // No pod found. Emit an error guarded by the state counter we are basing the error conclusion on. stateManager.receiveIgnoreClosed( Event.runError(runState.workflowInstance(), "No pod associated with this instance"), runState.counter()); return; } var pod = podOpt.orElseThrow(); logEvent(Watcher.Action.MODIFIED, pod, pod.getMetadata().getResourceVersion(), true); emitPodEvents(pod, runState); }
Example #18
Source File: KubernetesDockerRunnerTest.java From styx with Apache License 2.0 | 5 votes |
@Test public void shouldIgnoreDeletedEvents() throws Exception { createdPod.setStatus(podStatusNoContainer("Succeeded")); receiveAndProcessEvent(Watcher.Action.DELETED, createdPod); verify(stateManager, never()).receive(any(), anyLong()); }
Example #19
Source File: KubernetesDockerRunner.java From styx with Apache License 2.0 | 5 votes |
private void logEvent(Watcher.Action action, Pod pod, String resourceVersion, boolean polled) { final String podName = pod.getMetadata().getName(); final String workflowInstance = Optional.ofNullable(pod.getMetadata().getAnnotations()) .map(annotations -> annotations.get(STYX_WORKFLOW_INSTANCE_ANNOTATION)) .orElse("N/A"); final String status = readStatus(pod); LOG.info("{}Pod event for {} ({}) at resource version {}, action: {}, workflow instance: {}, status: {}", polled ? "Polled: " : "", podName, pod.getMetadata().getUid(), resourceVersion, action, workflowInstance, status); }
Example #20
Source File: AbstractWatchableResourceOperator.java From strimzi-kafka-operator with Apache License 2.0 | 5 votes |
public Watch watch(String namespace, Optional<LabelSelector> selector, Watcher<T> watcher) { FilterWatchListDeletable<T, L, Boolean, Watch, Watcher<T>> operation = ANY_NAMESPACE.equals(namespace) ? operation().inAnyNamespace() : operation().inNamespace(namespace); if (selector.isPresent()) { operation = operation.withLabelSelector(selector.get()); } return operation.watch(watcher); }
Example #21
Source File: KubernetesDeploymentsTest.java From che with Eclipse Public License 2.0 | 5 votes |
@Test public void shouldCallHandlerForEventsOnDeployments() throws Exception { // Given when(objectReference.getKind()).thenReturn(DEPLOYMENT_OBJECT_KIND); kubernetesDeployments.watchEvents(podEventHandler); verify(eventNamespaceMixedOperation).watch(eventWatcherCaptor.capture()); Watcher<Event> watcher = eventWatcherCaptor.getValue(); // When watcher.eventReceived(Watcher.Action.ADDED, event); // Then verify(podEventHandler).handle(any()); }
Example #22
Source File: WatchOverHTTP.java From kubernetes-client with Apache License 2.0 | 5 votes |
@Test public void testDeleted() throws InterruptedException { logger.info("testDeleted"); KubernetesClient client = server.getClient().inNamespace("test"); server.expect() .withPath(path) .andReturn(200, "Failed WebSocket Connection").once(); server.expect().withPath(path).andReturnChunked(200, new WatchEvent(pod1, "DELETED"), "\n", new WatchEvent(pod1, "ADDED"), "\n").once(); final CountDownLatch addLatch = new CountDownLatch(1); final CountDownLatch deleteLatch = new CountDownLatch(1); try (Watch watch = client.pods().withName("pod1").withResourceVersion("1").watch(new Watcher<Pod>() { @Override public void eventReceived(Action action, Pod resource) { switch (action) { case DELETED: deleteLatch.countDown(); break; case ADDED: addLatch.countDown(); break; default: throw new AssertionFailedError(); } } @Override public void onClose(KubernetesClientException cause) {} })) /* autoclose */ { assertTrue(addLatch.await(10, TimeUnit.SECONDS)); assertTrue(deleteLatch.await(10, TimeUnit.SECONDS)); } }
Example #23
Source File: CustomResourceTest.java From kubernetes-client with Apache License 2.0 | 5 votes |
@Test @DisplayName("Should be able to test watch with ListOptions provided") public void testWatchWithListOptions() throws IOException, InterruptedException { // Given server.expect().withPath("/apis/test.fabric8.io/v1alpha1/namespaces/ns1/hellos?timeoutSeconds=30&allowWatchBookmarks=true&watch=true&resourceVersion=1003") .andUpgradeToWebSocket() .open() .waitFor(WATCH_EVENT_PERIOD) .andEmit(new WatchEvent(null, "ADDED")) .done().always(); KubernetesClient client = server.getClient(); CountDownLatch anyEventReceived = new CountDownLatch(1); // When Watch watch = client.customResource(customResourceDefinitionContext) .watch("ns1", null, null, new ListOptionsBuilder() .withTimeoutSeconds(30L) .withResourceVersion("1003") .withAllowWatchBookmarks(true) .build(), new Watcher<String>() { @Override public void eventReceived(Action action, String resource) { anyEventReceived.countDown(); } @Override public void onClose(KubernetesClientException cause) { } }); // Then assertTrue(anyEventReceived.await(1, TimeUnit.SECONDS)); watch.close(); }
Example #24
Source File: EventSchedulerTest.java From java-operator-sdk with Apache License 2.0 | 5 votes |
private Object exceptionInExecution(InvocationOnMock invocation) { try { Object[] args = invocation.getArguments(); LocalDateTime start = LocalDateTime.now(); Thread.sleep(INVOCATION_DURATION); LocalDateTime end = LocalDateTime.now(); IllegalStateException exception = new IllegalStateException("Exception thrown for testing purposes"); eventProcessingList.add(new EventProcessingDetail((Watcher.Action) args[0], start, end, (CustomResource) args[1], exception)); throw exception; } catch (InterruptedException e) { throw new IllegalStateException(e); } }
Example #25
Source File: KubernetesTaskLauncher.java From spring-cloud-deployer-kubernetes with Apache License 2.0 | 5 votes |
private void deletePod(String id) { FilterWatchListDeletable<Pod, PodList, Boolean, Watch, Watcher<Pod>> podsToDelete = client.pods() .withLabel(SPRING_APP_KEY, id); if (podsToDelete != null && podsToDelete.list().getItems() != null) { logger.debug(String.format("Deleting Pod for task: %s", id)); boolean podsDeleted = podsToDelete.delete(); logger.debug(String.format("Pod deleted for: %s - %b", id, podsDeleted)); } }
Example #26
Source File: KubernetesDockerRunnerTest.java From styx with Apache License 2.0 | 5 votes |
@Test public void shouldDiscardChangesForOldExecutions() throws Exception { kdr.start(RUN_STATE, RUN_SPEC); // simulate event from different pod, but still with the same workflow instance annotation createdPod.getMetadata().setName(POD_NAME + "-other"); setTerminated(createdPod, "Succeeded", 20, null); receiveAndProcessEvent(Watcher.Action.MODIFIED, createdPod); verify(stateManager, never()).receive(any(), anyLong()); }
Example #27
Source File: ConfigMapSupplierTest.java From data-highway with Apache License 2.0 | 5 votes |
@SuppressWarnings("unchecked") @Before public void before() { when(client.configMaps()).thenReturn(configMaps); when(configMaps.withName(name)).thenReturn(resource); when(resource.watch(any(Watcher.class))).thenReturn(watch); }
Example #28
Source File: WatchOverHTTP.java From kubernetes-client with Apache License 2.0 | 5 votes |
@Test public void testHttpErrorReconnect() throws InterruptedException { logger.info("testHttpErrorReconnect"); KubernetesClient client = server.getClient().inNamespace("test"); server.expect() .withPath(path) .andReturn(200, "Failed WebSocket Connection").once(); server.expect().withPath(path).andReturnChunked(503, new StatusBuilder().withCode(503).build()).times(6); server.expect().withPath(path).andReturnChunked(200, outdatedEvent, "\n").once(); final CountDownLatch closeLatch = new CountDownLatch(1); try (Watch watch = client.pods().withName("pod1").withResourceVersion("1").watch(new Watcher<Pod>() { @Override public void eventReceived(Action action, Pod resource) { throw new AssertionFailedError(); } @Override public void onClose(KubernetesClientException cause) { logger.debug("onClose", cause); closeLatch.countDown(); } })) /* autoclose */ { assertTrue(closeLatch.await(3, TimeUnit.MINUTES)); } }
Example #29
Source File: BaseOperation.java From kubernetes-client with Apache License 2.0 | 5 votes |
@Override public FilterWatchListDeletable<T, L, Boolean, Watch, Watcher<T>> withoutField(String key, String value) { fieldsNot.merge(key, new String[]{value}, (oldList, newList) -> { if (Utils.isNotNullOrEmpty(newList[0])) { // Only add new values when not null final String[] concatList = (String[]) Array.newInstance(String.class, oldList.length + newList.length); System.arraycopy(oldList, 0, concatList, 0, oldList.length); System.arraycopy(newList, 0, concatList, oldList.length, newList.length); return concatList; } else { return oldList; } }); return this; }
Example #30
Source File: TopicOperatorTest.java From strimzi-kafka-operator with Apache License 2.0 | 5 votes |
/** Test what happens when a non-topic KafkaTopic gets created in kubernetes */ @Test public void testOnKafkaTopicAdded_invalidResource(VertxTestContext context) { KafkaTopic kafkaTopic = new KafkaTopicBuilder() .withMetadata(new ObjectMetaBuilder().withName("invalid").withLabels(labels.labels()).build()) .withNewSpec() .withReplicas(1) .withPartitions(1) .withConfig(singletonMap(null, null)) .endSpec() .build(); mockK8s.setGetFromNameResponse(new ResourceName(kafkaTopic), Future.succeededFuture(kafkaTopic)); LogContext logContext = LogContext.kubeWatch(Watcher.Action.ADDED, kafkaTopic); Checkpoint async = context.checkpoint(); topicOperator.onResourceEvent(logContext, kafkaTopic, ADDED).onComplete(ar -> { assertFailed(context, ar); context.verify(() -> assertThat(ar.cause(), instanceOf(InvalidTopicException.class))); context.verify(() -> assertThat(ar.cause().getMessage(), is("KafkaTopic's spec.config has invalid entry: The key 'null' of the topic config is invalid: The value corresponding to the key must have a string, number or boolean value but the value was null"))); mockKafka.assertEmpty(context); mockTopicStore.assertEmpty(context); assertNotReadyStatus(context, new InvalidTopicException(null, ar.cause().getMessage())); context.verify(() -> { MeterRegistry registry = metrics.meterRegistry(); assertThat(registry.get(TopicOperator.METRICS_PREFIX + "reconciliations").tag("kind", "KafkaTopic").counter().count(), is(1.0)); assertThat(registry.get(TopicOperator.METRICS_PREFIX + "reconciliations.successful").tag("kind", "KafkaTopic").counter().count(), is(0.0)); assertThat(registry.get(TopicOperator.METRICS_PREFIX + "reconciliations.failed").tag("kind", "KafkaTopic").counter().count(), is(0.0)); assertThat(registry.get(TopicOperator.METRICS_PREFIX + "reconciliations.duration").tag("kind", "KafkaTopic").timer().count(), is(0L)); assertThat(registry.get(TopicOperator.METRICS_PREFIX + "reconciliations.duration").tag("kind", "KafkaTopic").timer().totalTime(TimeUnit.MILLISECONDS), is(0.0)); }); async.flag(); }); }