diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/AnnotationControllerConfiguration.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/AnnotationControllerConfiguration.java index c86c3f95b6..2407189c1c 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/AnnotationControllerConfiguration.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/AnnotationControllerConfiguration.java @@ -34,6 +34,7 @@ public class AnnotationControllerConfiguration protected final Reconciler reconciler; private final ControllerConfiguration annotation; private List specs; + private Class resourceClass; public AnnotationControllerConfiguration(Reconciler reconciler) { this.reconciler = reconciler; @@ -81,7 +82,12 @@ public Set getNamespaces() { @Override @SuppressWarnings("unchecked") public Class getResourceClass() { - return (Class) Utils.getFirstTypeArgumentFromInterface(reconciler.getClass()); + if (resourceClass == null) { + resourceClass = + (Class) Utils.getFirstTypeArgumentFromSuperClassOrInterface(reconciler.getClass(), + Reconciler.class); + } + return resourceClass; } @Override diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ControllerConfiguration.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ControllerConfiguration.java index 7fc0ca27b7..33e5f0218f 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ControllerConfiguration.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ControllerConfiguration.java @@ -55,7 +55,15 @@ default Optional reconciliationMaxInterval() { return Optional.of(Duration.ofHours(10L)); } + @SuppressWarnings("unused") default ConfigurationService getConfigurationService() { return ConfigurationServiceProvider.instance(); } + + @SuppressWarnings("unchecked") + @Override + default Class getResourceClass() { + return (Class) Utils.getFirstTypeArgumentFromSuperClassOrInterface(getClass(), + ControllerConfiguration.class); + } } diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ResourceConfiguration.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ResourceConfiguration.java index ca59e738d8..70d2b765a5 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ResourceConfiguration.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ResourceConfiguration.java @@ -31,7 +31,8 @@ default String getLabelSelector() { @SuppressWarnings("unchecked") default Class getResourceClass() { - return (Class) Utils.getFirstTypeArgumentFromInterface(getClass()); + return (Class) Utils.getFirstTypeArgumentFromSuperClassOrInterface(getClass(), + ResourceConfiguration.class); } default Set getNamespaces() { diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/Utils.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/Utils.java index d74d27f2d4..98686f9425 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/Utils.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/Utils.java @@ -5,6 +5,7 @@ import java.lang.reflect.Type; import java.text.SimpleDateFormat; import java.time.Instant; +import java.util.Arrays; import java.util.Date; import java.util.Properties; import java.util.function.Function; @@ -89,13 +90,44 @@ static boolean getBooleanFromSystemPropsOrDefault(String propertyName, boolean d } public static Class getFirstTypeArgumentFromExtendedClass(Class clazz) { - Type type = clazz.getGenericSuperclass(); - return (Class) ((ParameterizedType) type).getActualTypeArguments()[0]; + try { + Type type = clazz.getGenericSuperclass(); + return (Class) ((ParameterizedType) type).getActualTypeArguments()[0]; + } catch (Exception e) { + throw new RuntimeException("Couldn't retrieve generic parameter type from " + + clazz.getSimpleName() + + " because it doesn't extend a class that is parameterized with the type we want to retrieve", + e); + } + } + + public static Class getFirstTypeArgumentFromInterface(Class clazz, + Class expectedImplementedInterface) { + return Arrays.stream(clazz.getGenericInterfaces()) + .filter(type -> type.getTypeName().startsWith(expectedImplementedInterface.getName()) + && type instanceof ParameterizedType) + .map(ParameterizedType.class::cast) + .findFirst() + .map(t -> (Class) t.getActualTypeArguments()[0]) + .orElseThrow(() -> new RuntimeException( + "Couldn't retrieve generic parameter type from " + clazz.getSimpleName() + + " because it doesn't implement " + + expectedImplementedInterface.getSimpleName() + + " directly")); } - public static Class getFirstTypeArgumentFromInterface(Class clazz) { - ParameterizedType type = (ParameterizedType) clazz.getGenericInterfaces()[0]; - return (Class) type.getActualTypeArguments()[0]; + public static Class getFirstTypeArgumentFromSuperClassOrInterface(Class clazz, + Class expectedImplementedInterface) { + // first check super class if it exists + if (!clazz.getSuperclass().equals(Object.class)) { + try { + return getFirstTypeArgumentFromExtendedClass(clazz); + } catch (Exception e) { + // try interfaces + return getFirstTypeArgumentFromInterface(clazz, expectedImplementedInterface); + } + } + return getFirstTypeArgumentFromInterface(clazz, expectedImplementedInterface); } public static T valueOrDefault(C annotation, Function mapper, T defaultValue) { diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/informer/InformerConfiguration.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/informer/InformerConfiguration.java index 2fc74aa010..9cb0f1ee1d 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/informer/InformerConfiguration.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/informer/InformerConfiguration.java @@ -6,6 +6,7 @@ import io.fabric8.kubernetes.api.model.HasMetadata; import io.javaoperatorsdk.operator.api.config.DefaultResourceConfiguration; import io.javaoperatorsdk.operator.api.config.ResourceConfiguration; +import io.javaoperatorsdk.operator.api.config.Utils; import io.javaoperatorsdk.operator.api.reconciler.EventSourceContext; import io.javaoperatorsdk.operator.processing.event.source.SecondaryToPrimaryMapper; import io.javaoperatorsdk.operator.processing.event.source.informer.Mappers; @@ -160,4 +161,10 @@ static InformerConfigurationBuilder from( .withNamespacesInheritedFromController(eventSourceContext); } + @SuppressWarnings("unchecked") + @Override + default Class getResourceClass() { + return (Class) Utils.getFirstTypeArgumentFromSuperClassOrInterface(getClass(), + InformerConfiguration.class); + } } diff --git a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/api/config/ControllerConfigurationTest.java b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/api/config/ControllerConfigurationTest.java index 05aa637f1f..1e78288232 100644 --- a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/api/config/ControllerConfigurationTest.java +++ b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/api/config/ControllerConfigurationTest.java @@ -4,12 +4,18 @@ import io.javaoperatorsdk.operator.sample.simple.TestCustomResource; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; class ControllerConfigurationTest { @Test void getCustomResourceClass() { + final ControllerConfiguration lambdasCannotBeUsedToExtractGenericParam = + () -> null; + assertThrows(RuntimeException.class, + lambdasCannotBeUsedToExtractGenericParam::getResourceClass); + final ControllerConfiguration conf = new ControllerConfiguration<>() { @Override public String getAssociatedReconcilerClassName() { diff --git a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/api/config/UtilsTest.java b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/api/config/UtilsTest.java index 05ab4d1258..127f26915f 100644 --- a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/api/config/UtilsTest.java +++ b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/api/config/UtilsTest.java @@ -4,8 +4,12 @@ import org.junit.jupiter.api.Test; +import io.fabric8.kubernetes.api.model.ConfigMap; +import io.fabric8.kubernetes.api.model.HasMetadata; import io.fabric8.kubernetes.api.model.apps.Deployment; import io.javaoperatorsdk.operator.api.reconciler.Context; +import io.javaoperatorsdk.operator.api.reconciler.Reconciler; +import io.javaoperatorsdk.operator.api.reconciler.UpdateControl; import io.javaoperatorsdk.operator.api.reconciler.dependent.DependentResource; import io.javaoperatorsdk.operator.api.reconciler.dependent.ReconcileResult; import io.javaoperatorsdk.operator.processing.dependent.kubernetes.KubernetesDependentResource; @@ -84,10 +88,31 @@ void getsFirstTypeArgumentFromExtendedClass() { @Test void getsFirstTypeArgumentFromInterface() { - assertThat(Utils.getFirstTypeArgumentFromInterface(TestDependentResource.class)) + assertThat(Utils.getFirstTypeArgumentFromInterface(TestDependentResource.class, + DependentResource.class)) .isEqualTo(Deployment.class); } + @Test + void getsFirstTypeArgumentFromInterfaceFromParent() { + assertThat(Utils.getFirstTypeArgumentFromSuperClassOrInterface(ConcreteReconciler.class, + Reconciler.class)).isEqualTo(ConfigMap.class); + } + + public abstract static class AbstractReconciler

implements Reconciler

{ + + + } + + public static class ConcreteReconciler extends AbstractReconciler { + + @Override + public UpdateControl reconcile(ConfigMap resource, Context context) + throws Exception { + return null; + } + } + public static class TestDependentResource implements DependentResource { diff --git a/operator-framework/pom.xml b/operator-framework/pom.xml index 1032ce3ac7..33b3a1d981 100644 --- a/operator-framework/pom.xml +++ b/operator-framework/pom.xml @@ -85,6 +85,12 @@ ${project.version} test + + org.bouncycastle + bcpkix-jdk15on + 1.70 + test + \ No newline at end of file diff --git a/operator-framework/src/main/java/io/javaoperatorsdk/operator/config/runtime/RuntimeControllerMetadata.java b/operator-framework/src/main/java/io/javaoperatorsdk/operator/config/runtime/RuntimeControllerMetadata.java index 1595f88f97..068d762c03 100644 --- a/operator-framework/src/main/java/io/javaoperatorsdk/operator/config/runtime/RuntimeControllerMetadata.java +++ b/operator-framework/src/main/java/io/javaoperatorsdk/operator/config/runtime/RuntimeControllerMetadata.java @@ -17,8 +17,8 @@ public class RuntimeControllerMetadata { RECONCILERS_RESOURCE_PATH, Reconciler.class, HasMetadata.class); } - static Class getResourceClass( - Reconciler reconciler) { + @SuppressWarnings("unchecked") + static Class getResourceClass(Reconciler reconciler) { final Class resourceClass = controllerToCustomResourceMappings.get(reconciler.getClass()); if (resourceClass == null) { diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/AbstractMultipleDependentResourceIT.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/AbstractMultipleDependentResourceIT.java new file mode 100644 index 0000000000..2327476ae9 --- /dev/null +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/AbstractMultipleDependentResourceIT.java @@ -0,0 +1,62 @@ +package io.javaoperatorsdk.operator; + +import java.time.Duration; +import java.util.stream.IntStream; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +import io.fabric8.kubernetes.api.model.ConfigMap; +import io.fabric8.kubernetes.api.model.ObjectMetaBuilder; +import io.javaoperatorsdk.operator.junit.LocalOperatorExtension; +import io.javaoperatorsdk.operator.sample.AbstractExecutionNumberRecordingReconciler; +import io.javaoperatorsdk.operator.sample.multipledependentresource.MultipleDependentResourceConfigMap; +import io.javaoperatorsdk.operator.sample.multipledependentresource.MultipleDependentResourceCustomResource; +import io.javaoperatorsdk.operator.sample.multipledependentresource.MultipleDependentResourceReconciler; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.awaitility.Awaitility.await; + +public abstract class AbstractMultipleDependentResourceIT> { + + public static final String TEST_RESOURCE_NAME = "multipledependentresource-testresource"; + @RegisterExtension + LocalOperatorExtension operator = + LocalOperatorExtension.builder().withReconciler(getReconcilerClass()) + .waitForNamespaceDeletion(true) + .build(); + + protected abstract Class getReconcilerClass(); + + @Test + void twoConfigMapsHaveBeenCreated() { + var customResource = createTestCustomResource(); + operator.create(MultipleDependentResourceCustomResource.class, customResource); + + var reconciler = operator.getReconcilerOfType(getReconcilerClass()); + + await().pollDelay(Duration.ofMillis(300)) + .until(() -> reconciler.getNumberOfExecutions() <= 1); + + IntStream.of(MultipleDependentResourceReconciler.FIRST_CONFIG_MAP_ID, + MultipleDependentResourceReconciler.SECOND_CONFIG_MAP_ID).forEach(configMapId -> { + ConfigMap configMap = + operator.get(ConfigMap.class, customResource.getConfigMapName(configMapId)); + assertThat(configMap).isNotNull(); + assertThat(configMap.getMetadata().getName()) + .isEqualTo(customResource.getConfigMapName(configMapId)); + assertThat(configMap.getData().get(MultipleDependentResourceConfigMap.DATA_KEY)) + .isEqualTo(String.valueOf(configMapId)); + }); + } + + public MultipleDependentResourceCustomResource createTestCustomResource() { + var resource = new MultipleDependentResourceCustomResource(); + resource.setMetadata( + new ObjectMetaBuilder() + .withName(TEST_RESOURCE_NAME) + .withNamespace(operator.getNamespace()) + .build()); + return resource; + } +} diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/MultipleDependentResourceIT.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/MultipleDependentResourceIT.java index 78e422f81e..7c2e0c3808 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/MultipleDependentResourceIT.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/MultipleDependentResourceIT.java @@ -1,61 +1,12 @@ package io.javaoperatorsdk.operator; -import java.time.Duration; -import java.util.stream.IntStream; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; - -import io.fabric8.kubernetes.api.model.ConfigMap; -import io.fabric8.kubernetes.api.model.ObjectMetaBuilder; -import io.javaoperatorsdk.operator.junit.LocalOperatorExtension; -import io.javaoperatorsdk.operator.sample.multipledependentresource.MultipleDependentResourceConfigMap; -import io.javaoperatorsdk.operator.sample.multipledependentresource.MultipleDependentResourceCustomResource; import io.javaoperatorsdk.operator.sample.multipledependentresource.MultipleDependentResourceReconciler; -import static org.assertj.core.api.Assertions.assertThat; -import static org.awaitility.Awaitility.await; - -class MultipleDependentResourceIT { - - public static final String TEST_RESOURCE_NAME = "multipledependentresource-testresource"; - @RegisterExtension - LocalOperatorExtension operator = - LocalOperatorExtension.builder().withReconciler(MultipleDependentResourceReconciler.class) - .waitForNamespaceDeletion(true) - .build(); - - @Test - void twoConfigMapsHaveBeenCreated() { - MultipleDependentResourceCustomResource customResource = createTestCustomResource(); - operator.create(MultipleDependentResourceCustomResource.class, customResource); +class MultipleDependentResourceIT + extends AbstractMultipleDependentResourceIT { - var reconciler = operator.getReconcilerOfType(MultipleDependentResourceReconciler.class); - - await().pollDelay(Duration.ofMillis(300)) - .until(() -> reconciler.getNumberOfExecutions() <= 1); - - IntStream.of(MultipleDependentResourceReconciler.FIRST_CONFIG_MAP_ID, - MultipleDependentResourceReconciler.SECOND_CONFIG_MAP_ID).forEach(configMapId -> { - ConfigMap configMap = - operator.get(ConfigMap.class, customResource.getConfigMapName(configMapId)); - assertThat(configMap).isNotNull(); - assertThat(configMap.getMetadata().getName()) - .isEqualTo(customResource.getConfigMapName(configMapId)); - assertThat(configMap.getData().get(MultipleDependentResourceConfigMap.DATA_KEY)) - .isEqualTo(String.valueOf(configMapId)); - }); + @Override + protected Class getReconcilerClass() { + return MultipleDependentResourceReconciler.class; } - - public MultipleDependentResourceCustomResource createTestCustomResource() { - MultipleDependentResourceCustomResource resource = - new MultipleDependentResourceCustomResource(); - resource.setMetadata( - new ObjectMetaBuilder() - .withName(TEST_RESOURCE_NAME) - .withNamespace(operator.getNamespace()) - .build()); - return resource; - } - } diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/config/runtime/AnnotationControllerConfigurationTest.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/config/runtime/AnnotationControllerConfigurationTest.java index fc7fb887db..de54d2f3f4 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/config/runtime/AnnotationControllerConfigurationTest.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/config/runtime/AnnotationControllerConfigurationTest.java @@ -81,16 +81,15 @@ void getDependentResources() { @Test void missingAnnotationThrowsException() { - Assertions.assertThrows(OperatorException.class, () -> { - new AnnotationControllerConfiguration<>(new MissingAnnotationReconciler()); - }); + Assertions.assertThrows(OperatorException.class, + () -> new AnnotationControllerConfiguration<>(new MissingAnnotationReconciler())); } @SuppressWarnings("rawtypes") private DependentResourceSpec findByName( List dependentResourceSpecList, String name) { return dependentResourceSpecList.stream().filter(d -> d.getName().equals(name)).findFirst() - .get(); + .orElseThrow(); } @SuppressWarnings("rawtypes") diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/AbstractExecutionNumberRecordingReconciler.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/AbstractExecutionNumberRecordingReconciler.java new file mode 100644 index 0000000000..ee7e8ddeba --- /dev/null +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/AbstractExecutionNumberRecordingReconciler.java @@ -0,0 +1,29 @@ +package io.javaoperatorsdk.operator.sample; + +import java.util.concurrent.atomic.AtomicInteger; + +import io.fabric8.kubernetes.api.model.HasMetadata; +import io.javaoperatorsdk.operator.api.reconciler.Context; +import io.javaoperatorsdk.operator.api.reconciler.Reconciler; +import io.javaoperatorsdk.operator.api.reconciler.UpdateControl; +import io.javaoperatorsdk.operator.support.TestExecutionInfoProvider; + +public abstract class AbstractExecutionNumberRecordingReconciler

implements + Reconciler

, TestExecutionInfoProvider { + + private final AtomicInteger numberOfReconcileExecutions = new AtomicInteger(0); + + protected int recordReconcileExecution() { + return numberOfReconcileExecutions.incrementAndGet(); + } + + public int getNumberOfExecutions() { + return numberOfReconcileExecutions.get(); + } + + @Override + public UpdateControl

reconcile(P resource, Context

context) throws Exception { + recordReconcileExecution(); + return UpdateControl.noUpdate(); + } +} diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/cleanerforreconciler/CleanerForReconcilerTestReconciler.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/cleanerforreconciler/CleanerForReconcilerTestReconciler.java index fad1bb7798..092fbea945 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/cleanerforreconciler/CleanerForReconcilerTestReconciler.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/cleanerforreconciler/CleanerForReconcilerTestReconciler.java @@ -2,30 +2,19 @@ import java.util.concurrent.atomic.AtomicInteger; -import io.javaoperatorsdk.operator.api.reconciler.*; -import io.javaoperatorsdk.operator.support.TestExecutionInfoProvider; +import io.javaoperatorsdk.operator.api.reconciler.Cleaner; +import io.javaoperatorsdk.operator.api.reconciler.Context; +import io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration; +import io.javaoperatorsdk.operator.api.reconciler.DeleteControl; +import io.javaoperatorsdk.operator.sample.AbstractExecutionNumberRecordingReconciler; @ControllerConfiguration public class CleanerForReconcilerTestReconciler - implements Reconciler, - Cleaner, - TestExecutionInfoProvider { + extends AbstractExecutionNumberRecordingReconciler + implements Cleaner { - private final AtomicInteger numberOfExecutions = new AtomicInteger(0); private final AtomicInteger numberOfCleanupExecutions = new AtomicInteger(0); - @Override - public UpdateControl reconcile( - CleanerForReconcilerCustomResource resource, - Context context) { - numberOfExecutions.addAndGet(1); - return UpdateControl.noUpdate(); - } - - public int getNumberOfExecutions() { - return numberOfExecutions.get(); - } - public int getNumberOfCleanupExecutions() { return numberOfCleanupExecutions.get(); } diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/cleanermanageddependent/CleanerForManagedDependentTestReconciler.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/cleanermanageddependent/CleanerForManagedDependentTestReconciler.java index 6be29c5092..b8dea84cf4 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/cleanermanageddependent/CleanerForManagedDependentTestReconciler.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/cleanermanageddependent/CleanerForManagedDependentTestReconciler.java @@ -1,28 +1,10 @@ package io.javaoperatorsdk.operator.sample.cleanermanageddependent; -import java.util.concurrent.atomic.AtomicInteger; - -import io.javaoperatorsdk.operator.api.reconciler.*; +import io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration; import io.javaoperatorsdk.operator.api.reconciler.dependent.Dependent; -import io.javaoperatorsdk.operator.support.TestExecutionInfoProvider; +import io.javaoperatorsdk.operator.sample.AbstractExecutionNumberRecordingReconciler; @ControllerConfiguration(dependents = {@Dependent(type = ConfigMapDependentResource.class)}) public class CleanerForManagedDependentTestReconciler - implements Reconciler, - TestExecutionInfoProvider { - - private final AtomicInteger numberOfExecutions = new AtomicInteger(0); - - @Override - public UpdateControl reconcile( - CleanerForManagedDependentCustomResource resource, - Context context) { - numberOfExecutions.addAndGet(1); - return UpdateControl.noUpdate(); - } - - public int getNumberOfExecutions() { - return numberOfExecutions.get(); - } - + extends AbstractExecutionNumberRecordingReconciler { } diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/customfilter/CustomFilteringTestReconciler.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/customfilter/CustomFilteringTestReconciler.java index 1e42e8e6e1..254394f685 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/customfilter/CustomFilteringTestReconciler.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/customfilter/CustomFilteringTestReconciler.java @@ -1,25 +1,9 @@ package io.javaoperatorsdk.operator.sample.customfilter; -import java.util.concurrent.atomic.AtomicInteger; - -import io.javaoperatorsdk.operator.api.reconciler.Context; import io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration; -import io.javaoperatorsdk.operator.api.reconciler.Reconciler; -import io.javaoperatorsdk.operator.api.reconciler.UpdateControl; +import io.javaoperatorsdk.operator.sample.AbstractExecutionNumberRecordingReconciler; @ControllerConfiguration(eventFilters = {CustomFlagFilter.class, CustomFlagFilter2.class}) -public class CustomFilteringTestReconciler implements Reconciler { - - private final AtomicInteger numberOfExecutions = new AtomicInteger(0); - - @Override - public UpdateControl reconcile(CustomFilteringTestResource resource, - Context context) { - numberOfExecutions.incrementAndGet(); - return UpdateControl.noUpdate(); - } - - public int getNumberOfExecutions() { - return numberOfExecutions.get(); - } +public class CustomFilteringTestReconciler extends + AbstractExecutionNumberRecordingReconciler { } diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/dependentoperationeventfiltering/DependentOperationEventFilterCustomResourceTestReconciler.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/dependentoperationeventfiltering/DependentOperationEventFilterCustomResourceTestReconciler.java index 4ce74c75eb..ff46f09436 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/dependentoperationeventfiltering/DependentOperationEventFilterCustomResourceTestReconciler.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/dependentoperationeventfiltering/DependentOperationEventFilterCustomResourceTestReconciler.java @@ -1,10 +1,9 @@ package io.javaoperatorsdk.operator.sample.dependentoperationeventfiltering; -import java.util.concurrent.atomic.AtomicInteger; - -import io.javaoperatorsdk.operator.api.reconciler.*; +import io.javaoperatorsdk.operator.api.reconciler.Constants; +import io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration; import io.javaoperatorsdk.operator.api.reconciler.dependent.Dependent; -import io.javaoperatorsdk.operator.support.TestExecutionInfoProvider; +import io.javaoperatorsdk.operator.sample.AbstractExecutionNumberRecordingReconciler; @ControllerConfiguration( namespaces = Constants.WATCH_CURRENT_NAMESPACE, @@ -12,21 +11,6 @@ @Dependent(type = ConfigMapDependentResource.class), }) public class DependentOperationEventFilterCustomResourceTestReconciler - implements Reconciler, - TestExecutionInfoProvider { - - private final AtomicInteger numberOfExecutions = new AtomicInteger(0); - - @Override - public UpdateControl reconcile( - DependentOperationEventFilterCustomResource resource, - Context context) { - numberOfExecutions.addAndGet(1); - return UpdateControl.noUpdate(); - } - - public int getNumberOfExecutions() { - return numberOfExecutions.get(); - } - + extends + AbstractExecutionNumberRecordingReconciler { } diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/deployment/DeploymentReconciler.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/deployment/DeploymentReconciler.java index fc721af52c..da447c3534 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/deployment/DeploymentReconciler.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/deployment/DeploymentReconciler.java @@ -1,7 +1,6 @@ package io.javaoperatorsdk.operator.sample.deployment; import java.util.ArrayList; -import java.util.concurrent.atomic.AtomicInteger; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -11,25 +10,23 @@ import io.fabric8.kubernetes.api.model.apps.DeploymentStatus; import io.javaoperatorsdk.operator.api.reconciler.Context; import io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration; -import io.javaoperatorsdk.operator.api.reconciler.Reconciler; import io.javaoperatorsdk.operator.api.reconciler.UpdateControl; -import io.javaoperatorsdk.operator.support.TestExecutionInfoProvider; +import io.javaoperatorsdk.operator.sample.AbstractExecutionNumberRecordingReconciler; @ControllerConfiguration(labelSelector = "test=KubernetesResourceStatusUpdateIT") public class DeploymentReconciler - implements Reconciler, TestExecutionInfoProvider { + extends AbstractExecutionNumberRecordingReconciler { public static final String STATUS_MESSAGE = "Reconciled by DeploymentReconciler"; private static final Logger log = LoggerFactory.getLogger(DeploymentReconciler.class); - private final AtomicInteger numberOfExecutions = new AtomicInteger(0); @Override public UpdateControl reconcile( Deployment resource, Context context) { log.info("Reconcile deployment: {}", resource); - numberOfExecutions.incrementAndGet(); + recordReconcileExecution(); if (resource.getStatus() == null) { resource.setStatus(new DeploymentStatus()); } @@ -47,10 +44,4 @@ public UpdateControl reconcile( return UpdateControl.noUpdate(); } } - - - @Override - public int getNumberOfExecutions() { - return numberOfExecutions.get(); - } } diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/doubleupdate/DoubleUpdateTestCustomReconciler.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/doubleupdate/DoubleUpdateTestCustomReconciler.java index 11f0a54f3e..a5151d3b78 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/doubleupdate/DoubleUpdateTestCustomReconciler.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/doubleupdate/DoubleUpdateTestCustomReconciler.java @@ -1,31 +1,28 @@ package io.javaoperatorsdk.operator.sample.doubleupdate; import java.util.HashMap; -import java.util.concurrent.atomic.AtomicInteger; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import io.javaoperatorsdk.operator.api.reconciler.Context; import io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration; -import io.javaoperatorsdk.operator.api.reconciler.Reconciler; import io.javaoperatorsdk.operator.api.reconciler.UpdateControl; -import io.javaoperatorsdk.operator.support.TestExecutionInfoProvider; +import io.javaoperatorsdk.operator.sample.AbstractExecutionNumberRecordingReconciler; @ControllerConfiguration public class DoubleUpdateTestCustomReconciler - implements Reconciler, TestExecutionInfoProvider { + extends AbstractExecutionNumberRecordingReconciler { private static final Logger log = LoggerFactory.getLogger(DoubleUpdateTestCustomReconciler.class); public static final String TEST_ANNOTATION = "TestAnnotation"; public static final String TEST_ANNOTATION_VALUE = "TestAnnotationValue"; - private final AtomicInteger numberOfExecutions = new AtomicInteger(0); @Override public UpdateControl reconcile( DoubleUpdateTestCustomResource resource, Context context) { - numberOfExecutions.addAndGet(1); + recordReconcileExecution(); log.info("Value: " + resource.getSpec().getValue()); @@ -44,8 +41,4 @@ private void ensureStatusExists(DoubleUpdateTestCustomResource resource) { resource.setStatus(status); } } - - public int getNumberOfExecutions() { - return numberOfExecutions.get(); - } } diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/errorstatushandler/ErrorStatusHandlerTestReconciler.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/errorstatushandler/ErrorStatusHandlerTestReconciler.java index 412a784b7c..069ebca444 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/errorstatushandler/ErrorStatusHandlerTestReconciler.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/errorstatushandler/ErrorStatusHandlerTestReconciler.java @@ -1,27 +1,28 @@ package io.javaoperatorsdk.operator.sample.errorstatushandler; -import java.util.concurrent.atomic.AtomicInteger; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import io.javaoperatorsdk.operator.api.reconciler.*; -import io.javaoperatorsdk.operator.support.TestExecutionInfoProvider; +import io.javaoperatorsdk.operator.api.reconciler.Context; +import io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration; +import io.javaoperatorsdk.operator.api.reconciler.ErrorStatusHandler; +import io.javaoperatorsdk.operator.api.reconciler.ErrorStatusUpdateControl; +import io.javaoperatorsdk.operator.api.reconciler.UpdateControl; +import io.javaoperatorsdk.operator.sample.AbstractExecutionNumberRecordingReconciler; @ControllerConfiguration public class ErrorStatusHandlerTestReconciler - implements Reconciler, TestExecutionInfoProvider, - ErrorStatusHandler { + extends AbstractExecutionNumberRecordingReconciler + implements ErrorStatusHandler { private static final Logger log = LoggerFactory.getLogger(ErrorStatusHandlerTestReconciler.class); - private final AtomicInteger numberOfExecutions = new AtomicInteger(0); public static final String ERROR_STATUS_MESSAGE = "Error Retries Exceeded"; @Override public UpdateControl reconcile( ErrorStatusHandlerTestCustomResource resource, Context context) { - var number = numberOfExecutions.addAndGet(1); + var number = recordReconcileExecution(); var retryAttempt = -1; if (context.getRetryInfo().isPresent()) { retryAttempt = context.getRetryInfo().get().getAttemptCount(); @@ -39,10 +40,6 @@ private void ensureStatusExists(ErrorStatusHandlerTestCustomResource resource) { } } - public int getNumberOfExecutions() { - return numberOfExecutions.get(); - } - @Override public ErrorStatusUpdateControl updateErrorStatus( ErrorStatusHandlerTestCustomResource resource, diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/event/EventSourceTestCustomReconciler.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/event/EventSourceTestCustomReconciler.java index a7d97b83f3..ffd9c90564 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/event/EventSourceTestCustomReconciler.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/event/EventSourceTestCustomReconciler.java @@ -1,24 +1,21 @@ package io.javaoperatorsdk.operator.sample.event; -import java.util.concurrent.atomic.AtomicInteger; - -import io.javaoperatorsdk.operator.api.reconciler.*; +import io.javaoperatorsdk.operator.api.reconciler.Context; import io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration; -import io.javaoperatorsdk.operator.support.TestExecutionInfoProvider; +import io.javaoperatorsdk.operator.api.reconciler.UpdateControl; +import io.javaoperatorsdk.operator.sample.AbstractExecutionNumberRecordingReconciler; @ControllerConfiguration public class EventSourceTestCustomReconciler - implements Reconciler, - TestExecutionInfoProvider { + extends AbstractExecutionNumberRecordingReconciler { public static final int TIMER_PERIOD = 500; - private final AtomicInteger numberOfExecutions = new AtomicInteger(0); @Override public UpdateControl reconcile( EventSourceTestCustomResource resource, Context context) { - numberOfExecutions.addAndGet(1); + recordReconcileExecution(); ensureStatusExists(resource); resource.getStatus().setState(EventSourceTestCustomResourceStatus.State.SUCCESS); @@ -32,8 +29,4 @@ private void ensureStatusExists(EventSourceTestCustomResource resource) { resource.setStatus(status); } } - - public int getNumberOfExecutions() { - return numberOfExecutions.get(); - } } diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/maxinterval/MaxIntervalTestReconciler.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/maxinterval/MaxIntervalTestReconciler.java index f868148145..5ed030aa07 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/maxinterval/MaxIntervalTestReconciler.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/maxinterval/MaxIntervalTestReconciler.java @@ -1,27 +1,13 @@ package io.javaoperatorsdk.operator.sample.maxinterval; import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicInteger; -import io.javaoperatorsdk.operator.api.reconciler.*; -import io.javaoperatorsdk.operator.support.TestExecutionInfoProvider; +import io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration; +import io.javaoperatorsdk.operator.api.reconciler.ReconciliationMaxInterval; +import io.javaoperatorsdk.operator.sample.AbstractExecutionNumberRecordingReconciler; @ControllerConfiguration(reconciliationMaxInterval = @ReconciliationMaxInterval(interval = 50, timeUnit = TimeUnit.MILLISECONDS)) public class MaxIntervalTestReconciler - implements Reconciler, TestExecutionInfoProvider { - - private final AtomicInteger numberOfExecutions = new AtomicInteger(0); - - @Override - public UpdateControl reconcile( - MaxIntervalTestCustomResource resource, Context context) { - numberOfExecutions.addAndGet(1); - return UpdateControl.noUpdate(); - } - - public int getNumberOfExecutions() { - return numberOfExecutions.get(); - } - + extends AbstractExecutionNumberRecordingReconciler { } diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/multipledependentresource/MultipleDependentResourceReconciler.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/multipledependentresource/MultipleDependentResourceReconciler.java index 8cdbb81eba..e733559623 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/multipledependentresource/MultipleDependentResourceReconciler.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/multipledependentresource/MultipleDependentResourceReconciler.java @@ -1,30 +1,27 @@ package io.javaoperatorsdk.operator.sample.multipledependentresource; import java.util.Map; -import java.util.concurrent.atomic.AtomicInteger; import io.fabric8.kubernetes.client.KubernetesClient; import io.javaoperatorsdk.operator.api.reconciler.Context; import io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration; import io.javaoperatorsdk.operator.api.reconciler.EventSourceContext; import io.javaoperatorsdk.operator.api.reconciler.EventSourceInitializer; -import io.javaoperatorsdk.operator.api.reconciler.Reconciler; import io.javaoperatorsdk.operator.api.reconciler.UpdateControl; import io.javaoperatorsdk.operator.junit.KubernetesClientAware; import io.javaoperatorsdk.operator.processing.dependent.kubernetes.KubernetesDependentResourceConfig; import io.javaoperatorsdk.operator.processing.event.source.EventSource; -import io.javaoperatorsdk.operator.support.TestExecutionInfoProvider; +import io.javaoperatorsdk.operator.sample.AbstractExecutionNumberRecordingReconciler; @ControllerConfiguration public class MultipleDependentResourceReconciler - implements Reconciler, - TestExecutionInfoProvider, EventSourceInitializer, + extends AbstractExecutionNumberRecordingReconciler + implements EventSourceInitializer, KubernetesClientAware { public static final int FIRST_CONFIG_MAP_ID = 1; public static final int SECOND_CONFIG_MAP_ID = 2; public static final String LABEL = "multipledependentresource"; - private final AtomicInteger numberOfExecutions = new AtomicInteger(0); private final MultipleDependentResourceConfigMap firstDependentResourceConfigMap; private final MultipleDependentResourceConfigMap secondDependentResourceConfigMap; @@ -50,17 +47,12 @@ private String getLabelSelector(int resourceId) { public UpdateControl reconcile( MultipleDependentResourceCustomResource resource, Context context) { - numberOfExecutions.getAndIncrement(); + recordReconcileExecution(); firstDependentResourceConfigMap.reconcile(resource, context); secondDependentResourceConfigMap.reconcile(resource, context); return UpdateControl.noUpdate(); } - - public int getNumberOfExecutions() { - return numberOfExecutions.get(); - } - @Override public Map prepareEventSources( EventSourceContext context) { diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/multiplesecondaryeventsource/MultipleSecondaryEventSourceReconciler.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/multiplesecondaryeventsource/MultipleSecondaryEventSourceReconciler.java index 29557b0a30..544ac9367a 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/multiplesecondaryeventsource/MultipleSecondaryEventSourceReconciler.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/multiplesecondaryeventsource/MultipleSecondaryEventSourceReconciler.java @@ -3,32 +3,35 @@ import java.util.HashMap; import java.util.Map; import java.util.Set; -import java.util.concurrent.atomic.AtomicInteger; import io.fabric8.kubernetes.api.model.ConfigMap; import io.fabric8.kubernetes.api.model.ObjectMeta; import io.fabric8.kubernetes.client.KubernetesClient; import io.javaoperatorsdk.operator.api.config.informer.InformerConfiguration; -import io.javaoperatorsdk.operator.api.reconciler.*; +import io.javaoperatorsdk.operator.api.reconciler.Context; +import io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration; +import io.javaoperatorsdk.operator.api.reconciler.EventSourceContext; +import io.javaoperatorsdk.operator.api.reconciler.EventSourceInitializer; +import io.javaoperatorsdk.operator.api.reconciler.UpdateControl; import io.javaoperatorsdk.operator.junit.KubernetesClientAware; import io.javaoperatorsdk.operator.processing.event.ResourceID; import io.javaoperatorsdk.operator.processing.event.source.EventSource; import io.javaoperatorsdk.operator.processing.event.source.informer.InformerEventSource; -import io.javaoperatorsdk.operator.support.TestExecutionInfoProvider; +import io.javaoperatorsdk.operator.sample.AbstractExecutionNumberRecordingReconciler; @ControllerConfiguration public class MultipleSecondaryEventSourceReconciler - implements Reconciler, TestExecutionInfoProvider, - EventSourceInitializer, KubernetesClientAware { + extends AbstractExecutionNumberRecordingReconciler + implements EventSourceInitializer, + KubernetesClientAware { - private final AtomicInteger numberOfExecutions = new AtomicInteger(0); private KubernetesClient client; @Override public UpdateControl reconcile( MultipleSecondaryEventSourceCustomResource resource, Context context) { - numberOfExecutions.addAndGet(1); + recordReconcileExecution(); if (client.configMaps().inNamespace(resource.getMetadata().getNamespace()) .withName(getName1(resource)).get() == null) { @@ -41,7 +44,7 @@ public UpdateControl reconcile( .createOrReplace(configMap(getName2(resource), resource)); } - if (numberOfExecutions.get() >= 3) { + if (getNumberOfExecutions() >= 3) { if (context.getSecondaryResources(ConfigMap.class).size() != 2) { throw new IllegalStateException("There should be 2 related config maps"); } @@ -57,10 +60,6 @@ public static String getName2(MultipleSecondaryEventSourceCustomResource resourc return resource.getMetadata().getName() + "2"; } - public int getNumberOfExecutions() { - return numberOfExecutions.get(); - } - @Override public Map prepareEventSources( EventSourceContext context) { @@ -75,8 +74,7 @@ public Map prepareEventSources( return Set.of(new ResourceID(name.toString(), s.getMetadata().getNamespace())); }).build(); InformerEventSource configMapEventSource = - new InformerEventSource(config, - context); + new InformerEventSource<>(config, context); return EventSourceInitializer.nameEventSources(configMapEventSource); } diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/orderedmanageddependent/OrderedManagedDependentTestReconciler.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/orderedmanageddependent/OrderedManagedDependentTestReconciler.java index 8ca8f0651d..329e5da681 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/orderedmanageddependent/OrderedManagedDependentTestReconciler.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/orderedmanageddependent/OrderedManagedDependentTestReconciler.java @@ -3,15 +3,11 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; -import java.util.concurrent.atomic.AtomicInteger; import io.javaoperatorsdk.operator.api.reconciler.Constants; -import io.javaoperatorsdk.operator.api.reconciler.Context; import io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration; -import io.javaoperatorsdk.operator.api.reconciler.Reconciler; -import io.javaoperatorsdk.operator.api.reconciler.UpdateControl; import io.javaoperatorsdk.operator.api.reconciler.dependent.Dependent; -import io.javaoperatorsdk.operator.support.TestExecutionInfoProvider; +import io.javaoperatorsdk.operator.sample.AbstractExecutionNumberRecordingReconciler; @ControllerConfiguration( namespaces = Constants.WATCH_CURRENT_NAMESPACE, @@ -20,23 +16,8 @@ @Dependent(type = ConfigMapDependentResource2.class) }) public class OrderedManagedDependentTestReconciler - implements Reconciler, - TestExecutionInfoProvider { + extends AbstractExecutionNumberRecordingReconciler { - private final AtomicInteger numberOfExecutions = new AtomicInteger(0); public static final List> dependentExecution = Collections.synchronizedList(new ArrayList<>()); - - @Override - public UpdateControl reconcile( - OrderedManagedDependentCustomResource resource, - Context context) { - numberOfExecutions.addAndGet(1); - return UpdateControl.noUpdate(); - } - - public int getNumberOfExecutions() { - return numberOfExecutions.get(); - } - } diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/retry/RetryTestCustomReconciler.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/retry/RetryTestCustomReconciler.java index 29d658fc7b..781ef2a279 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/retry/RetryTestCustomReconciler.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/retry/RetryTestCustomReconciler.java @@ -7,18 +7,15 @@ import io.javaoperatorsdk.operator.api.reconciler.Context; import io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration; -import io.javaoperatorsdk.operator.api.reconciler.Reconciler; import io.javaoperatorsdk.operator.api.reconciler.UpdateControl; -import io.javaoperatorsdk.operator.support.TestExecutionInfoProvider; +import io.javaoperatorsdk.operator.sample.AbstractExecutionNumberRecordingReconciler; @ControllerConfiguration public class RetryTestCustomReconciler - implements Reconciler, TestExecutionInfoProvider { + extends AbstractExecutionNumberRecordingReconciler { private static final Logger log = LoggerFactory.getLogger(RetryTestCustomReconciler.class); - private final AtomicInteger numberOfExecutions = new AtomicInteger(0); - private final AtomicInteger numberOfExecutionFails; @@ -29,11 +26,11 @@ public RetryTestCustomReconciler(int numberOfExecutionFails) { @Override public UpdateControl reconcile(RetryTestCustomResource resource, Context context) { - numberOfExecutions.addAndGet(1); + recordReconcileExecution(); log.info("Value: " + resource.getSpec().getValue()); - if (numberOfExecutions.get() < numberOfExecutionFails.get() + 1) { + if (getNumberOfExecutions() < numberOfExecutionFails.get() + 1) { throw new RuntimeException("Testing Retry"); } if (context.getRetryInfo().isEmpty() || context.getRetryInfo().get().isLastAttempt()) { @@ -53,8 +50,4 @@ private void ensureStatusExists(RetryTestCustomResource resource) { resource.setStatus(status); } } - - public int getNumberOfExecutions() { - return numberOfExecutions.get(); - } } diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/simple/TestReconciler.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/simple/TestReconciler.java index ebf809799e..d91aee0766 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/simple/TestReconciler.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/simple/TestReconciler.java @@ -12,23 +12,24 @@ import io.fabric8.kubernetes.api.model.ObjectMetaBuilder; import io.fabric8.kubernetes.client.KubernetesClient; import io.javaoperatorsdk.operator.ReconcilerUtils; -import io.javaoperatorsdk.operator.api.reconciler.*; +import io.javaoperatorsdk.operator.api.reconciler.Cleaner; +import io.javaoperatorsdk.operator.api.reconciler.Context; import io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration; +import io.javaoperatorsdk.operator.api.reconciler.DeleteControl; +import io.javaoperatorsdk.operator.api.reconciler.UpdateControl; import io.javaoperatorsdk.operator.junit.KubernetesClientAware; -import io.javaoperatorsdk.operator.support.TestExecutionInfoProvider; +import io.javaoperatorsdk.operator.sample.AbstractExecutionNumberRecordingReconciler; @ControllerConfiguration(generationAwareEventProcessing = false) public class TestReconciler - implements Reconciler, Cleaner, - TestExecutionInfoProvider, - KubernetesClientAware { + extends AbstractExecutionNumberRecordingReconciler + implements Cleaner, KubernetesClientAware { private static final Logger log = LoggerFactory.getLogger(TestReconciler.class); public static final String FINALIZER_NAME = ReconcilerUtils.getDefaultFinalizerName(TestCustomResource.class); - private final AtomicInteger numberOfExecutions = new AtomicInteger(0); private final AtomicInteger numberOfCleanupExecutions = new AtomicInteger(0); private KubernetesClient kubernetesClient; private volatile boolean updateStatus; @@ -89,7 +90,7 @@ public DeleteControl cleanup( @Override public UpdateControl reconcile( TestCustomResource resource, Context context) { - numberOfExecutions.addAndGet(1); + recordReconcileExecution(); if (!resource.getMetadata().getFinalizers().contains(FINALIZER_NAME)) { throw new IllegalStateException("Finalizer is not present."); } @@ -146,10 +147,6 @@ private Map configMapData(TestCustomResource resource) { return data; } - public int getNumberOfExecutions() { - return numberOfExecutions.get(); - } - public int getNumberOfCleanupExecutions() { return numberOfCleanupExecutions.get(); } diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/subresource/SubResourceTestCustomReconciler.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/subresource/SubResourceTestCustomReconciler.java index 1e76681f25..0a06a9706d 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/subresource/SubResourceTestCustomReconciler.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/subresource/SubResourceTestCustomReconciler.java @@ -1,33 +1,28 @@ package io.javaoperatorsdk.operator.sample.subresource; -import java.util.concurrent.atomic.AtomicInteger; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; import io.javaoperatorsdk.operator.api.reconciler.Context; import io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration; -import io.javaoperatorsdk.operator.api.reconciler.Reconciler; import io.javaoperatorsdk.operator.api.reconciler.UpdateControl; -import io.javaoperatorsdk.operator.support.TestExecutionInfoProvider; +import io.javaoperatorsdk.operator.sample.AbstractExecutionNumberRecordingReconciler; import static io.javaoperatorsdk.operator.support.TestUtils.waitXms; @ControllerConfiguration(generationAwareEventProcessing = false) public class SubResourceTestCustomReconciler - implements Reconciler, TestExecutionInfoProvider { + extends AbstractExecutionNumberRecordingReconciler { public static final int RECONCILER_MIN_EXEC_TIME = 300; private static final Logger log = LoggerFactory.getLogger(SubResourceTestCustomReconciler.class); - private final AtomicInteger numberOfExecutions = new AtomicInteger(0); - @Override public UpdateControl reconcile( SubResourceTestCustomResource resource, Context context) { - numberOfExecutions.addAndGet(1); + recordReconcileExecution(); log.info("Value: " + resource.getSpec().getValue()); ensureStatusExists(resource); @@ -43,8 +38,4 @@ private void ensureStatusExists(SubResourceTestCustomResource resource) { resource.setStatus(status); } } - - public int getNumberOfExecutions() { - return numberOfExecutions.get(); - } }