From 6c234d91a96208767e53192b9a10075a58dd39f2 Mon Sep 17 00:00:00 2001 From: laxmikantbpandhare Date: Fri, 6 Aug 2021 12:00:51 -0700 Subject: [PATCH 1/4] feature: Micrometer Integration for generating metrics - #64 feature: micrometer integration for genering metrics feature: modified variables and made it private feature: added changes for customize increment method feature: removed ConterDetails class and modified IncrementCounter accordingly feature: modified pom depedency feature: modified pom depedency feature: added changes and wrapped counter and timer with createAndUpdate method feature: modified and added inceremenmt() method feature: modified for enabling google formatter removed spaces removed spaces feature: added counter and timer for delete resource feature: added counter and timer for delete resource feature: added changes for delete resource feature: added changes for delete resource feature: update control modified feature: delete control modified feature: delete control modified test delete resource feature: modiofied to retest feature: modified according to PR review comments feature: added count for each and event (create, update, and delete) feature: added count for each and event (create, update, and delete) feature: added Histogram changes for Time feature: added histogram changes for delete as well feature: modified name field in tags feature: retry counter added --- operator-framework-core/pom.xml | 12 ++ .../io/javaoperatorsdk/operator/Metrics.java | 182 ++++++++++++++++++ .../io/javaoperatorsdk/operator/Operator.java | 9 +- .../api/config/ConfigurationService.java | 5 + .../processing/DefaultEventHandler.java | 4 + .../operator/processing/EventDispatcher.java | 15 +- .../processing/EventDispatcherTest.java | 10 +- .../operator/IntegrationTestSupport.java | 2 +- 8 files changed, 233 insertions(+), 6 deletions(-) create mode 100644 operator-framework-core/src/main/java/io/javaoperatorsdk/operator/Metrics.java diff --git a/operator-framework-core/pom.xml b/operator-framework-core/pom.xml index 14851dc779..2c5fcf9053 100644 --- a/operator-framework-core/pom.xml +++ b/operator-framework-core/pom.xml @@ -15,6 +15,13 @@ Core framework for implementing Kubernetes operators jar + + 11 + 11 + 11 + 1.7.3 + + @@ -92,5 +99,10 @@ log4j-core test + + io.micrometer + micrometer-core + ${micrometer-core.version} + diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/Metrics.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/Metrics.java new file mode 100644 index 0000000000..6e3bd7a140 --- /dev/null +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/Metrics.java @@ -0,0 +1,182 @@ +package io.javaoperatorsdk.operator; + +import io.fabric8.kubernetes.client.CustomResource; +import io.javaoperatorsdk.operator.api.Context; +import io.javaoperatorsdk.operator.api.DeleteControl; +import io.javaoperatorsdk.operator.api.ResourceController; +import io.javaoperatorsdk.operator.api.UpdateControl; +import io.javaoperatorsdk.operator.api.config.ControllerConfiguration; +import io.micrometer.core.instrument.*; +import io.micrometer.core.instrument.distribution.DistributionStatisticConfig; +import io.micrometer.core.instrument.distribution.pause.PauseDetector; +import io.micrometer.core.instrument.noop.*; +import java.util.concurrent.TimeUnit; +import java.util.function.ToDoubleFunction; +import java.util.function.ToLongFunction; + +public class Metrics { + public static final Metrics NOOP = new Metrics(new NoopMeterRegistry(Clock.SYSTEM)); + private final MeterRegistry registry; + + public Metrics(MeterRegistry registry) { + this.registry = registry; + } + + public UpdateControl timeControllerCreateOrUpdate( + ResourceController controller, + ControllerConfiguration configuration, + R resource, + Context context) { + final var name = configuration.getName(); + final var timer = + Timer.builder("operator.sdk.controllers.execution.createorupdate") + .tags("controller", name) + .publishPercentiles(0.3, 0.5, 0.95) + .publishPercentileHistogram() + .register(registry); + try { + final var result = timer.record(() -> controller.createOrUpdateResource(resource, context)); + String successType = "cr"; + if (result.isUpdateStatusSubResource()) { + successType = "status"; + } + if (result.isUpdateCustomResourceAndStatusSubResource()) { + successType = "both"; + } + registry + .counter( + "operator.sdk.controllers.execution.success", "controller", name, "type", successType) + .increment(); + registry + .counter("operator.sdk.events.received", "events", name, "type", "totalEvents") + .increment(); + return result; + } catch (Exception e) { + registry + .counter( + "operator.sdk.controllers.execution.failure", + "controller", + name, + "exception", + e.getClass().getSimpleName()) + .increment(); + registry + .counter("operator.sdk.events.received", "events", name, "exception", "totalEvents") + .increment(); + throw e; + } + } + + public DeleteControl timeControllerDelete( + ResourceController controller, + ControllerConfiguration configuration, + CustomResource resource, + Context context) { + final var name = configuration.getName(); + final var timer = + Timer.builder("operator.sdk.controllers.execution.delete") + .tags("controller", name) + .publishPercentiles(0.3, 0.5, 0.95) + .publishPercentileHistogram() + .register(registry); + try { + final var result = timer.record(() -> controller.deleteResource(resource, context)); + String successType = "notDelete"; + if (result == DeleteControl.DEFAULT_DELETE) { + successType = "delete"; + } + registry + .counter( + "operator.sdk.controllers.execution.success", "controller", name, "type", successType) + .increment(); + registry + .counter("operator.sdk.events.received", "events", name, "type", "totalEvents") + .increment(); + return result; + } catch (Exception e) { + registry + .counter( + "operator.sdk.controllers.execution.failure", + "controller", + name, + "exception", + e.getClass().getSimpleName()) + .increment(); + registry + .counter("operator.sdk.events.received", "events", name, "exception", "totalEvents") + .increment(); + throw e; + } + } + + public void timeControllerRetry() { + + registry + .counter( + "operator.sdk.retry.on.exception", "retry", "retryCounter", "type", + "retryException") + .increment(); + + } + + public static class NoopMeterRegistry extends MeterRegistry { + public NoopMeterRegistry(Clock clock) { + super(clock); + } + + @Override + protected Gauge newGauge(Meter.Id id, T t, ToDoubleFunction toDoubleFunction) { + return new NoopGauge(id); + } + + @Override + protected Counter newCounter(Meter.Id id) { + return new NoopCounter(id); + } + + @Override + protected Timer newTimer( + Meter.Id id, + DistributionStatisticConfig distributionStatisticConfig, + PauseDetector pauseDetector) { + return new NoopTimer(id); + } + + @Override + protected DistributionSummary newDistributionSummary( + Meter.Id id, DistributionStatisticConfig distributionStatisticConfig, double v) { + return new NoopDistributionSummary(id); + } + + @Override + protected Meter newMeter(Meter.Id id, Meter.Type type, Iterable iterable) { + return new NoopMeter(id); + } + + @Override + protected FunctionTimer newFunctionTimer( + Meter.Id id, + T t, + ToLongFunction toLongFunction, + ToDoubleFunction toDoubleFunction, + TimeUnit timeUnit) { + return new NoopFunctionTimer(id); + } + + @Override + protected FunctionCounter newFunctionCounter( + Meter.Id id, T t, ToDoubleFunction toDoubleFunction) { + return new NoopFunctionCounter(id); + } + + @Override + protected TimeUnit getBaseTimeUnit() { + return TimeUnit.SECONDS; + } + + @Override + protected DistributionStatisticConfig defaultHistogramConfig() { + return DistributionStatisticConfig.NONE; + } + } +} diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/Operator.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/Operator.java index 0894d9ac70..dc0de9b415 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/Operator.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/Operator.java @@ -25,14 +25,17 @@ public class Operator implements AutoCloseable { private final Object lock; private final List controllers; private volatile boolean started; + private final Metrics metrics; - public Operator(KubernetesClient k8sClient, ConfigurationService configurationService) { + public Operator( + KubernetesClient k8sClient, ConfigurationService configurationService, Metrics metrics) { this.k8sClient = k8sClient; this.configurationService = configurationService; this.closeables = new ArrayList<>(); this.lock = new Object(); this.controllers = new ArrayList<>(); this.started = false; + this.metrics = metrics; } /** Adds a shutdown hook that automatically calls {@link #close()} when the app shuts down. */ @@ -40,6 +43,10 @@ public void installShutdownHook() { Runtime.getRuntime().addShutdownHook(new Thread(this::close)); } + public Operator(KubernetesClient k8sClient, ConfigurationService configurationService) { + this(k8sClient, configurationService, Metrics.NOOP); + } + public KubernetesClient getKubernetesClient() { return k8sClient; } diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ConfigurationService.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ConfigurationService.java index 7482080148..126bb46b93 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ConfigurationService.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ConfigurationService.java @@ -3,6 +3,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import io.fabric8.kubernetes.client.Config; import io.fabric8.kubernetes.client.CustomResource; +import io.javaoperatorsdk.operator.Metrics; import io.javaoperatorsdk.operator.api.ResourceController; import java.util.Set; @@ -93,4 +94,8 @@ default ObjectMapper getObjectMapper() { default int getTerminationTimeoutSeconds() { return DEFAULT_TERMINATION_TIMEOUT_SECONDS; } + + default Metrics getMetrics() { + return Metrics.NOOP; + } } diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/DefaultEventHandler.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/DefaultEventHandler.java index ddd6cc8e4b..9ca0a2232a 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/DefaultEventHandler.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/DefaultEventHandler.java @@ -6,6 +6,7 @@ import io.fabric8.kubernetes.client.CustomResource; import io.fabric8.kubernetes.client.dsl.MixedOperation; +import io.javaoperatorsdk.operator.Metrics; import io.javaoperatorsdk.operator.api.ResourceController; import io.javaoperatorsdk.operator.api.RetryInfo; import io.javaoperatorsdk.operator.api.config.ConfigurationService; @@ -16,6 +17,7 @@ import io.javaoperatorsdk.operator.processing.retry.GenericRetry; import io.javaoperatorsdk.operator.processing.retry.Retry; import io.javaoperatorsdk.operator.processing.retry.RetryExecution; +import io.micrometer.core.instrument.Clock; import java.util.HashMap; import java.util.HashSet; import java.util.Map; @@ -46,6 +48,7 @@ public class DefaultEventHandler implements EventHandler { private final int terminationTimeout; private final ReentrantLock lock = new ReentrantLock(); private DefaultEventSourceManager eventSourceManager; + private final Metrics metrics = new Metrics(new Metrics.NoopMeterRegistry(Clock.SYSTEM)); public DefaultEventHandler( ResourceController controller, ControllerConfiguration configuration, MixedOperation client) { @@ -162,6 +165,7 @@ void eventProcessingFinished( if (retry != null && postExecutionControl.exceptionDuringExecution()) { handleRetryOnException(executionScope); + metrics.timeControllerRetry(); return; } diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/EventDispatcher.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/EventDispatcher.java index 382a973ea5..e69d69ffb7 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/EventDispatcher.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/EventDispatcher.java @@ -123,7 +123,12 @@ private PostExecutionControl handleCreateOrUpdate( getName(resource), getVersion(resource), executionScope); - UpdateControl updateControl = controller.createOrUpdateResource(resource, context); + + UpdateControl updateControl = + configuration + .getConfigurationService() + .getMetrics() + .timeControllerCreateOrUpdate(controller, configuration, resource, context); R updatedCustomResource = null; if (updateControl.isUpdateCustomResourceAndStatusSubResource()) { updatedCustomResource = updateCustomResource(updateControl.getCustomResource()); @@ -153,8 +158,12 @@ private PostExecutionControl handleDelete(R resource, Context context) { "Executing delete for resource: {} with version: {}", getName(resource), getVersion(resource)); - // todo: this is be executed in a try-catch statement, in case this fails - DeleteControl deleteControl = controller.deleteResource(resource, context); + + DeleteControl deleteControl = + configuration + .getConfigurationService() + .getMetrics() + .timeControllerDelete(controller, configuration, resource, context); final var useFinalizer = configuration.useFinalizer(); if (useFinalizer) { if (deleteControl == DeleteControl.DEFAULT_DELETE diff --git a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/EventDispatcherTest.java b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/EventDispatcherTest.java index 1d00ebfcac..fa44508227 100644 --- a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/EventDispatcherTest.java +++ b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/EventDispatcherTest.java @@ -15,12 +15,14 @@ import io.fabric8.kubernetes.client.CustomResource; import io.fabric8.kubernetes.client.Watcher; +import io.javaoperatorsdk.operator.Metrics; import io.javaoperatorsdk.operator.TestUtils; import io.javaoperatorsdk.operator.api.Context; import io.javaoperatorsdk.operator.api.DeleteControl; import io.javaoperatorsdk.operator.api.ResourceController; import io.javaoperatorsdk.operator.api.RetryInfo; import io.javaoperatorsdk.operator.api.UpdateControl; +import io.javaoperatorsdk.operator.api.config.ConfigurationService; import io.javaoperatorsdk.operator.api.config.ControllerConfiguration; import io.javaoperatorsdk.operator.processing.event.Event; import io.javaoperatorsdk.operator.processing.event.internal.CustomResourceEvent; @@ -40,6 +42,7 @@ class EventDispatcherTest { private final ResourceController controller = mock(ResourceController.class); private ControllerConfiguration configuration = mock(ControllerConfiguration.class); + private final ConfigurationService configService = mock(ConfigurationService.class); private final EventDispatcher.CustomResourceFacade customResourceFacade = mock(EventDispatcher.CustomResourceFacade.class); @@ -51,6 +54,9 @@ void setup() { when(configuration.getFinalizer()).thenReturn(DEFAULT_FINALIZER); when(configuration.useFinalizer()).thenCallRealMethod(); + when(configuration.getName()).thenReturn("EventDispatcherTestController"); + when(configService.getMetrics()).thenReturn(Metrics.NOOP); + when(configuration.getConfigurationService()).thenReturn(configService); when(controller.createOrUpdateResource(eq(testCustomResource), any())) .thenReturn(UpdateControl.updateCustomResource(testCustomResource)); when(controller.deleteResource(eq(testCustomResource), any())) @@ -135,7 +141,6 @@ void callsDeleteIfObjectHasFinalizerAndMarkedForDelete() { @Test void callDeleteOnControllerIfMarkedForDeletionWhenNoFinalizerIsConfigured() { configureToNotUseFinalizer(); - markForDeletion(testCustomResource); eventDispatcher.handleExecution( @@ -156,6 +161,9 @@ void doNotCallDeleteIfMarkedForDeletionWhenFinalizerHasAlreadyBeenRemoved() { private void configureToNotUseFinalizer() { ControllerConfiguration configuration = mock(ControllerConfiguration.class); + when(configuration.getName()).thenReturn("EventDispatcherTestController"); + when(configService.getMetrics()).thenReturn(Metrics.NOOP); + when(configuration.getConfigurationService()).thenReturn(configService); when(configuration.useFinalizer()).thenReturn(false); eventDispatcher = new EventDispatcher(controller, configuration, customResourceFacade); } diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/IntegrationTestSupport.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/IntegrationTestSupport.java index fc1cd343cb..bbdb510d8e 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/IntegrationTestSupport.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/IntegrationTestSupport.java @@ -59,7 +59,7 @@ public void initialize(KubernetesClient k8sClient, ResourceController controller namespaces.create( new NamespaceBuilder().withNewMetadata().withName(TEST_NAMESPACE).endMetadata().build()); } - operator = new Operator(k8sClient, configurationService); + operator = new Operator(k8sClient, configurationService, Metrics.NOOP); final var overriddenConfig = ControllerConfigurationOverrider.override(config).settingNamespace(TEST_NAMESPACE); if (retry != null) { From 04ad0bd2218021bb5979b011c48e2835c81150f0 Mon Sep 17 00:00:00 2001 From: laxmikantbpandhare Date: Wed, 25 Aug 2021 23:08:53 -0700 Subject: [PATCH 2/4] feature: modified events logic --- .../io/javaoperatorsdk/operator/Metrics.java | 24 +++++++++---------- .../processing/DefaultEventHandler.java | 1 + 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/Metrics.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/Metrics.java index 6e3bd7a140..c8a0761a1a 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/Metrics.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/Metrics.java @@ -36,6 +36,7 @@ public UpdateControl timeControllerCreateOrUpdate( .register(registry); try { final var result = timer.record(() -> controller.createOrUpdateResource(resource, context)); + System.out.println("I am here in create update"); String successType = "cr"; if (result.isUpdateStatusSubResource()) { successType = "status"; @@ -47,9 +48,6 @@ public UpdateControl timeControllerCreateOrUpdate( .counter( "operator.sdk.controllers.execution.success", "controller", name, "type", successType) .increment(); - registry - .counter("operator.sdk.events.received", "events", name, "type", "totalEvents") - .increment(); return result; } catch (Exception e) { registry @@ -60,9 +58,6 @@ public UpdateControl timeControllerCreateOrUpdate( "exception", e.getClass().getSimpleName()) .increment(); - registry - .counter("operator.sdk.events.received", "events", name, "exception", "totalEvents") - .increment(); throw e; } } @@ -81,6 +76,7 @@ public DeleteControl timeControllerDelete( .register(registry); try { final var result = timer.record(() -> controller.deleteResource(resource, context)); + System.out.println("I am here in delete"); String successType = "notDelete"; if (result == DeleteControl.DEFAULT_DELETE) { successType = "delete"; @@ -89,9 +85,6 @@ public DeleteControl timeControllerDelete( .counter( "operator.sdk.controllers.execution.success", "controller", name, "type", successType) .increment(); - registry - .counter("operator.sdk.events.received", "events", name, "type", "totalEvents") - .increment(); return result; } catch (Exception e) { registry @@ -102,9 +95,6 @@ public DeleteControl timeControllerDelete( "exception", e.getClass().getSimpleName()) .increment(); - registry - .counter("operator.sdk.events.received", "events", name, "exception", "totalEvents") - .increment(); throw e; } } @@ -119,6 +109,16 @@ public void timeControllerRetry() { } + public void timeControllerEvents() { + + registry + .counter( + "operator.sdk.total.events.received", "events", "totalEvents", "type", + "eventsReceived") + .increment(); + + } + public static class NoopMeterRegistry extends MeterRegistry { public NoopMeterRegistry(Clock clock) { super(clock); diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/DefaultEventHandler.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/DefaultEventHandler.java index 9ca0a2232a..8fdfb107fe 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/DefaultEventHandler.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/DefaultEventHandler.java @@ -116,6 +116,7 @@ public void handleEvent(Event event) { final Predicate selector = event.getCustomResourcesSelector(); for (String uid : eventSourceManager.getLatestResourceUids(selector)) { eventBuffer.addEvent(uid, event); + metrics.timeControllerEvents(); executeBufferedEvents(uid); } } finally { From 6380615510eb02000cc21bf1a8b1c9bf8902842e Mon Sep 17 00:00:00 2001 From: laxmikantbpandhare Date: Wed, 25 Aug 2021 23:12:36 -0700 Subject: [PATCH 3/4] comment: removed sysout --- .../src/main/java/io/javaoperatorsdk/operator/Metrics.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/Metrics.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/Metrics.java index c8a0761a1a..6edc599e47 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/Metrics.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/Metrics.java @@ -36,7 +36,6 @@ public UpdateControl timeControllerCreateOrUpdate( .register(registry); try { final var result = timer.record(() -> controller.createOrUpdateResource(resource, context)); - System.out.println("I am here in create update"); String successType = "cr"; if (result.isUpdateStatusSubResource()) { successType = "status"; @@ -76,7 +75,6 @@ public DeleteControl timeControllerDelete( .register(registry); try { final var result = timer.record(() -> controller.deleteResource(resource, context)); - System.out.println("I am here in delete"); String successType = "notDelete"; if (result == DeleteControl.DEFAULT_DELETE) { successType = "delete"; From 34a5dbe860b090eb9fe35a6507da9bbee6c79b0d Mon Sep 17 00:00:00 2001 From: laxmikantbpandhare Date: Thu, 26 Aug 2021 09:11:32 -0700 Subject: [PATCH 4/4] feature: modified for addition of config in defaulteventhandler --- .../processing/DefaultEventHandler.java | 21 ++++++++++++------- .../CustomResourceSelectorTest.java | 14 ++++++++++++- .../processing/DefaultEventHandlerTest.java | 16 ++++++++++++-- 3 files changed, 41 insertions(+), 10 deletions(-) diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/DefaultEventHandler.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/DefaultEventHandler.java index 8fdfb107fe..c59ca2dc9e 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/DefaultEventHandler.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/DefaultEventHandler.java @@ -48,7 +48,7 @@ public class DefaultEventHandler implements EventHandler { private final int terminationTimeout; private final ReentrantLock lock = new ReentrantLock(); private DefaultEventSourceManager eventSourceManager; - private final Metrics metrics = new Metrics(new Metrics.NoopMeterRegistry(Clock.SYSTEM)); + private ControllerConfiguration configuration; public DefaultEventHandler( ResourceController controller, ControllerConfiguration configuration, MixedOperation client) { @@ -57,20 +57,20 @@ public DefaultEventHandler( configuration.getName(), GenericRetry.fromConfiguration(configuration.getRetryConfiguration()), configuration.getConfigurationService().concurrentReconciliationThreads(), - configuration.getConfigurationService().getTerminationTimeoutSeconds()); + configuration.getConfigurationService().getTerminationTimeoutSeconds(), configuration); } DefaultEventHandler( EventDispatcher eventDispatcher, String relatedControllerName, Retry retry, - int concurrentReconciliationThreads) { + int concurrentReconciliationThreads, ControllerConfiguration configuration) { this( eventDispatcher, relatedControllerName, retry, concurrentReconciliationThreads, - ConfigurationService.DEFAULT_TERMINATION_TIMEOUT_SECONDS); + ConfigurationService.DEFAULT_TERMINATION_TIMEOUT_SECONDS, configuration); } private DefaultEventHandler( @@ -78,7 +78,7 @@ private DefaultEventHandler( String relatedControllerName, Retry retry, int concurrentReconciliationThreads, - int terminationTimeout) { + int terminationTimeout, ControllerConfiguration configuration) { this.eventDispatcher = eventDispatcher; this.retry = retry; this.controllerName = relatedControllerName; @@ -88,6 +88,7 @@ private DefaultEventHandler( new ScheduledThreadPoolExecutor( concurrentReconciliationThreads, runnable -> new Thread(runnable, "EventHandler-" + relatedControllerName)); + this.configuration = configuration; } @Override @@ -116,7 +117,10 @@ public void handleEvent(Event event) { final Predicate selector = event.getCustomResourcesSelector(); for (String uid : eventSourceManager.getLatestResourceUids(selector)) { eventBuffer.addEvent(uid, event); - metrics.timeControllerEvents(); + configuration + .getConfigurationService() + .getMetrics() + .timeControllerEvents(); executeBufferedEvents(uid); } } finally { @@ -166,7 +170,10 @@ void eventProcessingFinished( if (retry != null && postExecutionControl.exceptionDuringExecution()) { handleRetryOnException(executionScope); - metrics.timeControllerRetry(); + configuration + .getConfigurationService() + .getMetrics() + .timeControllerRetry(); return; } diff --git a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/CustomResourceSelectorTest.java b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/CustomResourceSelectorTest.java index 5bc2eb20e9..72c681b857 100644 --- a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/CustomResourceSelectorTest.java +++ b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/CustomResourceSelectorTest.java @@ -11,10 +11,13 @@ import static org.mockito.Mockito.when; import io.fabric8.kubernetes.client.Watcher; +import io.javaoperatorsdk.operator.Metrics; import io.javaoperatorsdk.operator.api.config.ConfigurationService; +import io.javaoperatorsdk.operator.api.config.ControllerConfiguration; import io.javaoperatorsdk.operator.processing.event.DefaultEvent; import io.javaoperatorsdk.operator.processing.event.DefaultEventSourceManager; import io.javaoperatorsdk.operator.processing.event.internal.CustomResourceEvent; +import io.javaoperatorsdk.operator.processing.event.internal.TimerEventSource; import io.javaoperatorsdk.operator.sample.simple.TestCustomResource; import java.util.Objects; import java.util.UUID; @@ -33,12 +36,17 @@ class CustomResourceSelectorTest { private final DefaultEventSourceManager defaultEventSourceManagerMock = mock(DefaultEventSourceManager.class); + private TimerEventSource retryTimerEventSourceMock = mock(TimerEventSource.class); + private ControllerConfiguration configuration = + mock(ControllerConfiguration.class); + private final ConfigurationService configService = mock(ConfigurationService.class); + private final DefaultEventHandler defaultEventHandler = new DefaultEventHandler( eventDispatcherMock, "Test", null, - ConfigurationService.DEFAULT_RECONCILIATION_THREADS_NUMBER); + ConfigurationService.DEFAULT_RECONCILIATION_THREADS_NUMBER, configuration); @BeforeEach public void setup() { @@ -58,6 +66,10 @@ public void setup() { }) .when(defaultEventSourceManagerMock) .cleanup(any()); + + when(configuration.getName()).thenReturn("DefaultEventHandlerTest"); + when(configService.getMetrics()).thenReturn(Metrics.NOOP); + when(configuration.getConfigurationService()).thenReturn(configService); } @Test diff --git a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/DefaultEventHandlerTest.java b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/DefaultEventHandlerTest.java index b4bd89dd18..699784180f 100644 --- a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/DefaultEventHandlerTest.java +++ b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/DefaultEventHandlerTest.java @@ -13,8 +13,11 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import io.fabric8.kubernetes.client.CustomResource; import io.fabric8.kubernetes.client.Watcher; +import io.javaoperatorsdk.operator.Metrics; import io.javaoperatorsdk.operator.api.config.ConfigurationService; +import io.javaoperatorsdk.operator.api.config.ControllerConfiguration; import io.javaoperatorsdk.operator.processing.event.DefaultEventSourceManager; import io.javaoperatorsdk.operator.processing.event.Event; import io.javaoperatorsdk.operator.processing.event.internal.CustomResourceEvent; @@ -44,20 +47,25 @@ class DefaultEventHandlerTest { mock(DefaultEventSourceManager.class); private TimerEventSource retryTimerEventSourceMock = mock(TimerEventSource.class); + private ControllerConfiguration configuration = + mock(ControllerConfiguration.class); + private final ConfigurationService configService = mock(ConfigurationService.class); private DefaultEventHandler defaultEventHandler = new DefaultEventHandler( eventDispatcherMock, "Test", null, - ConfigurationService.DEFAULT_RECONCILIATION_THREADS_NUMBER); + ConfigurationService.DEFAULT_RECONCILIATION_THREADS_NUMBER, + configuration); private DefaultEventHandler defaultEventHandlerWithRetry = new DefaultEventHandler( eventDispatcherMock, "Test", GenericRetry.defaultLimitedExponentialRetry(), - ConfigurationService.DEFAULT_RECONCILIATION_THREADS_NUMBER); + ConfigurationService.DEFAULT_RECONCILIATION_THREADS_NUMBER, + configuration); @BeforeEach public void setup() { @@ -66,6 +74,10 @@ public void setup() { defaultEventHandler.setEventSourceManager(defaultEventSourceManagerMock); defaultEventHandlerWithRetry.setEventSourceManager(defaultEventSourceManagerMock); + when(configuration.getName()).thenReturn("DefaultEventHandlerTest"); + when(configService.getMetrics()).thenReturn(Metrics.NOOP); + when(configuration.getConfigurationService()).thenReturn(configService); + // todo: remove when(defaultEventSourceManagerMock.getCache()).thenReturn(customResourceCache); doCallRealMethod().when(defaultEventSourceManagerMock).getLatestResource(any());